Commit 061e994b authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Kevin Modzelewski

Move closure/generators out of the irgen symbol table

parent 8052061e
...@@ -585,7 +585,7 @@ std::unique_ptr<PhiAnalysis> computeRequiredPhis(const OSREntryDescriptor* entry ...@@ -585,7 +585,7 @@ std::unique_ptr<PhiAnalysis> computeRequiredPhis(const OSREntryDescriptor* entry
continue; continue;
if (p.first.s() == PASSED_CLOSURE_NAME || p.first.s() == FRAME_INFO_PTR_NAME if (p.first.s() == PASSED_CLOSURE_NAME || p.first.s() == FRAME_INFO_PTR_NAME
|| p.first.s() == PASSED_GENERATOR_NAME || p.first.s() == CREATED_CLOSURE_NAME) || p.first.s() == PASSED_GENERATOR_NAME || p.first.s() == CREATED_CLOSURE_NAME)
continue; assert(0);
int vreg = cfg->getVRegInfo().getVReg(p.first); int vreg = cfg->getVRegInfo().getVReg(p.first);
ASSERT(initial_map[vreg] == DefinednessAnalysis::Undefined, "%s %d", p.first.c_str(), initial_map[vreg]); ASSERT(initial_map[vreg] == DefinednessAnalysis::Undefined, "%s %d", p.first.c_str(), initial_map[vreg]);
if (potentially_undefined.count(p.first.s())) if (potentially_undefined.count(p.first.s()))
......
...@@ -115,6 +115,14 @@ public: ...@@ -115,6 +115,14 @@ public:
v[vreg] = true; v[vreg] = true;
} }
int numSet() const {
int r = 0;
for (auto b : v)
if (b)
r++;
return r;
}
class iterator { class iterator {
public: public:
const VRegSet& set; const VRegSet& set;
......
...@@ -905,7 +905,7 @@ TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortL ...@@ -905,7 +905,7 @@ TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortL
continue; continue;
if (p.first.s() == PASSED_CLOSURE_NAME || p.first.s() == FRAME_INFO_PTR_NAME if (p.first.s() == PASSED_CLOSURE_NAME || p.first.s() == FRAME_INFO_PTR_NAME
|| p.first.s() == PASSED_GENERATOR_NAME || p.first.s() == CREATED_CLOSURE_NAME) || p.first.s() == PASSED_GENERATOR_NAME || p.first.s() == CREATED_CLOSURE_NAME)
continue; assert(0);
initial_types[vreg_info.getVReg(p.first)] = p.second; initial_types[vreg_info.getVReg(p.first)] = p.second;
} }
......
...@@ -775,32 +775,12 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) { ...@@ -775,32 +775,12 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
return nullptr; return nullptr;
} }
if (generator) {
// generated is only borrowed in order to not introduce cycles
sorted_symbol_table[source_info->getInternedStrings().get(PASSED_GENERATOR_NAME)] = generator;
}
if (frame_info.passed_closure)
sorted_symbol_table[source_info->getInternedStrings().get(PASSED_CLOSURE_NAME)]
= incref(frame_info.passed_closure);
if (created_closure)
sorted_symbol_table[source_info->getInternedStrings().get(CREATED_CLOSURE_NAME)] = incref(created_closure);
sorted_symbol_table[source_info->getInternedStrings().get(FRAME_INFO_PTR_NAME)] = (Box*)&frame_info;
if (found_entry == nullptr) { if (found_entry == nullptr) {
OSREntryDescriptor* entry = OSREntryDescriptor::create(getMD(), node, CXX); OSREntryDescriptor* entry = OSREntryDescriptor::create(getMD(), node, CXX);
for (auto& it : sorted_symbol_table) { for (auto& it : sorted_symbol_table) {
if (isIsDefinedName(it.first)) if (isIsDefinedName(it.first))
entry->args[it.first] = BOOL; entry->args[it.first] = BOOL;
else if (it.first.s() == PASSED_GENERATOR_NAME)
entry->args[it.first] = GENERATOR;
else if (it.first.s() == PASSED_CLOSURE_NAME || it.first.s() == CREATED_CLOSURE_NAME)
entry->args[it.first] = CLOSURE;
else if (it.first.s() == FRAME_INFO_PTR_NAME)
entry->args[it.first] = FRAME_INFO;
else { else {
assert(it.first.s()[0] != '!'); assert(it.first.s()[0] != '!');
entry->args[it.first] = UNKNOWN; entry->args[it.first] = UNKNOWN;
...@@ -821,9 +801,8 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) { ...@@ -821,9 +801,8 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code"); UNAVOIDABLE_STAT_TIMER(t0, "us_timer_in_jitted_code");
CompiledFunction* partial_func = compilePartialFuncInternal(&exit); CompiledFunction* partial_func = compilePartialFuncInternal(&exit);
auto arg_tuple = getTupleFromArgsArray(&arg_array[0], arg_array.size()); // generated is only borrowed in order to not introduce cycles
Box* r = partial_func->call(std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple), Box* r = partial_func->call_osr(generator, created_closure, &frame_info, &arg_array[0]);
std::get<3>(arg_tuple));
if (partial_func->exception_style == CXX) { if (partial_func->exception_style == CXX) {
assert(r); assert(r);
......
...@@ -821,19 +821,15 @@ ConcreteCompilerVariable* UnknownType::hasnext(IREmitter& emitter, const OpInfo& ...@@ -821,19 +821,15 @@ ConcreteCompilerVariable* UnknownType::hasnext(IREmitter& emitter, const OpInfo&
return boolFromI1(emitter, rtn_val); return boolFromI1(emitter, rtn_val);
} }
CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata* f, CompilerVariable* closure, llvm::Value* globals, CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata* f, llvm::Value* closure, llvm::Value* globals,
const std::vector<ConcreteCompilerVariable*>& defaults) { const std::vector<ConcreteCompilerVariable*>& defaults) {
// Unlike the FunctionMetadata*, which can be shared between recompilations, the Box* around it // Unlike the FunctionMetadata*, which can be shared between recompilations, the Box* around it
// should be created anew every time the functiondef is encountered // should be created anew every time the functiondef is encountered
llvm::Value* closure_v;
ConcreteCompilerVariable* convertedClosure = NULL; ConcreteCompilerVariable* convertedClosure = NULL;
if (closure) { if (!closure) {
convertedClosure = closure->makeConverted(emitter, closure->getConcreteType()); closure = getNullPtr(g.llvm_closure_type_ptr);
closure_v = convertedClosure->getValue(); emitter.setType(closure, RefType::BORROWED);
} else {
closure_v = getNullPtr(g.llvm_closure_type_ptr);
emitter.setType(closure_v, RefType::BORROWED);
} }
llvm::SmallVector<llvm::Value*, 4> array_passed_args; llvm::SmallVector<llvm::Value*, 4> array_passed_args;
...@@ -860,8 +856,8 @@ CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata* f, Compiler ...@@ -860,8 +856,8 @@ CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata* f, Compiler
// emitter.createCall(). // emitter.createCall().
llvm::Instruction* boxed = emitter.getBuilder()->CreateCall( llvm::Instruction* boxed = emitter.getBuilder()->CreateCall(
g.funcs.createFunctionFromMetadata, g.funcs.createFunctionFromMetadata,
std::vector<llvm::Value*>{ embedRelocatablePtr(f, g.llvm_functionmetadata_type_ptr), closure_v, globals, std::vector<llvm::Value*>{ embedRelocatablePtr(f, g.llvm_functionmetadata_type_ptr), closure, globals, scratch,
scratch, getConstantInt(defaults.size(), g.i64) }); getConstantInt(defaults.size(), g.i64) });
emitter.setType(boxed, RefType::OWNED); emitter.setType(boxed, RefType::OWNED);
// The refcounter needs to know that this call "uses" the arguments that got passed via scratch. // The refcounter needs to know that this call "uses" the arguments that got passed via scratch.
......
...@@ -361,7 +361,7 @@ UnboxedSlice extractSlice(CompilerVariable* slice); ...@@ -361,7 +361,7 @@ UnboxedSlice extractSlice(CompilerVariable* slice);
#if 0 #if 0
CompilerVariable* makeUnicode(IREmitter& emitter, llvm::StringRef); CompilerVariable* makeUnicode(IREmitter& emitter, llvm::StringRef);
#endif #endif
CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata*, CompilerVariable* closure, llvm::Value* globals, CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata*, llvm::Value* closure, llvm::Value* globals,
const std::vector<ConcreteCompilerVariable*>& defaults); const std::vector<ConcreteCompilerVariable*>& defaults);
ConcreteCompilerVariable* undefVariable(); ConcreteCompilerVariable* undefVariable();
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts); CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts);
......
...@@ -290,12 +290,6 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt ...@@ -290,12 +290,6 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
CFGBlock* block) { CFGBlock* block) {
if (isIsDefinedName(name)) if (isIsDefinedName(name))
return BOOL; return BOOL;
else if (name.s() == PASSED_GENERATOR_NAME)
return GENERATOR;
else if (name.s() == PASSED_CLOSURE_NAME)
return CLOSURE;
else if (name.s() == CREATED_CLOSURE_NAME)
return CLOSURE;
else { else {
// This could crash if we call getTypeAtBlockStart on something that doesn't have a type or vreg. // This could crash if we call getTypeAtBlockStart on something that doesn't have a type or vreg.
// Luckily it looks like we don't do that. // Luckily it looks like we don't do that.
...@@ -306,7 +300,7 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt ...@@ -306,7 +300,7 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
static bool shouldPhisOwnThisSym(llvm::StringRef name) { static bool shouldPhisOwnThisSym(llvm::StringRef name) {
// generating unnecessary increfs to the passed generator would introduce cycles inside the generator // generating unnecessary increfs to the passed generator would introduce cycles inside the generator
if (name == PASSED_GENERATOR_NAME) if (name == PASSED_GENERATOR_NAME)
return false; assert(0);
return true; return true;
} }
...@@ -384,7 +378,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -384,7 +378,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
llvm_entry_blocks[block] = llvm::BasicBlock::Create(g.context, buf, irstate->getLLVMFunction()); llvm_entry_blocks[block] = llvm::BasicBlock::Create(g.context, buf, irstate->getLLVMFunction());
} }
llvm::Value* osr_frame_info_arg = NULL; llvm::Value* osr_frame_info_arg = NULL, * osr_generator = NULL, * osr_created_closure = NULL;
// the function entry block, where we add the type guards [no guards anymore] // the function entry block, where we add the type guards [no guards anymore]
llvm::BasicBlock* osr_entry_block = NULL; llvm::BasicBlock* osr_entry_block = NULL;
...@@ -415,50 +409,43 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -415,50 +409,43 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
} }
// Handle loading symbols from the passed osr arguments: // Handle loading symbols from the passed osr arguments:
osr_generator = func_args[0];
osr_created_closure = func_args[1];
osr_frame_info_arg = func_args[2];
llvm::Value* passed_vars = func_args[3];
assert(func_args.size() == 4);
irstate->getRefcounts()->setType(osr_generator, RefType::BORROWED);
irstate->getRefcounts()->setType(osr_created_closure, RefType::BORROWED);
if (source->is_generator)
irstate->setPassedGenerator(osr_generator);
if (source->getScopeInfo()->createsClosure())
irstate->setCreatedClosure(osr_created_closure);
int arg_num = -1; int arg_num = -1;
for (const auto& p : entry_descriptor->args) { for (const auto& p : entry_descriptor->args) {
llvm::Value* from_arg; llvm::Value* from_arg;
arg_num++; arg_num++;
if (arg_num < 3) {
from_arg = func_args[arg_num];
#ifndef NDEBUG
if (from_arg->getType() != p.second->llvmType()) {
from_arg->getType()->dump();
printf("\n");
p.second->llvmType()->dump();
printf("\n");
}
#endif
assert(from_arg->getType() == p.second->llvmType());
} else {
ASSERT(func_args.size() == 4, "%ld", func_args.size());
llvm::Value* ptr = entry_emitter->getBuilder()->CreateConstGEP1_32(func_args[3], arg_num - 3);
if (p.second == INT) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.i64->getPointerTo());
} else if (p.second == BOOL) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, BOOL->llvmType()->getPointerTo());
} else if (p.second == FLOAT) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.double_->getPointerTo());
} else if (p.second == GENERATOR) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.llvm_generator_type_ptr->getPointerTo());
} else if (p.second == CLOSURE) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.llvm_closure_type_ptr->getPointerTo());
} else if (p.second == FRAME_INFO) {
ptr = entry_emitter->getBuilder()->CreateBitCast(
ptr, g.llvm_frame_info_type->getPointerTo()->getPointerTo());
} else {
assert(p.second->llvmType() == g.llvm_value_type_ptr);
}
from_arg = entry_emitter->getBuilder()->CreateLoad(ptr);
assert(from_arg->getType() == p.second->llvmType());
}
if (from_arg->getType() == g.llvm_frame_info_type->getPointerTo()) { llvm::Value* ptr = entry_emitter->getBuilder()->CreateConstGEP1_32(passed_vars, arg_num);
assert(p.first.s() == FRAME_INFO_PTR_NAME); if (p.second == INT) {
osr_frame_info_arg = from_arg; ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.i64->getPointerTo());
// Don't add the frame info to the symbol table since we will store it separately: } else if (p.second == BOOL) {
continue; ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, BOOL->llvmType()->getPointerTo());
} else if (p.second == FLOAT) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.double_->getPointerTo());
} else if (p.second == GENERATOR) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.llvm_generator_type_ptr->getPointerTo());
} else if (p.second == CLOSURE) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.llvm_closure_type_ptr->getPointerTo());
} else if (p.second == FRAME_INFO) {
ptr = entry_emitter->getBuilder()->CreateBitCast(
ptr, g.llvm_frame_info_type->getPointerTo()->getPointerTo());
} else {
assert(p.second->llvmType() == g.llvm_value_type_ptr);
} }
from_arg = entry_emitter->getBuilder()->CreateLoad(ptr);
assert(from_arg->getType() == p.second->llvmType());
ConcreteCompilerType* phi_type; ConcreteCompilerType* phi_type;
phi_type = getTypeAtBlockStart(types, p.first, vreg_info, target_block); phi_type = getTypeAtBlockStart(types, p.first, vreg_info, target_block);
...@@ -665,17 +652,6 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc ...@@ -665,17 +652,6 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
} }
} }
if (source->getScopeInfo()->createsClosure())
names.insert(source->getInternedStrings().get(CREATED_CLOSURE_NAME));
if (source->getScopeInfo()->takesClosure())
names.insert(source->getInternedStrings().get(PASSED_CLOSURE_NAME));
if (source->is_generator) {
assert(0 && "not sure if this is correct");
names.insert(source->getInternedStrings().get(PASSED_GENERATOR_NAME));
}
for (const InternedString& s : names) { for (const InternedString& s : names) {
// printf("adding guessed phi for %s\n", s.c_str()); // printf("adding guessed phi for %s\n", s.c_str());
ConcreteCompilerType* type = getTypeAtBlockStart(types, s, vreg_info, block); ConcreteCompilerType* type = getTypeAtBlockStart(types, s, vreg_info, block);
...@@ -1062,17 +1038,11 @@ CompiledFunction* doCompile(FunctionMetadata* md, SourceInfo* source, ParamNames ...@@ -1062,17 +1038,11 @@ CompiledFunction* doCompile(FunctionMetadata* md, SourceInfo* source, ParamNames
llvm_arg_types.push_back(spec->arg_types[i]->llvmType()); llvm_arg_types.push_back(spec->arg_types[i]->llvmType());
} }
} else { } else {
int arg_num = -1; // For simplicity, OSR entries always take all possible arguments:
for (const auto& p : entry_descriptor->args) { llvm_arg_types.push_back(g.llvm_generator_type_ptr);
arg_num++; llvm_arg_types.push_back(g.llvm_closure_type_ptr);
// printf("Loading %s: %s\n", p.first.c_str(), p.second->debugName().c_str()); llvm_arg_types.push_back(g.llvm_frame_info_type->getPointerTo());
if (arg_num < 3) llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
llvm_arg_types.push_back(p.second->llvmType());
else {
llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
break;
}
}
} }
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor); CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor);
......
This diff is collapsed.
...@@ -75,6 +75,9 @@ private: ...@@ -75,6 +75,9 @@ private:
llvm::Value* globals; llvm::Value* globals;
llvm::Value* vregs; llvm::Value* vregs;
llvm::Value* stmt; llvm::Value* stmt;
llvm::Value* passed_closure = NULL, * created_closure = NULL, * passed_generator = NULL;
int scratch_size; int scratch_size;
public: public:
...@@ -121,6 +124,14 @@ public: ...@@ -121,6 +124,14 @@ public:
ParamNames* getParamNames() { return param_names; } ParamNames* getParamNames() { return param_names; }
llvm::Value* getPassedClosure();
llvm::Value* getCreatedClosure();
llvm::Value* getPassedGenerator();
void setPassedClosure(llvm::Value*);
void setCreatedClosure(llvm::Value*);
void setPassedGenerator(llvm::Value*);
// Returns the custom globals, or the module if the globals come from the module. // Returns the custom globals, or the module if the globals come from the module.
llvm::Value* getGlobals(); llvm::Value* getGlobals();
// Returns the custom globals, or null if the globals come from the module. // Returns the custom globals, or null if the globals come from the module.
......
...@@ -517,9 +517,11 @@ private: ...@@ -517,9 +517,11 @@ private:
return node; return node;
} }
void pushJump(CFGBlock* target, bool allow_backedge = false) { void pushJump(CFGBlock* target, bool allow_backedge = false, int lineno = 0) {
AST_Jump* rtn = new AST_Jump(); AST_Jump* rtn = new AST_Jump();
rtn->target = target; rtn->target = target;
rtn->lineno = lineno;
push_back(rtn); push_back(rtn);
curblock->connectTo(target, allow_backedge); curblock->connectTo(target, allow_backedge);
curblock = nullptr; curblock = nullptr;
...@@ -2264,7 +2266,7 @@ public: ...@@ -2264,7 +2266,7 @@ public:
curblock->connectTo(end_false); curblock->connectTo(end_false);
curblock = end_true; curblock = end_true;
pushJump(loop_block, true); pushJump(loop_block, true, getLastLinenoSub(node->body.back()));
curblock = end_false; curblock = end_false;
pushJump(else_block); pushJump(else_block);
......
...@@ -316,6 +316,7 @@ class BoxedGenerator; ...@@ -316,6 +316,7 @@ class BoxedGenerator;
class ICInfo; class ICInfo;
class LocationMap; class LocationMap;
class JitCodeBlock; class JitCodeBlock;
class FrameInfo;
extern std::vector<Box*> constants; extern std::vector<Box*> constants;
extern std::vector<Box*> late_constants; // constants that should be freed after normal constants extern std::vector<Box*> late_constants; // constants that should be freed after normal constants
...@@ -346,6 +347,8 @@ public: ...@@ -346,6 +347,8 @@ public:
// The function pointer to the generated code. For convenience, it can be accessed // The function pointer to the generated code. For convenience, it can be accessed
// as one of many different types. // as one of many different types.
// TODO: we instead make these functions that make sure that the function actually
// matches the C signature that we would return.
union { union {
Box* (*call)(Box*, Box*, Box*, Box**); Box* (*call)(Box*, Box*, Box*, Box**);
Box* (*closure_call)(BoxedClosure*, Box*, Box*, Box*, Box**); Box* (*closure_call)(BoxedClosure*, Box*, Box*, Box*, Box**);
...@@ -354,6 +357,7 @@ public: ...@@ -354,6 +357,7 @@ public:
Box* (*call1)(Box*, Box*, Box*, Box*, Box**); Box* (*call1)(Box*, Box*, Box*, Box*, Box**);
Box* (*call2)(Box*, Box*, Box*, Box*, Box*, Box**); Box* (*call2)(Box*, Box*, Box*, Box*, Box*, Box**);
Box* (*call3)(Box*, Box*, Box*, Box*, Box*, Box*, Box**); Box* (*call3)(Box*, Box*, Box*, Box*, Box*, Box*, Box**);
Box* (*call_osr)(BoxedGenerator*, BoxedClosure*, FrameInfo*, Box**);
void* code; void* code;
uintptr_t code_start; uintptr_t code_start;
}; };
......
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