Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion minibenchmarks/django_template.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/integration/django"))
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/testsuite/lib/django"))

from django.template.base import Origin, Template, Context, TemplateDoesNotExist
from django.conf import settings
Expand Down
2 changes: 1 addition & 1 deletion minibenchmarks/pyxl_bench.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), "../test/integration/pyxl/"))
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/testsuite/lib/pyxl/"))

from pyxl.codec.register import pyxl_transform_string

Expand Down
2 changes: 1 addition & 1 deletion minibenchmarks/sqlalchemy_declarative.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/integration/sqlalchemy/lib"))
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/testsuite/lib/sqlalchemy/lib"))

from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Expand Down
2 changes: 1 addition & 1 deletion minibenchmarks/sqlalchemy_imperative.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
import sys
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/integration/sqlalchemy/lib"))
sys.path.append(os.path.join(os.path.dirname(__file__), "../test/testsuite/lib/sqlalchemy/lib"))

from sqlalchemy import Column, ForeignKey, Integer, String, Table, MetaData
from sqlalchemy.ext.declarative import declarative_base
Expand Down
31 changes: 24 additions & 7 deletions src/codegen/ast_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,19 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {

UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code");
CompiledFunction* partial_func = compilePartialFuncInternal(&exit);

auto arg_tuple = getTupleFromArgsArray(&arg_array[0], arg_array.size());
Box* r = partial_func->call(std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple),
std::get<3>(arg_tuple));

assert(r);
return r;
if (partial_func->exception_style == CXX) {
assert(r);
return r;
} else {
if (!r)
throwCAPIException();
return r;
}
}

Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
Expand Down Expand Up @@ -1725,14 +1732,24 @@ Box* astInterpretFunction(CLFunction* clfunc, int nargs, Box* closure, Box* gene
clfunc->dependent_interp_callsites.invalidateAll();

UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code");
Box* r;
if (closure && generator)
return optimized->closure_generator_call((BoxedClosure*)closure, (BoxedGenerator*)generator, arg1, arg2,
arg3, args);
r = optimized->closure_generator_call((BoxedClosure*)closure, (BoxedGenerator*)generator, arg1, arg2, arg3,
args);
else if (closure)
return optimized->closure_call((BoxedClosure*)closure, arg1, arg2, arg3, args);
r = optimized->closure_call((BoxedClosure*)closure, arg1, arg2, arg3, args);
else if (generator)
return optimized->generator_call((BoxedGenerator*)generator, arg1, arg2, arg3, args);
return optimized->call(arg1, arg2, arg3, args);
r = optimized->generator_call((BoxedGenerator*)generator, arg1, arg2, arg3, args);
else
r = optimized->call(arg1, arg2, arg3, args);

if (optimized->exception_style == CXX)
return r;
else {
if (!r)
throwCAPIException();
return r;
}
}

