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
continue;
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)
continue;
assert(0);
int vreg = cfg->getVRegInfo().getVReg(p.first);
ASSERT(initial_map[vreg] == DefinednessAnalysis::Undefined, "%s %d", p.first.c_str(), initial_map[vreg]);
if (potentially_undefined.count(p.first.s()))
......
......@@ -115,6 +115,14 @@ public:
v[vreg] = true;
}
int numSet() const {
int r = 0;
for (auto b : v)
if (b)
r++;
return r;
}
class iterator {
public:
const VRegSet& set;
......
......@@ -905,7 +905,7 @@ TypeAnalysis* doTypeAnalysis(const OSREntryDescriptor* entry_descriptor, EffortL
continue;
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)
continue;
assert(0);
initial_types[vreg_info.getVReg(p.first)] = p.second;
}
......
......@@ -775,32 +775,12 @@ Box* ASTInterpreter::doOSR(AST_Jump* node) {
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) {
OSREntryDescriptor* entry = OSREntryDescriptor::create(getMD(), node, CXX);
for (auto& it : sorted_symbol_table) {
if (isIsDefinedName(it.first))
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 {
assert(it.first.s()[0] != '!');
entry->args[it.first] = UNKNOWN;
......@@ -821,9 +801,8 @@ 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));
// generated is only borrowed in order to not introduce cycles
Box* r = partial_func->call_osr(generator, created_closure, &frame_info, &arg_array[0]);
if (partial_func->exception_style == CXX) {
assert(r);
......
......@@ -821,19 +821,15 @@ ConcreteCompilerVariable* UnknownType::hasnext(IREmitter& emitter, const OpInfo&
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) {
// Unlike the FunctionMetadata*, which can be shared between recompilations, the Box* around it
// should be created anew every time the functiondef is encountered
llvm::Value* closure_v;
ConcreteCompilerVariable* convertedClosure = NULL;
if (closure) {
convertedClosure = closure->makeConverted(emitter, closure->getConcreteType());
closure_v = convertedClosure->getValue();
} else {
closure_v = getNullPtr(g.llvm_closure_type_ptr);
emitter.setType(closure_v, RefType::BORROWED);
if (!closure) {
closure = getNullPtr(g.llvm_closure_type_ptr);
emitter.setType(closure, RefType::BORROWED);
}
llvm::SmallVector<llvm::Value*, 4> array_passed_args;
......@@ -860,8 +856,8 @@ CompilerVariable* makeFunction(IREmitter& emitter, FunctionMetadata* f, Compiler
// emitter.createCall().
llvm::Instruction* boxed = emitter.getBuilder()->CreateCall(
g.funcs.createFunctionFromMetadata,
std::vector<llvm::Value*>{ embedRelocatablePtr(f, g.llvm_functionmetadata_type_ptr), closure_v, globals,
scratch, getConstantInt(defaults.size(), g.i64) });
std::vector<llvm::Value*>{ embedRelocatablePtr(f, g.llvm_functionmetadata_type_ptr), closure, globals, scratch,
getConstantInt(defaults.size(), g.i64) });
emitter.setType(boxed, RefType::OWNED);
// The refcounter needs to know that this call "uses" the arguments that got passed via scratch.
......
......@@ -361,7 +361,7 @@ UnboxedSlice extractSlice(CompilerVariable* slice);
#if 0
CompilerVariable* makeUnicode(IREmitter& emitter, llvm::StringRef);
#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);
ConcreteCompilerVariable* undefVariable();
CompilerVariable* makeTuple(const std::vector<CompilerVariable*>& elts);
......
......@@ -290,12 +290,6 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
CFGBlock* block) {
if (isIsDefinedName(name))
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 {
// 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.
......@@ -306,7 +300,7 @@ static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, InternedSt
static bool shouldPhisOwnThisSym(llvm::StringRef name) {
// generating unnecessary increfs to the passed generator would introduce cycles inside the generator
if (name == PASSED_GENERATOR_NAME)
return false;
assert(0);
return true;
}
......@@ -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::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]
llvm::BasicBlock* osr_entry_block = NULL;
......@@ -415,24 +409,25 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
// 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;
for (const auto& p : entry_descriptor->args) {
llvm::Value* from_arg;
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);
llvm::Value* ptr = entry_emitter->getBuilder()->CreateConstGEP1_32(passed_vars, arg_num);
if (p.second == INT) {
ptr = entry_emitter->getBuilder()->CreateBitCast(ptr, g.i64->getPointerTo());
} else if (p.second == BOOL) {
......@@ -451,14 +446,6 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
}
from_arg = entry_emitter->getBuilder()->CreateLoad(ptr);
assert(from_arg->getType() == p.second->llvmType());
}
if (from_arg->getType() == g.llvm_frame_info_type->getPointerTo()) {
assert(p.first.s() == FRAME_INFO_PTR_NAME);
osr_frame_info_arg = from_arg;
// Don't add the frame info to the symbol table since we will store it separately:
continue;
}
ConcreteCompilerType* phi_type;
phi_type = getTypeAtBlockStart(types, p.first, vreg_info, target_block);
......@@ -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) {
// printf("adding guessed phi for %s\n", s.c_str());
ConcreteCompilerType* type = getTypeAtBlockStart(types, s, vreg_info, block);
......@@ -1062,17 +1038,11 @@ CompiledFunction* doCompile(FunctionMetadata* md, SourceInfo* source, ParamNames
llvm_arg_types.push_back(spec->arg_types[i]->llvmType());
}
} else {
int arg_num = -1;
for (const auto& p : entry_descriptor->args) {
arg_num++;
// printf("Loading %s: %s\n", p.first.c_str(), p.second->debugName().c_str());
if (arg_num < 3)
llvm_arg_types.push_back(p.second->llvmType());
else {
// For simplicity, OSR entries always take all possible arguments:
llvm_arg_types.push_back(g.llvm_generator_type_ptr);
llvm_arg_types.push_back(g.llvm_closure_type_ptr);
llvm_arg_types.push_back(g.llvm_frame_info_type->getPointerTo());
llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
break;
}
}
}
CompiledFunction* cf = new CompiledFunction(NULL, spec, NULL, effort, exception_style, entry_descriptor);
......
This diff is collapsed.
......@@ -75,6 +75,9 @@ private:
llvm::Value* globals;
llvm::Value* vregs;
llvm::Value* stmt;
llvm::Value* passed_closure = NULL, * created_closure = NULL, * passed_generator = NULL;
int scratch_size;
public:
......@@ -121,6 +124,14 @@ public:
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.
llvm::Value* getGlobals();
// Returns the custom globals, or null if the globals come from the module.
......
......@@ -517,9 +517,11 @@ private:
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();
rtn->target = target;
rtn->lineno = lineno;
push_back(rtn);
curblock->connectTo(target, allow_backedge);
curblock = nullptr;
......@@ -2264,7 +2266,7 @@ public:
curblock->connectTo(end_false);
curblock = end_true;
pushJump(loop_block, true);
pushJump(loop_block, true, getLastLinenoSub(node->body.back()));
curblock = end_false;
pushJump(else_block);
......
......@@ -316,6 +316,7 @@ class BoxedGenerator;
class ICInfo;
class LocationMap;
class JitCodeBlock;
class FrameInfo;
extern std::vector<Box*> constants;
extern std::vector<Box*> late_constants; // constants that should be freed after normal constants
......@@ -346,6 +347,8 @@ public:
// The function pointer to the generated code. For convenience, it can be accessed
// 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 {
Box* (*call)(Box*, Box*, Box*, Box**);
Box* (*closure_call)(BoxedClosure*, Box*, Box*, Box*, Box**);
......@@ -354,6 +357,7 @@ public:
Box* (*call1)(Box*, Box*, Box*, Box*, Box**);
Box* (*call2)(Box*, Box*, Box*, Box*, Box*, Box**);
Box* (*call3)(Box*, Box*, Box*, Box*, Box*, Box*, Box**);
Box* (*call_osr)(BoxedGenerator*, BoxedClosure*, FrameInfo*, Box**);
void* code;
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