Commit bf2bae9d authored by Marius Wachtler's avatar Marius Wachtler

Merge pull request #1021 from undingen/new_frame_intro3

Don't generate patchpoints for calls to fixed functions which don't need patching
parents ff657c1f 3d553b4e
......@@ -42,7 +42,7 @@ calliter_traverse(calliterobject *it, visitproc visit, void *arg)
}
// Pyston change: extract most of the body of calliter_iternext here
// so we can use it from both calliter_iternext and calliter_hasnext
// so we can use it from both calliter_iternext and calliterHasnextUnboxed
PyObject *
calliter_next(calliterobject *it)
{
......
......@@ -804,10 +804,9 @@ PyObject* slot_tp_iter(PyObject* self) noexcept {
return call_method(self, "next", &next_str, "()");
}
static bool slotTppHasnext(PyObject* self) {
static llvm_compat_bool slotTppHasnext(PyObject* self) {
STAT_TIMER(t0, "us_timer_slot_tpphasnext", SLOT_AVOIDABILITY(self));
static PyObject* hasnext_str;
Box* r = self->hasnextOrNullIC();
assert(r);
return r->nonzeroIC();
......
......@@ -136,23 +136,19 @@ private:
// this variables are used by the baseline JIT, make sure they have an offset < 0x80 so we can use shorter
// instructions
CFGBlock* next_block, *current_block;
AST_stmt* current_inst;
FrameInfo frame_info;
FunctionMetadata* md;
SourceInfo* source_info;
ScopeInfo* scope_info;
PhiAnalysis* phis;
Box** vregs;
ExcInfo last_exception;
BoxedClosure* created_closure;
BoxedGenerator* generator;
unsigned edgecount;
FrameInfo frame_info;
BoxedModule* parent_module;
// This is either a module or a dict
Box* globals;
std::unique_ptr<JitFragmentWriter> jit;
bool should_jit;
......@@ -163,13 +159,15 @@ public:
}
AST_stmt* getCurrentStatement() {
assert(current_inst);
return current_inst;
assert(frame_info.stmt);
return frame_info.stmt;
}
void setCurrentStatement(AST_stmt* stmt) { frame_info.stmt = stmt; }
Box* getGlobals() {
assert(globals);
return globals;
assert(frame_info.globals);
return frame_info.globals;
}
FunctionMetadata* getMD() { return md; }
......@@ -224,12 +222,12 @@ void ASTInterpreter::setFrameInfo(const FrameInfo* frame_info) {
void ASTInterpreter::setGlobals(Box* globals) {
assert(gc::isValidGCObject(globals));
this->globals = globals;
this->frame_info.globals = globals;
}
ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs)
: current_block(0),
current_inst(0),
frame_info(ExcInfo(NULL, NULL, NULL)),
md(md),
source_info(md->source.get()),
scope_info(0),
......@@ -239,9 +237,7 @@ ASTInterpreter::ASTInterpreter(FunctionMetadata* md, Box** vregs)
created_closure(0),
generator(0),
edgecount(0),
frame_info(ExcInfo(NULL, NULL, NULL)),
parent_module(source_info->parent_module),
globals(0),
should_jit(false) {
scope_info = source_info->getScopeInfo();
......@@ -352,9 +348,9 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
}
// Important that this happens after RegisterHelper:
interpreter.current_inst = start_at;
interpreter.setCurrentStatement(start_at);
threading::allowGLReadPreemption();
interpreter.current_inst = NULL;
interpreter.setCurrentStatement(NULL);
if (!from_start) {
interpreter.current_block = start_block;
......@@ -366,7 +362,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
started = true;
}
interpreter.current_inst = s;
interpreter.setCurrentStatement(s);
v = interpreter.visit_stmt(s);
}
} else {
......@@ -396,7 +392,7 @@ Box* ASTInterpreter::executeInner(ASTInterpreter& interpreter, CFGBlock* start_b
}
for (AST_stmt* s : interpreter.current_block->body) {
interpreter.current_inst = s;
interpreter.setCurrentStatement(s);
if (interpreter.jit)
interpreter.jit->emitSetCurrentInst(s);
v = interpreter.visit_stmt(s);
......@@ -432,8 +428,8 @@ void ASTInterpreter::doStore(AST_Name* node, Value value) {
ScopeInfo::VarScopeType vst = node->lookup_type;
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit)
jit->emitSetGlobal(globals, name.getBox(), value);
setGlobal(globals, name.getBox(), value.o);
jit->emitSetGlobal(frame_info.globals, name.getBox(), value);
setGlobal(frame_info.globals, name.getBox(), value.o);
} else if (vst == ScopeInfo::VarScopeType::NAME) {
if (jit)
jit->emitSetItemName(name.getBox(), value);
......@@ -719,9 +715,6 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
if (created_closure)
sorted_symbol_table[source_info->getInternedStrings().get(CREATED_CLOSURE_NAME)] = created_closure;
if (!source_info->scoping->areGlobalsFromModule())
sorted_symbol_table[source_info->getInternedStrings().get(PASSED_GLOBALS_NAME)] = globals;
sorted_symbol_table[source_info->getInternedStrings().get(FRAME_INFO_PTR_NAME)] = (Box*)&frame_info;
if (found_entry == nullptr) {
......@@ -849,7 +842,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
"import * not supported in functions");
Value module = visit_expr(node->args[0]);
v = Value(importStar(module.o, globals), jit ? jit->emitImportStar(module) : NULL);
v = Value(importStar(module.o, frame_info.globals), jit ? jit->emitImportStar(module) : NULL);
} else if (node->opcode == AST_LangPrimitive::NONE) {
v = getNone();
} else if (node->opcode == AST_LangPrimitive::LANDINGPAD) {
......@@ -1037,9 +1030,9 @@ Value ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::
Box* passed_globals = NULL;
RewriterVar* passed_globals_var = NULL;
if (!getMD()->source->scoping->areGlobalsFromModule()) {
passed_globals = globals;
passed_globals = frame_info.globals;
if (jit)
passed_globals_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, globals));
passed_globals_var = jit->getInterp()->getAttr(offsetof(ASTInterpreter, frame_info.globals));
}
Value rtn;
......@@ -1103,7 +1096,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
Box* passed_globals = NULL;
if (!getMD()->source->scoping->areGlobalsFromModule())
passed_globals = globals;
passed_globals = frame_info.globals;
Box* attrDict
= runtimeCall(createFunctionFromMetadata(md, closure, passed_globals, {}), ArgPassSpec(0), 0, 0, 0, 0, 0);
......@@ -1150,7 +1143,7 @@ Value ASTInterpreter::visit_assert(AST_Assert* node) {
#endif
static BoxedString* AssertionError_str = internStringImmortal("AssertionError");
Box* assertion_type = getGlobal(globals, AssertionError_str);
Box* assertion_type = getGlobal(frame_info.globals, AssertionError_str);
assertFail(assertion_type, node->msg ? visit_expr(node->msg).o : 0);
return Value();
......@@ -1194,7 +1187,7 @@ Value ASTInterpreter::visit_delete(AST_Delete* node) {
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (jit)
jit->emitDelGlobal(target->id.getBox());
delGlobal(globals, target->id.getBox());
delGlobal(frame_info.globals, target->id.getBox());
continue;
} else if (vst == ScopeInfo::VarScopeType::NAME) {
if (jit)
......@@ -1489,9 +1482,9 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
case ScopeInfo::VarScopeType::GLOBAL: {
Value v;
if (jit)
v.var = jit->emitGetGlobal(globals, node->id.getBox());
v.var = jit->emitGetGlobal(frame_info.globals, node->id.getBox());
v.o = getGlobal(globals, node->id.getBox());
v.o = getGlobal(frame_info.globals, node->id.getBox());
return v;
}
case ScopeInfo::VarScopeType::DEREF: {
......@@ -1529,7 +1522,7 @@ Value ASTInterpreter::visit_name(AST_Name* node) {
Value v;
if (jit)
v.var = jit->emitGetBoxedLocal(node->id.getBox());
v.o = boxedLocalsGet(frame_info.boxedLocals, node->id.getBox(), globals);
v.o = boxedLocalsGet(frame_info.boxedLocals, node->id.getBox(), frame_info.globals);
assert(gc::isValidGCObject(v.o));
return v;
}
......@@ -1590,7 +1583,7 @@ int ASTInterpreterJitInterface::getCurrentBlockOffset() {
}
int ASTInterpreterJitInterface::getCurrentInstOffset() {
return offsetof(ASTInterpreter, current_inst);
return offsetof(ASTInterpreter, frame_info.stmt);
}
int ASTInterpreterJitInterface::getGeneratorOffset() {
......@@ -1598,7 +1591,7 @@ int ASTInterpreterJitInterface::getGeneratorOffset() {
}
int ASTInterpreterJitInterface::getGlobalsOffset() {
return offsetof(ASTInterpreter, globals);
return offsetof(ASTInterpreter, frame_info.globals);
}
void ASTInterpreterJitInterface::delNameHelper(void* _interpreter, InternedString name) {
......@@ -1855,9 +1848,6 @@ static Box* astInterpretDeoptInner(FunctionMetadata* md, AST_expr* after_expr, A
interpreter.setPassedClosure(p.second);
} else if (name == CREATED_CLOSURE_NAME) {
interpreter.setCreatedClosure(p.second);
} else if (name == PASSED_GLOBALS_NAME) {
assert(!source_info->scoping->areGlobalsFromModule());
interpreter.setGlobals(p.second);
} else {
InternedString interned = md->source->getInternedStrings().get(name);
interpreter.addSymbol(interned, p.second, false);
......@@ -1937,18 +1927,6 @@ static ASTInterpreter* getInterpreterFromFramePtr(void* frame_ptr) {
return *ptr;
}
AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
return interpreter->getCurrentStatement();
}
Box* getGlobalsForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
return interpreter->getGlobals();
}
FunctionMetadata* getMDForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
......@@ -1961,12 +1939,6 @@ FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr) {
return interpreter->getFrameInfo();
}
Box** getVRegsForInterpretedFrame(void* frame_ptr) {
ASTInterpreter* interpreter = getInterpreterFromFramePtr(frame_ptr);
assert(interpreter);
return interpreter->getVRegs();
}
BoxedDict* localsForInterpretedFrame(Box** vregs, CFG* cfg) {
BoxedDict* rtn = new BoxedDict();
for (auto& l : cfg->sym_vreg_map_user_visible) {
......
......@@ -76,13 +76,10 @@ Box* astInterpretFunctionEval(FunctionMetadata* cf, Box* globals, Box* boxedLoca
Box* astInterpretDeopt(FunctionMetadata* cf, AST_expr* after_expr, AST_stmt* enclosing_stmt, Box* expr_val,
FrameStackState frame_state);
AST_stmt* getCurrentStatementForInterpretedFrame(void* frame_ptr);
Box* getGlobalsForInterpretedFrame(void* frame_ptr);
FunctionMetadata* getMDForInterpretedFrame(void* frame_ptr);
struct FrameInfo;
FrameInfo* getFrameInfoForInterpretedFrame(void* frame_ptr);
Box** getVRegsForInterpretedFrame(void* frame_ptr);
BoxedDict* localsForInterpretedFrame(Box** vregs, CFG* cfg);
BoxedDict* localsForInterpretedFrame(void* frame_ptr);
......
......@@ -369,6 +369,8 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
llvm_entry_blocks[block] = llvm::BasicBlock::Create(g.context, buf, irstate->getLLVMFunction());
}
llvm::Value* osr_frame_info_arg = NULL;
// the function entry block, where we add the type guards [no guards anymore]
llvm::BasicBlock* osr_entry_block = NULL;
llvm::BasicBlock* osr_unbox_block_end = NULL; // the block after type guards where we up/down-convert things
......@@ -438,17 +440,11 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
if (from_arg->getType() == g.llvm_frame_info_type->getPointerTo()) {
assert(p.first.s() == FRAME_INFO_PTR_NAME);
irstate->setFrameInfoArgument(from_arg);
osr_frame_info_arg = from_arg;
// Don't add the frame info to the symbol table since we will store it separately:
continue;
}
if (p.first.s() == PASSED_GLOBALS_NAME) {
assert(!source->scoping->areGlobalsFromModule());
irstate->setGlobals(from_arg);
continue;
}
ConcreteCompilerType* phi_type;
phi_type = getTypeAtBlockStart(types, p.first, target_block);
......@@ -609,13 +605,13 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
assert(osr_entry_block);
assert(phis);
irstate->setupFrameInfoVarOSR(osr_frame_info_arg);
for (const auto& p : entry_descriptor->args) {
// Don't add the frame info to the symbol table since we will store it separately
// (we manually added it during the calculation of osr_syms):
if (p.first.s() == FRAME_INFO_PTR_NAME)
continue;
if (p.first.s() == PASSED_GLOBALS_NAME)
continue;
ConcreteCompilerType* analyzed_type = getTypeAtBlockStart(types, p.first, block);
......
......@@ -56,9 +56,9 @@ IRGenState::IRGenState(FunctionMetadata* md, CompiledFunction* cf, SourceInfo* s
func_dbg_info(func_dbg_info),
scratch_space(NULL),
frame_info(NULL),
frame_info_arg(NULL),
globals(NULL),
vregs(NULL),
stmt(NULL),
scratch_size(0) {
assert(cf->func);
assert(!cf->md); // in this case don't need to pass in sourceinfo
......@@ -164,7 +164,18 @@ template <typename Builder> static llvm::Value* getVRegsGep(Builder& builder, ll
return builder.CreateConstInBoundsGEP2_32(v, 0, 4);
}
llvm::Value* IRGenState::getFrameInfoVar() {
template <typename Builder> static llvm::Value* getStmtGep(Builder& builder, llvm::Value* v) {
static_assert(offsetof(FrameInfo, stmt) == 56, "");
return builder.CreateConstInBoundsGEP2_32(v, 0, 5);
}
template <typename Builder> static llvm::Value* getGlobalsGep(Builder& builder, llvm::Value* v) {
static_assert(offsetof(FrameInfo, globals) == 64, "");
return builder.CreateConstInBoundsGEP2_32(v, 0, 6);
}
void IRGenState::setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* passed_globals,
llvm::Value* frame_info_arg) {
/*
There is a matrix of possibilities here.
......@@ -182,8 +193,7 @@ llvm::Value* IRGenState::getFrameInfoVar() {
- If the function is NAME-scope, we extract the boxedLocals from the frame_info in order
to set this->boxed_locals.
*/
if (!this->frame_info) {
assert(!frame_info);
llvm::BasicBlock& entry_block = getLLVMFunction()->getEntryBlock();
llvm::IRBuilder<true> builder(&entry_block);
......@@ -196,13 +206,20 @@ llvm::Value* IRGenState::getFrameInfoVar() {
else
builder.SetInsertPoint(&entry_block);
llvm::AllocaInst* al_pointer_to_frame_info
= builder.CreateAlloca(g.llvm_frame_info_type->getPointerTo(), NULL, "frame_info_ptr");
if (frame_info_arg) {
assert(!passed_closure);
assert(!passed_globals);
// The OSR case
this->frame_info = frame_info_arg;
// use vrags array from the interpreter
vregs = builder.CreateLoad(getVRegsGep(builder, frame_info_arg));
this->globals = builder.CreateLoad(getGlobalsGep(builder, frame_info_arg));
if (getScopeInfo()->usesNameLookup()) {
// load frame_info.boxedLocals
......@@ -211,7 +228,6 @@ llvm::Value* IRGenState::getFrameInfoVar() {
} else {
// The "normal" case
assert(!vregs);
getMD()->calculateNumVRegs();
int num_user_visible_vregs = getMD()->source->cfg->sym_vreg_map_user_visible.size();
......@@ -220,8 +236,7 @@ llvm::Value* IRGenState::getFrameInfoVar() {
= builder.CreateAlloca(g.llvm_value_type_ptr, getConstantInt(num_user_visible_vregs), "vregs");
// Clear the vregs array because 0 means undefined valued.
builder.CreateMemSet(vregs_alloca, getConstantInt(0, g.i8),
getConstantInt(num_user_visible_vregs * sizeof(Box*)),
vregs_alloca->getAlignment());
getConstantInt(num_user_visible_vregs * sizeof(Box*)), vregs_alloca->getAlignment());
vregs = vregs_alloca;
} else
vregs = getNullPtr(g.llvm_value_type_ptr_ptr);
......@@ -229,11 +244,12 @@ llvm::Value* IRGenState::getFrameInfoVar() {
llvm::AllocaInst* al = builder.CreateAlloca(g.llvm_frame_info_type, NULL, "frame_info");
assert(al->isStaticAlloca());
// frame_info.exc.type = NULL
llvm::Constant* null_value = getNullPtr(g.llvm_value_type_ptr);
llvm::Value* exc_info = getExcinfoGep(builder, al);
builder.CreateStore(
null_value, builder.CreateConstInBoundsGEP2_32(exc_info, 0, offsetof(ExcInfo, type) / sizeof(Box*)));
builder.CreateStore(null_value,
builder.CreateConstInBoundsGEP2_32(exc_info, 0, offsetof(ExcInfo, type) / sizeof(Box*)));
// frame_info.boxedLocals = NULL
llvm::Value* boxed_locals_gep = getBoxedLocalsGep(builder, al);
......@@ -251,34 +267,51 @@ llvm::Value* IRGenState::getFrameInfoVar() {
= llvm::cast<llvm::StructType>(g.llvm_frame_info_type)->getElementType(2);
builder.CreateStore(getNullPtr(llvm_frame_obj_type_ptr), getFrameObjGep(builder, al));
// frame_info.passed_closure = NULL
builder.CreateStore(getNullPtr(g.llvm_closure_type_ptr), getPassedClosureGep(builder, al));
// set frame_info.passed_closure
builder.CreateStore(passed_closure, getPassedClosureGep(builder, al));
// set frame_info.globals
builder.CreateStore(passed_globals, getGlobalsGep(builder, al));
// set frame_info.vregs
builder.CreateStore(vregs, getVRegsGep(builder, al));
this->frame_info = al;
this->globals = passed_globals;
}
}
return this->frame_info;
stmt = getStmtGep(builder, frame_info);
builder.CreateStore(this->frame_info, al_pointer_to_frame_info);
// Create stackmap to make a pointer to the frame_info location known
PatchpointInfo* info = PatchpointInfo::create(getCurFunction(), 0, 0, 0);
std::vector<llvm::Value*> args;
args.push_back(getConstantInt(info->getId(), g.i64));
args.push_back(getConstantInt(0, g.i32));
args.push_back(al_pointer_to_frame_info);
info->setNumFrameArgs(1);
info->setIsFrameInfoStackmap();
builder.CreateCall(llvm::Intrinsic::getDeclaration(g.cur_module, llvm::Intrinsic::experimental_stackmap), args);
}
llvm::Value* IRGenState::getFrameInfoVar() {
assert(frame_info);
return frame_info;
}
llvm::Value* IRGenState::getBoxedLocalsVar() {
assert(getScopeInfo()->usesNameLookup());
getFrameInfoVar(); // ensures this->boxed_locals_var is initialized
assert(this->boxed_locals != NULL);
return this->boxed_locals;
}
llvm::Value* IRGenState::getVRegsVar() {
if (!vregs) {
// calling this sets also the vregs member
getFrameInfoVar();
assert(vregs);
}
return vregs;
}
llvm::Value* IRGenState::getStmtVar() {
assert(stmt);
return stmt;
}
ScopeInfo* IRGenState::getScopeInfo() {
return getSourceInfo()->getScopeInfo();
}
......@@ -288,18 +321,9 @@ ScopeInfo* IRGenState::getScopeInfoForNode(AST* node) {
return source->scoping->getScopeInfoForNode(node);
}
void IRGenState::setGlobals(llvm::Value* globals) {
assert(!source_info->scoping->areGlobalsFromModule());
assert(!this->globals);
this->globals = globals;
}
llvm::Value* IRGenState::getGlobals() {
if (!globals) {
assert(source_info->scoping->areGlobalsFromModule());
this->globals = embedRelocatablePtr(source_info->parent_module, g.llvm_value_type_ptr);
}
return this->globals;
assert(globals);
return globals;
}
llvm::Value* IRGenState::getGlobalsIfCustom() {
......@@ -464,28 +488,11 @@ public:
}
#endif
if (ENABLE_FRAME_INTROSPECTION) {
llvm::Type* rtn_type = llvm::cast<llvm::FunctionType>(llvm::cast<llvm::PointerType>(callee->getType())
->getElementType())->getReturnType();
llvm::Value* bitcasted = getBuilder()->CreateBitCast(callee, g.i8->getPointerTo());
llvm::CallSite cs = emitPatchpoint(rtn_type, NULL, bitcasted, args, {}, unw_info, target_exception_style);
if (rtn_type == cs->getType()) {
return cs.getInstruction();
} else if (rtn_type == g.i1) {
return getBuilder()->CreateTrunc(cs.getInstruction(), rtn_type);
} else if (llvm::isa<llvm::PointerType>(rtn_type)) {
return getBuilder()->CreateIntToPtr(cs.getInstruction(), rtn_type);
} else {
cs.getInstruction()->getType()->dump();
rtn_type->dump();
RELEASE_ASSERT(0, "don't know how to convert those");
}
} else {
llvm::Value* stmt = unw_info.current_stmt ? embedRelocatablePtr(unw_info.current_stmt, g.llvm_aststmt_type_ptr)
: getNullPtr(g.llvm_aststmt_type_ptr);
getBuilder()->CreateStore(stmt, irstate->getStmtVar());
return emitCall(unw_info, callee, args, target_exception_style).getInstruction();
}
}
llvm::Value* createCall(const UnwindInfo& unw_info, llvm::Value* callee,
ExceptionStyle target_exception_style = CXX) override {
......@@ -577,7 +584,6 @@ const std::string CREATED_CLOSURE_NAME = "#created_closure";
const std::string PASSED_CLOSURE_NAME = "#passed_closure";
const std::string PASSED_GENERATOR_NAME = "#passed_generator";
const std::string FRAME_INFO_PTR_NAME = "#frame_info_ptr";
const std::string PASSED_GLOBALS_NAME = "#passed_globals";
bool isIsDefinedName(llvm::StringRef name) {
return startswith(name, "!is_defined_");
......@@ -1131,11 +1137,6 @@ private:
return new ConcreteCompilerVariable(typeFromClass(ellipsis_cls), ellipsis, false);
}
llvm::Constant* embedParentModulePtr() {
BoxedModule* parent_module = irstate->getSourceInfo()->parent_module;
return embedRelocatablePtr(parent_module, g.llvm_value_type_ptr, "cParentModule");
}
ConcreteCompilerVariable* _getGlobal(AST_Name* node, const UnwindInfo& unw_info) {
if (node->id.s() == "None")
return getNone();
......@@ -1778,7 +1779,7 @@ private:
if (vst == ScopeInfo::VarScopeType::GLOBAL) {
if (irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
auto parent_module = llvm::ConstantExpr::getPointerCast(embedParentModulePtr(), g.llvm_value_type_ptr);
auto parent_module = irstate->getGlobals();
ConcreteCompilerVariable* module = new ConcreteCompilerVariable(MODULE, parent_module, false);
module->setattr(emitter, getEmptyOpInfo(unw_info), name.getBox(), val);
module->decvref(emitter);
......@@ -2209,11 +2210,6 @@ private:
sorted_symbol_table[internString(FRAME_INFO_PTR_NAME)]
= new ConcreteCompilerVariable(FRAME_INFO, irstate->getFrameInfoVar(), true);
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
sorted_symbol_table[internString(PASSED_GLOBALS_NAME)]
= new ConcreteCompilerVariable(UNKNOWN, irstate->getGlobals(), true);
}
// For OSR calls, we use the same calling convention as in some other places; namely,
// arg1, arg2, arg3, argarray [nargs is ommitted]
// It would be nice to directly pass all variables as arguments, instead of packing them into
......@@ -2595,13 +2591,6 @@ public:
std::vector<llvm::Value*>& stackmap_args) override {
int initial_args = stackmap_args.size();
stackmap_args.push_back(irstate->getFrameInfoVar());
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
stackmap_args.push_back(irstate->getGlobals());
pp->addFrameVar(PASSED_GLOBALS_NAME, UNKNOWN);
}
assert(UNBOXED_INT->llvmType() == g.i64);
if (ENABLE_JIT_OBJECT_CACHE) {
llvm::Value* v;
......@@ -2756,40 +2745,48 @@ public:
auto scope_info = irstate->getScopeInfo();
llvm::Value* passed_closure = NULL;
llvm::Function::arg_iterator AI = irstate->getLLVMFunction()->arg_begin();
llvm::Value* passed_closure = NULL;
llvm::Value* generator = NULL;
llvm::Value* globals = NULL;
if (scope_info->takesClosure()) {
passed_closure = AI;
symbol_table[internString(PASSED_CLOSURE_NAME)]
= new ConcreteCompilerVariable(getPassedClosureType(), AI, true);
++AI;
} else
passed_closure = getNullPtr(g.llvm_closure_type_ptr);
// store the passed_closure inside the frame info so that frame introspection can access it without needing
// a stackmap entry
emitter.getBuilder()->CreateStore(passed_closure,
getPassedClosureGep(*emitter.getBuilder(), irstate->getFrameInfoVar()));
if (irstate->getSourceInfo()->is_generator) {
generator = AI;
++AI;
}
if (scope_info->createsClosure()) {
if (!passed_closure)
passed_closure = getNullPtr(g.llvm_closure_type_ptr);
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
globals = AI;
++AI;
} else {
BoxedModule* parent_module = irstate->getSourceInfo()->parent_module;
globals = embedRelocatablePtr(parent_module, g.llvm_value_type_ptr, "cParentModule");
}
irstate->setupFrameInfoVar(passed_closure, globals);
if (scope_info->takesClosure()) {
symbol_table[internString(PASSED_CLOSURE_NAME)]
= new ConcreteCompilerVariable(getPassedClosureType(), passed_closure, true);
}
if (scope_info->createsClosure()) {
llvm::Value* new_closure = emitter.getBuilder()->CreateCall2(
g.funcs.createClosure, passed_closure, getConstantInt(scope_info->getClosureSize(), g.i64));
symbol_table[internString(CREATED_CLOSURE_NAME)]
= new ConcreteCompilerVariable(getCreatedClosureType(), new_closure, true);
}
if (irstate->getSourceInfo()->is_generator) {
symbol_table[internString(PASSED_GENERATOR_NAME)] = new ConcreteCompilerVariable(GENERATOR, AI, true);
++AI;
}
if (!irstate->getSourceInfo()->scoping->areGlobalsFromModule()) {
irstate->setGlobals(AI);
++AI;
}
if (irstate->getSourceInfo()->is_generator)
symbol_table[internString(PASSED_GENERATOR_NAME)]
= new ConcreteCompilerVariable(GENERATOR, generator, true);
std::vector<llvm::Value*> python_parameters;
for (int i = 0; i < arg_types.size(); i++) {
......
......@@ -49,7 +49,6 @@ extern const std::string CREATED_CLOSURE_NAME;
extern const std::string PASSED_CLOSURE_NAME;
extern const std::string PASSED_GENERATOR_NAME;
extern const std::string FRAME_INFO_PTR_NAME;
extern const std::string PASSED_GLOBALS_NAME;
// Class that holds state of the current IR generation, that might not be local
......@@ -70,9 +69,9 @@ private:
llvm::AllocaInst* scratch_space;
llvm::Value* frame_info;
llvm::Value* boxed_locals;
llvm::Value* frame_info_arg;
llvm::Value* globals;
llvm::Value* vregs;
llvm::Value* stmt;
int scratch_size;
public:
......@@ -91,10 +90,15 @@ public:
GCBuilder* getGC() { return gc; }
void setupFrameInfoVar(llvm::Value* passed_closure, llvm::Value* passed_globals,
llvm::Value* frame_info_arg = NULL);
void setupFrameInfoVarOSR(llvm::Value* frame_info_arg) { return setupFrameInfoVar(NULL, NULL, frame_info_arg); }
llvm::Value* getScratchSpace(int min_bytes);
llvm::Value* getFrameInfoVar();
llvm::Value* getBoxedLocalsVar();
llvm::Value* getVRegsVar();
llvm::Value* getStmtVar();
ConcreteCompilerType* getReturnType() { return cf->getReturnType(); }
......@@ -110,9 +114,6 @@ public:
ParamNames* getParamNames() { return param_names; }
void setFrameInfoArgument(llvm::Value* v) { frame_info_arg = v; }
void setGlobals(llvm::Value* globals);
// Returns the custom globals, or the module if the globals come from the module.
llvm::Value* getGlobals();
// Returns the custom globals, or null if the globals come from the module.
......
......@@ -212,6 +212,9 @@ public:
RELEASE_ASSERT(arg.getType() == call->getOperand(op_idx)->getType(), "");
}
if (f->getName() == "allowGLReadPreemption")
continue;
assert(!f->isDeclaration());
CS.setCalledFunction(f);
calls.push_back(CS);
......
......@@ -80,16 +80,6 @@ void PatchpointInfo::parseLocationMap(StackMap::Record* r, LocationMap* map) {
// printf("parsing pp %ld:\n", reinterpret_cast<int64_t>(this));
StackMap::Record::Location frame_info_location = r->locations[cur_arg];
cur_arg++;
// We could allow the frame_info to exist in a different location for each callsite,
// but in reality it will always live at a fixed stack offset.
if (map->frameInfoFound()) {
assert(frame_info_location == map->frame_info_location);
} else {
map->frame_info_location = frame_info_location;
}
for (FrameVarInfo& frame_var : frame_vars) {
int num_args = frame_var.type->numFrameArgs();
......@@ -165,6 +155,16 @@ void processStackmap(CompiledFunction* cf, StackMap* stackmap) {
PatchpointInfo* pp = new_patchpoints[r->id].first;
assert(pp);
if (pp->isFrameInfoStackmap()) {
assert(r->locations.size() == pp->totalStackmapArgs());
StackMap::Record::Location frame_info_location = r->locations[0];
assert(!cf->location_map->frameInfoFound());
assert(frame_info_location.type == StackMap::Record::Location::Direct);
assert(frame_info_location.regnum == 6 /* must be rbp based */);
cf->location_map->frame_info_location = frame_info_location;
continue;
}
void* slowpath_func = PatchpointInfo::getSlowpathAddr(r->id);
if (VERBOSITY() >= 2) {
printf("Processing pp %ld; [%d, %d)\n", reinterpret_cast<int64_t>(pp), r->offset,
......
......@@ -106,6 +106,7 @@ private:
const ICSetupInfo* icinfo;
int num_ic_stackmap_args;
int num_frame_stackmap_args;
bool is_frame_info_stackmap;
std::vector<FrameVarInfo> frame_vars;
unsigned int id;
......@@ -115,6 +116,7 @@ private:
icinfo(icinfo),
num_ic_stackmap_args(num_ic_stackmap_args),
num_frame_stackmap_args(-1),
is_frame_info_stackmap(false),
id(0) {}
......@@ -129,6 +131,7 @@ public:
int scratchStackmapArg() { return 0; }
int scratchSize() { return 80 + MAX_FRAME_SPILLS * sizeof(void*); }
bool isDeopt() const { return icinfo ? icinfo->isDeopt() : false; }
bool isFrameInfoStackmap() const { return is_frame_info_stackmap; }
int numFrameSpillsSupported() const { return isDeopt() ? MAX_FRAME_SPILLS : 0; }
void addFrameVar(llvm::StringRef name, CompilerType* type);
......@@ -136,8 +139,9 @@ public:
assert(num_frame_stackmap_args == -1);
num_frame_stackmap_args = num_frame_args;
}
void setIsFrameInfoStackmap(bool b = true) { is_frame_info_stackmap = b; }
int icStackmapArgsStart() { return 1; }
int icStackmapArgsStart() { return isFrameInfoStackmap() ? 0 : 1; }
int numICStackmapArgs() { return num_ic_stackmap_args; }
int frameStackmapArgsStart() { return icStackmapArgsStart() + numICStackmapArgs(); }
......
......@@ -344,7 +344,6 @@ public:
assert(cf->location_map);
const LocationMap::LocationTable& table = cf->location_map->names[name];
assert(table.locations.size());
auto entry = table.findEntry(offset);
if (!entry)
......@@ -356,28 +355,17 @@ public:
AST_stmt* getCurrentStatement() {
if (id.type == PythonFrameId::COMPILED) {
auto locations = findLocations("!current_stmt");
RELEASE_ASSERT(locations.size() == 1, "%ld", locations.size());
if (locations.size() == 1)
return reinterpret_cast<AST_stmt*>(readLocation(locations[0]));
} else if (id.type == PythonFrameId::INTERPRETED) {
return getCurrentStatementForInterpretedFrame((void*)id.bp);
}
abort();
assert(getFrameInfo()->stmt);
return getFrameInfo()->stmt;
}
Box* getGlobals() {
if (id.type == PythonFrameId::COMPILED) {
CompiledFunction* cf = getCF();
if (cf->md->source->scoping->areGlobalsFromModule())
return cf->md->source->parent_module;
auto locations = findLocations(PASSED_GLOBALS_NAME);
assert(locations.size() == 1);
Box* r = (Box*)readLocation(locations[0]);
Box* r = getFrameInfo()->globals;
ASSERT(gc::isValidGCObject(r), "%p", r);
return r;
} else if (id.type == PythonFrameId::INTERPRETED) {
return getGlobalsForInterpretedFrame((void*)id.bp);
}
abort();
}
Box* getGlobalsDict() {
......@@ -395,8 +383,7 @@ public:
CompiledFunction* cf = getCF();
assert(cf->location_map->frameInfoFound());
const auto& frame_info_loc = cf->location_map->frame_info_location;
return reinterpret_cast<FrameInfo*>(readLocation(frame_info_loc));
return *reinterpret_cast<FrameInfo**>(readLocation(frame_info_loc));
} else if (id.type == PythonFrameId::INTERPRETED) {
return getFrameInfoForInterpretedFrame((void*)id.bp);
}
......
......@@ -37,7 +37,7 @@ bool ENABLE_INTERPRETER = true;
bool ENABLE_BASELINEJIT = true;
bool ENABLE_PYPA_PARSER = true;
bool ENABLE_CPYTHON_PARSER = false;
bool USE_REGALLOC_BASIC = true;
bool USE_REGALLOC_BASIC = false;
bool PAUSE_AT_ABORT = false;
bool ENABLE_TRACEBACKS = true;
// Forces the llvm jit to use capi exceptions whenever it can, as opposed to whenever it thinks
......@@ -81,7 +81,6 @@ bool ENABLE_JIT_OBJECT_CACHE = 1 && _GLOBAL_ENABLE;
bool LAZY_SCOPING_ANALYSIS = 1;
bool ENABLE_FRAME_INTROSPECTION = 1;
bool BOOLS_AS_I64 = ENABLE_FRAME_INTROSPECTION;
extern "C" {
int Py_FrozenFlag = 1;
......
......@@ -47,7 +47,7 @@ extern bool ENABLE_ICS, ENABLE_ICGENERICS, ENABLE_ICGETITEMS, ENABLE_ICSETITEMS,
LAZY_SCOPING_ANALYSIS;
// Due to a temporary LLVM limitation, represent bools as i64's instead of i1's.
extern bool BOOLS_AS_I64;
#define BOOLS_AS_I64 1
#define ENABLE_SAMPLING_PROFILER 0
}
......
......@@ -514,7 +514,11 @@ CompiledFunction* compileFunction(FunctionMetadata* f, FunctionSpecialization* s
ExceptionStyle forced_exception_style = CXX);
EffortLevel initialEffort();
typedef bool i1;
#if BOOLS_AS_I64
typedef int64_t llvm_compat_bool;
#else
typedef bool llvm_compat_bool;
#endif
typedef int64_t i64;
const char* getNameOfClass(BoxedClass* cls);
......@@ -886,8 +890,14 @@ struct FrameInfo {
BoxedClosure* passed_closure;
Box** vregs;
FrameInfo(ExcInfo exc) : exc(exc), boxedLocals(NULL), frame_obj(0), passed_closure(0), vregs(0) {}
// Current statement
// Caution the llvm tier only updates this information on direct external calls but not for patchpoints.
// This means if a patchpoint "current_stmt" info is available it must be used instead of this field.
AST_stmt* stmt;
// This is either a module or a dict
Box* globals;
FrameInfo(ExcInfo exc) : exc(exc), boxedLocals(NULL), frame_obj(0), passed_closure(0), vregs(0), stmt(0), globals(0) {}
void gcVisit(GCVisitor* visitor);
};
......
......@@ -49,7 +49,7 @@ Box* dictIterValues(Box* self);
Box* dictIterItems(Box* self);
Box* dictIterIter(Box* self);
Box* dictIterHasnext(Box* self);
i1 dictIterHasnextUnboxed(Box* self);
llvm_compat_bool dictIterHasnextUnboxed(Box* self);
Box* dictiter_next(Box* self) noexcept;
Box* dictIterNext(Box* self);
......
......@@ -289,7 +289,7 @@ template <ExceptionStyle S> static Box* generatorNext(Box* s) noexcept(S == CAPI
return generatorSend<S>(s, None);
}
i1 generatorHasnextUnboxed(Box* s) {
llvm_compat_bool generatorHasnextUnboxed(Box* s) {
assert(s->cls == generator_cls);
BoxedGenerator* self = static_cast<BoxedGenerator*>(s);
......
......@@ -47,5 +47,9 @@ i64 unboxInt(Box* b) {
return ((BoxedInt*)b)->n;
}
extern "C" bool hasnext(Box* o) {
return o->cls->tpp_hasnext(o);
}
// BoxedInt::BoxedInt(int64_t n) : Box(int_cls), n(n) {}
}
......@@ -49,7 +49,7 @@ Box* dictIterIter(Box* s) {
return s;
}
i1 dictIterHasnextUnboxed(Box* s) {
llvm_compat_bool dictIterHasnextUnboxed(Box* s) {
assert(s->cls == dict_iterator_cls);
BoxedDictIterator* self = static_cast<BoxedDictIterator*>(s);
......
......@@ -50,7 +50,7 @@ Box* listiterHasnext(Box* s) {
return boxBool(ans);
}
i1 listiterHasnextUnboxed(Box* s) {
llvm_compat_bool listiterHasnextUnboxed(Box* s) {
assert(s->cls == list_iterator_cls);
BoxedListIterator* self = static_cast<BoxedListIterator*>(s);
......@@ -82,22 +82,6 @@ Box* listiter_next(Box* s) noexcept {
return rtn;
}
template <ExceptionStyle S> Box* listiterNext(Box* s) noexcept(S == CAPI) {
Box* rtn = listiter_next(s);
if (!rtn) {
if (S == CAPI) {
PyErr_SetObject(StopIteration, None);
return NULL;
} else
raiseExcHelper(StopIteration, "");
}
return rtn;
}
// force instantiation:
template Box* listiterNext<CAPI>(Box*);
template Box* listiterNext<CXX>(Box*);
Box* listReversed(Box* s) {
assert(PyList_Check(s));
BoxedList* self = static_cast<BoxedList*>(s);
......@@ -111,7 +95,7 @@ Box* listreviterHasnext(Box* s) {
return boxBool(self->pos >= 0);
}
i1 listreviterHasnextUnboxed(Box* s) {
llvm_compat_bool listreviterHasnextUnboxed(Box* s) {
assert(s->cls == list_reverse_iterator_cls);
BoxedListIterator* self = static_cast<BoxedListIterator*>(s);
......
......@@ -36,7 +36,7 @@ Box* tupleiterHasnext(Box* s) {
return boxBool(tupleiterHasnextUnboxed(s));
}
i1 tupleiterHasnextUnboxed(Box* s) {
llvm_compat_bool tupleiterHasnextUnboxed(Box* s) {
assert(s->cls == tuple_iterator_cls);
BoxedTupleIterator* self = static_cast<BoxedTupleIterator*>(s);
......
......@@ -87,7 +87,7 @@ public:
DEFAULT_CLASS(xrange_iterator_cls);
static bool xrangeIteratorHasnextUnboxed(Box* s) __attribute__((visibility("default"))) {
static llvm_compat_bool xrangeIteratorHasnextUnboxed(Box* s) __attribute__((visibility("default"))) {
assert(s->cls == xrange_iterator_cls);
BoxedXrangeIterator* self = static_cast<BoxedXrangeIterator*>(s);
......
......@@ -397,31 +397,6 @@ extern "C" Box* mul_i64_i64(i64 lhs, i64 rhs) {
return longMul(boxLong(lhs), boxLong(rhs));
}
extern "C" i1 eq_i64_i64(i64 lhs, i64 rhs) {
return lhs == rhs;
}
extern "C" i1 ne_i64_i64(i64 lhs, i64 rhs) {
return lhs != rhs;
}
extern "C" i1 lt_i64_i64(i64 lhs, i64 rhs) {
return lhs < rhs;
}
extern "C" i1 le_i64_i64(i64 lhs, i64 rhs) {
return lhs <= rhs;
}
extern "C" i1 gt_i64_i64(i64 lhs, i64 rhs) {
return lhs > rhs;
}
extern "C" i1 ge_i64_i64(i64 lhs, i64 rhs) {
return lhs >= rhs;
}
extern "C" Box* intAddInt(BoxedInt* lhs, BoxedInt* rhs) {
assert(PyInt_Check(lhs));
assert(PyInt_Check(rhs));
......
......@@ -34,12 +34,6 @@ extern "C" Box* add_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* sub_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs, Box* mod = None);
extern "C" Box* mul_i64_i64(i64 lhs, i64 rhs);
extern "C" i1 eq_i64_i64(i64 lhs, i64 rhs);
extern "C" i1 ne_i64_i64(i64 lhs, i64 rhs);
extern "C" i1 lt_i64_i64(i64 lhs, i64 rhs);
extern "C" i1 le_i64_i64(i64 lhs, i64 rhs);
extern "C" i1 gt_i64_i64(i64 lhs, i64 rhs);
extern "C" i1 ge_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* intAdd(BoxedInt* lhs, Box* rhs);
extern "C" Box* intAnd(BoxedInt* lhs, Box* rhs);
extern "C" Box* intDiv(BoxedInt* lhs, Box* rhs);
......
......@@ -70,7 +70,7 @@ Box* seqiterHasnext(Box* s) {
return rtn;
}
bool seqiterHasnextUnboxed(Box* s) {
llvm_compat_bool seqiterHasnextUnboxed(Box* s) {
return unboxBool(seqiterHasnext(s));
}
......@@ -151,7 +151,7 @@ void BoxedIterWrapper::gcHandler(GCVisitor* v, Box* b) {
v->visit(&iw->next);
}
bool iterwrapperHasnextUnboxed(Box* s) {
llvm_compat_bool iterwrapperHasnextUnboxed(Box* s) {
RELEASE_ASSERT(s->cls == iterwrapper_cls, "");
BoxedIterWrapper* self = static_cast<BoxedIterWrapper*>(s);
......@@ -196,7 +196,7 @@ extern "C" PyObject* PySeqIter_New(PyObject* seq) noexcept {
}
}
bool calliter_hasnext(Box* b) {
llvm_compat_bool calliterHasnextUnboxed(Box* b) {
calliterobject* it = (calliterobject*)b;
if (!it->it_nextvalue) {
it->it_nextvalue = calliter_next(it);
......
......@@ -55,7 +55,7 @@ public:
static void gcHandler(GCVisitor* v, Box* b);
};
bool calliter_hasnext(Box* b);
llvm_compat_bool calliterHasnextUnboxed(Box* b);
void setupIter();
}
......
......@@ -1246,6 +1246,22 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
}
}
template <ExceptionStyle S> Box* listiterNext(Box* s) noexcept(S == CAPI) {
Box* rtn = listiter_next(s);
if (!rtn) {
if (S == CAPI) {
PyErr_SetObject(StopIteration, None);
return NULL;
} else
raiseExcHelper(StopIteration, (const char*)NULL);
}
return rtn;
}
// force instantiation:
template Box* listiterNext<CAPI>(Box*) noexcept;
template Box* listiterNext<CXX>(Box*);
void BoxedListIterator::gcHandler(GCVisitor* v, Box* b) {
Box::gcHandler(v, b);
BoxedListIterator* it = (BoxedListIterator*)b;
......
......@@ -36,12 +36,12 @@ public:
Box* listIter(Box* self) noexcept;
Box* listIterIter(Box* self);
Box* listiterHasnext(Box* self);
i1 listiterHasnextUnboxed(Box* self);
llvm_compat_bool listiterHasnextUnboxed(Box* self);
template <ExceptionStyle S> Box* listiterNext(Box* self) noexcept(S == CAPI);
Box* listiter_next(Box* s) noexcept;
Box* listReversed(Box* self);
Box* listreviterHasnext(Box* self);
i1 listreviterHasnextUnboxed(Box* self);
llvm_compat_bool listreviterHasnextUnboxed(Box* self);
Box* listreviterNext(Box* self);
Box* listreviter_next(Box* s) noexcept;
void listSort(BoxedList* self, Box* cmp, Box* key, Box* reverse);
......
......@@ -2361,7 +2361,7 @@ public:
DEFAULT_CLASS(str_iterator_cls);
static bool hasnextUnboxed(BoxedStringIterator* self) {
static llvm_compat_bool hasnextUnboxed(BoxedStringIterator* self) {
assert(self->cls == str_iterator_cls);
return self->it != self->end;
}
......
......@@ -35,7 +35,7 @@ public:
Box* tupleIter(Box* self) noexcept;
Box* tupleIterIter(Box* self);
Box* tupleiterHasnext(Box* self);
i1 tupleiterHasnextUnboxed(Box* self);
llvm_compat_bool tupleiterHasnextUnboxed(Box* self);
Box* tupleiter_next(Box* self) noexcept;
Box* tupleiterNext(Box* self);
}
......
......@@ -4089,7 +4089,7 @@ void setupRuntime() {
PyType_Ready(&PyByteArrayIter_Type);
PyType_Ready(&PyCapsule_Type);
PyCallIter_Type.tpp_hasnext = calliter_hasnext;
PyCallIter_Type.tpp_hasnext = calliterHasnextUnboxed;
PyType_Ready(&PyCallIter_Type);
PyType_Ready(&PyCObject_Type);
......
......@@ -257,7 +257,7 @@ public:
bool has_subclasscheck;
bool has_getattribute;
typedef bool (*pyston_inquiry)(Box*);
typedef llvm_compat_bool (*pyston_inquiry)(Box*);
// tpp_descr_get is currently just a cache only for the use of tp_descr_get, and shouldn't
// be called or examined by clients:
......
......@@ -117,10 +117,6 @@ Box* boxStringFromCharPtr(const char* s) {
return boxString(s);
}
extern "C" bool hasnext(Box* o) {
return o->cls->tpp_hasnext(o);
}
extern "C" void dump(void* p) {
dumpEx(p, 0);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment