Commit 7e86fc1a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Fix OSR inside closures and generators

Nothing major was wrong, but was trying to double-pass the
generator/closure arguments.
parent 01ae20e9
...@@ -274,6 +274,17 @@ computeBlockTraversalOrder(const BlockSet& full_blocks, const BlockSet& partial_ ...@@ -274,6 +274,17 @@ computeBlockTraversalOrder(const BlockSet& full_blocks, const BlockSet& partial_
return rtn; return rtn;
} }
static ConcreteCompilerType* getTypeAtBlockStart(TypeAnalysis* types, const std::string& name, CFGBlock* block) {
if (startswith(name, "!is_defined"))
return BOOL;
else if (name == PASSED_GENERATOR_NAME)
return GENERATOR;
else if (name == PASSED_CLOSURE_NAME)
return CLOSURE;
else
return types->getTypeAtBlockStart(name, block);
}
static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_guards, const GuardList& in_guards, static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_guards, const GuardList& in_guards,
TypeAnalysis* types, const OSREntryDescriptor* entry_descriptor, const BlockSet& full_blocks, TypeAnalysis* types, const OSREntryDescriptor* entry_descriptor, const BlockSet& full_blocks,
const BlockSet& partial_blocks) { const BlockSet& partial_blocks) {
...@@ -337,6 +348,14 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -337,6 +348,14 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
arg_num++; arg_num++;
if (arg_num < 3) { if (arg_num < 3) {
from_arg = func_args[arg_num]; 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()); assert(from_arg->getType() == p.second->llvmType());
} else { } else {
ASSERT(func_args.size() == 4, "%ld", func_args.size()); ASSERT(func_args.size() == 4, "%ld", func_args.size());
...@@ -355,12 +374,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -355,12 +374,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
} }
ConcreteCompilerType* phi_type; ConcreteCompilerType* phi_type;
if (startswith(p.first, "!is_defined")) phi_type = getTypeAtBlockStart(types, p.first, target_block);
phi_type = BOOL;
else
phi_type = types->getTypeAtBlockStart(p.first, target_block);
// ConcreteCompilerType *analyzed_type = types->getTypeAtBlockStart(p.first, block);
// ConcreteCompilerType *phi_type = (*phis)[p.first].first;
ConcreteCompilerVariable* var = new ConcreteCompilerVariable(p.second, from_arg, true); ConcreteCompilerVariable* var = new ConcreteCompilerVariable(p.second, from_arg, true);
(*initial_syms)[p.first] = var; (*initial_syms)[p.first] = var;
...@@ -579,11 +593,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua ...@@ -579,11 +593,7 @@ static void emitBBs(IRGenState* irstate, const char* bb_type, GuardList& out_gua
assert(phis); assert(phis);
for (const auto& p : entry_descriptor->args) { for (const auto& p : entry_descriptor->args) {
ConcreteCompilerType* analyzed_type; ConcreteCompilerType* analyzed_type = getTypeAtBlockStart(types, p.first, block);
if (startswith(p.first, "!is_defined"))
analyzed_type = BOOL;
else
analyzed_type = types->getTypeAtBlockStart(p.first, block);
// printf("For %s, given %s, analyzed for %s\n", p.first.c_str(), p.second->debugName().c_str(), // printf("For %s, given %s, analyzed for %s\n", p.first.c_str(), p.second->debugName().c_str(),
// analyzed_type->debugName().c_str()); // analyzed_type->debugName().c_str());
...@@ -916,13 +926,13 @@ CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_ ...@@ -916,13 +926,13 @@ CompiledFunction* doCompile(SourceInfo* source, const OSREntryDescriptor* entry_
std::vector<llvm::Type*> llvm_arg_types; std::vector<llvm::Type*> llvm_arg_types;
if (entry_descriptor == NULL) {
if (source->scoping->getScopeInfoForNode(source->ast)->takesClosure()) if (source->scoping->getScopeInfoForNode(source->ast)->takesClosure())
llvm_arg_types.push_back(g.llvm_closure_type_ptr); llvm_arg_types.push_back(g.llvm_closure_type_ptr);
if (source->scoping->getScopeInfoForNode(source->ast)->takesGenerator()) if (source->scoping->getScopeInfoForNode(source->ast)->takesGenerator())
llvm_arg_types.push_back(g.llvm_generator_type_ptr); llvm_arg_types.push_back(g.llvm_generator_type_ptr);
if (entry_descriptor == NULL) {
for (int i = 0; i < nargs; i++) { for (int i = 0; i < nargs; i++) {
if (i == 3) { if (i == 3) {
llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo()); llvm_arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
......
...@@ -197,9 +197,9 @@ static std::vector<const std::string*>* getKeywordNameStorage(AST_Call* node) { ...@@ -197,9 +197,9 @@ static std::vector<const std::string*>* getKeywordNameStorage(AST_Call* node) {
return rtn; return rtn;
} }
static const std::string CREATED_CLOSURE_NAME = "!created_closure"; const std::string CREATED_CLOSURE_NAME = "!created_closure";
static const std::string PASSED_CLOSURE_NAME = "!passed_closure"; const std::string PASSED_CLOSURE_NAME = "!passed_closure";
static const std::string PASSED_GENERATOR_NAME = "!passed_generator"; const std::string PASSED_GENERATOR_NAME = "!passed_generator";
class IRGeneratorImpl : public IRGenerator { class IRGeneratorImpl : public IRGenerator {
private: private:
......
...@@ -41,6 +41,10 @@ typedef std::unordered_map<std::string, CompilerVariable*> SymbolTable; ...@@ -41,6 +41,10 @@ typedef std::unordered_map<std::string, CompilerVariable*> SymbolTable;
typedef std::map<std::string, CompilerVariable*> SortedSymbolTable; typedef std::map<std::string, CompilerVariable*> SortedSymbolTable;
typedef std::unordered_map<std::string, ConcreteCompilerVariable*> ConcreteSymbolTable; typedef std::unordered_map<std::string, ConcreteCompilerVariable*> ConcreteSymbolTable;
extern const std::string CREATED_CLOSURE_NAME;
extern const std::string PASSED_CLOSURE_NAME;
extern const std::string PASSED_GENERATOR_NAME;
// Class that holds state of the current IR generation, that might not be local // Class that holds state of the current IR generation, that might not be local
// to the specific phase or pass we're in. // to the specific phase or pass we're in.
// TODO this probably shouldn't be here // TODO this probably shouldn't be here
......
...@@ -40,6 +40,8 @@ namespace gc { ...@@ -40,6 +40,8 @@ namespace gc {
void collectRoots(void* start, void* end, TraceStack* stack) { void collectRoots(void* start, void* end, TraceStack* stack) {
assert(start <= end); assert(start <= end);
ASSERT((char*)end - (char*)start <= 1000000000, "Asked to scan %.1fGB -- a bug?",
((char*)end - (char*)start) * 1.0 / (1 << 30));
TraceStackGCVisitor(stack).visitPotentialRange((void**)start, (void**)end); TraceStackGCVisitor(stack).visitPotentialRange((void**)start, (void**)end);
} }
......
# This test could really benefit from defined/settable OSR limits
def f(x):
def inner():
t = 0
for i in xrange(20000):
t += x
return t
return inner
f = f(5)
print f()
# This test could really benefit from defined/settable OSR limits
def f(x):
for i in xrange(20000):
pass
yield x
print list(f(5))
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