Box** vregs = NULL;
Expand Down
50 changes: 20 additions & 30 deletions src/codegen/compvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,7 @@ class UnknownType : public ConcreteCompilerType {
CompilerVariable* slice) override {
ConcreteCompilerVariable* converted_slice = slice->makeConverted(emitter, slice->getBoxType());

ExceptionStyle target_exception_style = CXX;
if (FORCE_LLVM_CAPI || info.unw_info.capi_exc_dest)
target_exception_style = CAPI;
ExceptionStyle target_exception_style = info.preferredExceptionStyle();

bool do_patchpoint = ENABLE_ICGETITEMS;
llvm::Value* rtn;
Expand Down Expand Up @@ -500,9 +498,7 @@ CompilerVariable* UnknownType::getattr(IREmitter& emitter, const OpInfo& info, C

llvm::Value* rtn_val = NULL;

ExceptionStyle target_exception_style = CXX;
if (info.unw_info.capi_exc_dest || (!cls_only && FORCE_LLVM_CAPI))
target_exception_style = CAPI;
ExceptionStyle target_exception_style = cls_only ? CXX : info.preferredExceptionStyle();

llvm::Value* llvm_func;
void* raw_func;
Expand Down Expand Up @@ -656,9 +652,7 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
bool pass_keywords = (argspec.num_keywords != 0);
int npassed_args = argspec.totalPassed();

ExceptionStyle exception_style = ((FORCE_LLVM_CAPI && !info.unw_info.cxx_exc_dest) || info.unw_info.capi_exc_dest)
? ExceptionStyle::CAPI
: ExceptionStyle::CXX;
ExceptionStyle exception_style = info.preferredExceptionStyle();

llvm::Value* func;
if (pass_keywords)
Expand Down Expand Up @@ -691,10 +685,7 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
bool pass_keywords = (flags.argspec.num_keywords != 0);
int npassed_args = flags.argspec.totalPassed();

ExceptionStyle exception_style = ((FORCE_LLVM_CAPI && !info.unw_info.cxx_exc_dest && !flags.null_on_nonexistent)
|| info.unw_info.capi_exc_dest)
? ExceptionStyle::CAPI
: ExceptionStyle::CXX;
ExceptionStyle exception_style = flags.null_on_nonexistent ? CXX : info.preferredExceptionStyle();

if (exception_style == CAPI)
assert(!flags.null_on_nonexistent); // Will conflict with CAPI's null-on-exception
Expand Down Expand Up @@ -1522,7 +1513,7 @@ class NormalObjectType : public ConcreteCompilerType {
if (canStaticallyResolveGetattrs()) {
Box* rtattr = typeLookup(cls, attr, nullptr);
if (rtattr == NULL) {
ExceptionStyle exception_style = (FORCE_LLVM_CAPI || info.unw_info.capi_exc_dest) ? CAPI : CXX;
ExceptionStyle exception_style = info.preferredExceptionStyle();
llvm::Value* raise_func = exception_style == CXX ? g.funcs.raiseAttributeErrorStr
: g.funcs.raiseAttributeErrorStrCapi;
llvm::CallSite call = emitter.createCall3(
Expand Down Expand Up @@ -1619,15 +1610,13 @@ class NormalObjectType : public ConcreteCompilerType {
"%d", info.unw_info.current_stmt->lineno);

CompiledFunction* cf = NULL;
CompiledFunction* best_exception_mismatch = NULL;
bool found = false;
// TODO have to find the right version.. similar to resolveclfunc?
for (int i = 0; i < cl->versions.size(); i++) {
cf = cl->versions[i];
assert(cf->spec->arg_types.size() == cl->numReceivedArgs());

if (cf->exception_style != exception_style)
continue;

bool fits = true;
for (int j = 0; j < args.size(); j++) {
if (!args[j]->canConvertTo(cf->spec->arg_types[j + 1])) {
Expand All @@ -1638,14 +1627,22 @@ class NormalObjectType : public ConcreteCompilerType {
if (!fits)
continue;

if (cf->exception_style != exception_style) {
if (!best_exception_mismatch)
best_exception_mismatch = cf;
continue;
}

found = true;
break;
}

if (!found && exception_style == CAPI) {
std::string name = g.func_addr_registry.getFuncNameAtAddress(cl->versions[0]->code, true);
RELEASE_ASSERT(0, "Please define a capi variant for %s", name.c_str());
if (!found) {
assert(best_exception_mismatch);
cf = best_exception_mismatch;
found = true;
}

RELEASE_ASSERT(found, "");
RELEASE_ASSERT(cf->code, "");

Expand Down Expand Up @@ -1717,10 +1714,7 @@ class NormalObjectType : public ConcreteCompilerType {
CompilerVariable* callattr(IREmitter& emitter, const OpInfo& info, ConcreteCompilerVariable* var, BoxedString* attr,
CallattrFlags flags, const std::vector<CompilerVariable*>& args,
const std::vector<BoxedString*>* keyword_names) override {
ExceptionStyle exception_style = CXX;
// Not safe to force-capi here since most of the functions won't have capi variants:
if (/*FORCE_LLVM_CAPI ||*/ info.unw_info.capi_exc_dest)
exception_style = CAPI;
ExceptionStyle exception_style = info.preferredExceptionStyle();

ConcreteCompilerVariable* called_constant = tryCallattrConstant(
emitter, info, var, attr, flags.cls_only, flags.argspec, args, keyword_names, NULL, exception_style);
Expand Down Expand Up @@ -1783,9 +1777,7 @@ class NormalObjectType : public ConcreteCompilerType {
static BoxedString* attr = internStringImmortal("__getitem__");
bool no_attribute = false;

ExceptionStyle exception_style = CXX;
if (FORCE_LLVM_CAPI || info.unw_info.capi_exc_dest)
exception_style = CAPI;
ExceptionStyle exception_style = info.preferredExceptionStyle();

ConcreteCompilerVariable* called_constant = tryCallattrConstant(
emitter, info, var, attr, true, ArgPassSpec(1, 0, 0, 0), { slice }, NULL, &no_attribute, exception_style);
Expand Down Expand Up @@ -2293,9 +2285,7 @@ class TupleType : public ValuedCompilerType<const std::vector<CompilerVariable*>
rtn->incvref();
return rtn;
} else {
ExceptionStyle target_exception_style = CXX;
if (FORCE_LLVM_CAPI || info.unw_info.capi_exc_dest)
target_exception_style = CAPI;
ExceptionStyle target_exception_style = info.preferredExceptionStyle();

if (target_exception_style == CAPI) {
llvm::CallSite call = emitter.createCall(info.unw_info, g.funcs.raiseIndexErrorStrCapi,
Expand Down
20 changes: 17 additions & 3 deletions src/codegen/irgen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
std::unordered_map<CFGBlock*, ConcreteSymbolTable*> phi_ending_symbol_tables;
typedef std::unordered_map<InternedString, std::pair<ConcreteCompilerType*, llvm::PHINode*>> PHITable;
std::unordered_map<CFGBlock*, PHITable*> created_phis;
std::unordered_map<CFGBlock*, llvm::SmallVector<IRGenerator::ExceptionState, 2>> incoming_exception_state;

CFGBlock* initial_block = NULL;
if (entry_descriptor) {
Expand Down Expand Up @@ -759,6 +760,11 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
}

auto exc_it = incoming_exception_state.find(block);
if (exc_it != incoming_exception_state.end()) {
generator->setIncomingExceptionState(exc_it->second);
}

// Generate loop safepoints on backedges.
for (CFGBlock* predecessor : block->predecessors) {
if (predecessor->idx > block->idx) {
Expand All @@ -777,6 +783,15 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
phi_ending_symbol_tables[block] = ending_st.phi_symbol_table;
llvm_exit_blocks[block] = ending_st.ending_block;

if (ending_st.exception_state.size()) {
AST_stmt* last_stmt = block->body.back();
assert(last_stmt->type == AST_TYPE::Invoke);
CFGBlock* exc_block = ast_cast<AST_Invoke>(last_stmt)->exc_dest;
assert(!incoming_exception_state.count(exc_block));

incoming_exception_state.insert(std::make_pair(exc_block, ending_st.exception_state));
}

if (into_hax.count(block))
ASSERT(ending_st.symbol_table->size() == 0, "%d", block->idx);
}
Expand Down Expand Up @@ -952,7 +967,7 @@ static std::string getUniqueFunctionName(std::string nameprefix, EffortLevel eff

CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names,
const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
FunctionSpecialization* spec, std::string nameprefix) {
ExceptionStyle exception_style, FunctionSpecialization* spec, std::string nameprefix) {
Timer _t("in doCompile");
Timer _t2;
long irgen_us = 0;
Expand Down Expand Up @@ -1015,8 +1030,7 @@ CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames*
}
}


CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, ExceptionStyle::CXX, entry_descriptor);
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor);

// Make sure that the instruction memory keeps the module object alive.
// TODO: implement this for real
Expand Down
17 changes: 10 additions & 7 deletions src/codegen/irgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"

#include "core/options.h"
#include "core/types.h"

namespace pyston {
Expand All @@ -33,18 +34,18 @@ struct UnwindInfo {
public:
AST_stmt* current_stmt;

llvm::BasicBlock* capi_exc_dest;
llvm::BasicBlock* cxx_exc_dest;
llvm::BasicBlock* exc_dest;

bool hasHandler() const { return cxx_exc_dest != NULL || capi_exc_dest != NULL; }
bool hasHandler() const { return exc_dest != NULL; }

UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* capi_exc_dest, llvm::BasicBlock* cxx_exc_dest)
: current_stmt(current_stmt), capi_exc_dest(capi_exc_dest), cxx_exc_dest(cxx_exc_dest) {}
UnwindInfo(AST_stmt* current_stmt, llvm::BasicBlock* exc_dest) : current_stmt(current_stmt), exc_dest(exc_dest) {}

ExceptionStyle preferredExceptionStyle() const;

// Risky! This means that we can't unwind from this location, and should be used in the
// rare case that there are language-specific reasons that the statement should not unwind
// (ex: loading function arguments into the appropriate scopes).
static UnwindInfo cantUnwind() { return UnwindInfo(NULL, NULL, NULL); }
static UnwindInfo cantUnwind() { return UnwindInfo(NULL, NULL); }
};

// TODO get rid of this
Expand Down Expand Up @@ -112,7 +113,7 @@ bool isIsDefinedName(llvm::StringRef name);

CompiledFunction* doCompile(CLFunction* clfunc, SourceInfo* source, ParamNames* param_names,
const OSREntryDescriptor* entry_descriptor, EffortLevel effort,
FunctionSpecialization* spec, std::string nameprefix);
ExceptionStyle exception_style, FunctionSpecialization* spec, std::string nameprefix);

// A common pattern is to branch based off whether a variable is defined but only if it is
// potentially-undefined. If it is potentially-undefined, we have to generate control-flow
Expand Down Expand Up @@ -146,6 +147,8 @@ class OpInfo {
: effort(effort), type_recorder(type_recorder), unw_info(unw_info) {}

TypeRecorder* getTypeRecorder() const { return type_recorder; }

ExceptionStyle preferredExceptionStyle() const { return unw_info.preferredExceptionStyle(); }
};
}

Expand Down
16 changes: 12 additions & 4 deletions src/codegen/irgen/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E

ASSERT(f->versions.size() < 20, "%s %ld", name.c_str(), f->versions.size());

ExceptionStyle exception_style = CXX;
if (FORCE_LLVM_CAPI_THROWS)
exception_style = CAPI;
if (name == "next")
exception_style = CAPI;

if (VERBOSITY("irgen") >= 1) {
std::string s;
llvm::raw_string_ostream ss(s);
Expand All @@ -223,7 +229,8 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
ss << "\033[" << colors[(int)effort] << ";1mDoing OSR-entry partial compile of " << source->fn << ":"
<< name << ", starting with backedge to block " << entry_descriptor->backedge->target->idx;
}
ss << " at effort level " << (int)effort << '\n';
ss << " at effort level " << (int)effort << " with exception style "
<< (exception_style == CXX ? "C++" : "CAPI") << '\n';

if (entry_descriptor && VERBOSITY("irgen") >= 2) {
for (const auto& p : entry_descriptor->args) {
Expand All @@ -241,8 +248,7 @@ CompiledFunction* compileFunction(CLFunction* f, FunctionSpecialization* spec, E
}



CompiledFunction* cf = doCompile(f, source, &f->param_names, entry_descriptor, effort, spec, name);
CompiledFunction* cf = doCompile(f, source, &f->param_names, entry_descriptor, effort, exception_style, spec, name);
compileIR(cf, effort);

f->addVersion(cf);
Expand Down Expand Up @@ -822,7 +828,9 @@ extern "C" CompiledFunction* reoptCompiledFuncInternal(CompiledFunction* cf) {


extern "C" char* reoptCompiledFunc(CompiledFunction* cf) {
return (char*)reoptCompiledFuncInternal(cf)->code;
CompiledFunction* new_cf = reoptCompiledFuncInternal(cf);
assert(new_cf->exception_style == cf->exception_style);
return (char*)new_cf->code;
}

CLFunction* createRTFunction(int num_args, int num_defaults, bool takes_varargs, bool takes_kwargs,
Expand Down
Loading