Commit 49502e91 authored by Marius Wachtler's avatar Marius Wachtler

move ScopeInfo ownership to SourceInfo

parent 0971100d
...@@ -903,13 +903,13 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) { ...@@ -903,13 +903,13 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) {
ScopeNameUsage* usage = sorted_usages[i]; ScopeNameUsage* usage = sorted_usages[i];
AST* node = usage->node; AST* node = usage->node;
ScopeInfo* parent_info = this->scopes[(usage->parent == NULL) ? this->parent_module : usage->parent->node]; ScopeInfo* parent_info
= this->scopes[(usage->parent == NULL) ? this->parent_module : usage->parent->node].get();
switch (node->type) { switch (node->type) {
case AST_TYPE::ClassDef: { case AST_TYPE::ClassDef: {
ScopeInfoBase* scopeInfo = new ScopeInfoBase(parent_info, usage, usage->node, true /* usesNameLookup */, this->scopes[node] = llvm::make_unique<ScopeInfoBase>(parent_info, usage, usage->node,
globals_from_module); true /* usesNameLookup */, globals_from_module);
this->scopes[node] = scopeInfo;
break; break;
} }
case AST_TYPE::FunctionDef: case AST_TYPE::FunctionDef:
...@@ -917,10 +917,9 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) { ...@@ -917,10 +917,9 @@ void ScopingAnalysis::processNameUsages(ScopingAnalysis::NameUsageMap* usages) {
case AST_TYPE::GeneratorExp: case AST_TYPE::GeneratorExp:
case AST_TYPE::DictComp: case AST_TYPE::DictComp:
case AST_TYPE::SetComp: { case AST_TYPE::SetComp: {
ScopeInfoBase* scopeInfo this->scopes[node] = llvm::make_unique<ScopeInfoBase>(
= new ScopeInfoBase(parent_info, usage, usage->node, parent_info, usage, usage->node, usage->hasNameForcingSyntax() /* usesNameLookup */,
usage->hasNameForcingSyntax() /* usesNameLookup */, globals_from_module); globals_from_module);
this->scopes[node] = scopeInfo;
break; break;
} }
default: default:
...@@ -934,14 +933,15 @@ InternedStringPool& ScopingAnalysis::getInternedStrings() { ...@@ -934,14 +933,15 @@ InternedStringPool& ScopingAnalysis::getInternedStrings() {
return *interned_strings; return *interned_strings;
} }
ScopeInfo* ScopingAnalysis::analyzeSubtree(AST* node) { std::unique_ptr<ScopeInfo> ScopingAnalysis::analyzeSubtree(AST* node) {
NameUsageMap usages; NameUsageMap usages;
usages[node] = new ScopeNameUsage(node, NULL, this); usages[node] = new ScopeNameUsage(node, NULL, this);
NameCollectorVisitor::collect(node, &usages, this); NameCollectorVisitor::collect(node, &usages, this);
processNameUsages(&usages); processNameUsages(&usages);
ScopeInfo* rtn = scopes[node]; std::unique_ptr<ScopeInfo> rtn = std::move(scopes[node]);
// scopes.erase(node);
assert(rtn); assert(rtn);
return rtn; return rtn;
} }
...@@ -959,17 +959,17 @@ void ScopingAnalysis::registerScopeReplacement(AST* original_node, AST* new_node ...@@ -959,17 +959,17 @@ void ScopingAnalysis::registerScopeReplacement(AST* original_node, AST* new_node
scope_replacements[new_node] = original_node; scope_replacements[new_node] = original_node;
} }
ScopeInfo* ScopingAnalysis::getScopeInfoForNode(AST* node) { std::unique_ptr<ScopeInfo> ScopingAnalysis::getScopeInfoForNode(AST* node) {
assert(node); assert(node);
auto it = scope_replacements.find(node); auto it = scope_replacements.find(node);
if (it != scope_replacements.end()) if (it != scope_replacements.end())
node = it->second; node = it->second;
auto rtn = scopes.find(node); if (scopes.count(node)) {
if (rtn != scopes.end()) { std::unique_ptr<ScopeInfo> rtn = std::move(scopes[node]);
assert(rtn->second); assert(rtn);
return rtn->second; return rtn;
} }
return analyzeSubtree(node); return analyzeSubtree(node);
...@@ -993,10 +993,10 @@ ScopingAnalysis::ScopingAnalysis(AST* ast, bool globals_from_module) ...@@ -993,10 +993,10 @@ ScopingAnalysis::ScopingAnalysis(AST* ast, bool globals_from_module)
if (globals_from_module) { if (globals_from_module) {
assert(ast->type == AST_TYPE::Module); assert(ast->type == AST_TYPE::Module);
scopes[ast] = new ModuleScopeInfo(); scopes[ast] = llvm::make_unique<ModuleScopeInfo>();
parent_module = static_cast<AST_Module*>(ast); parent_module = static_cast<AST_Module*>(ast);
} else { } else {
scopes[ast] = new EvalExprScopeInfo(ast, globals_from_module); scopes[ast] = llvm::make_unique<EvalExprScopeInfo>(ast, globals_from_module);
} }
} }
} }
...@@ -151,13 +151,13 @@ public: ...@@ -151,13 +151,13 @@ public:
typedef llvm::DenseMap<AST*, ScopeNameUsage*> NameUsageMap; typedef llvm::DenseMap<AST*, ScopeNameUsage*> NameUsageMap;
private: private:
llvm::DenseMap<AST*, ScopeInfo*> scopes; llvm::DenseMap<AST*, std::unique_ptr<ScopeInfo>> scopes;
AST_Module* parent_module; AST_Module* parent_module;
InternedStringPool* interned_strings; InternedStringPool* interned_strings;
llvm::DenseMap<AST*, AST*> scope_replacements; llvm::DenseMap<AST*, AST*> scope_replacements;
ScopeInfo* analyzeSubtree(AST* node); std::unique_ptr<ScopeInfo> analyzeSubtree(AST* node);
void processNameUsages(NameUsageMap* usages); void processNameUsages(NameUsageMap* usages);
bool globals_from_module; bool globals_from_module;
...@@ -173,7 +173,7 @@ public: ...@@ -173,7 +173,7 @@ public:
void registerScopeReplacement(AST* original_node, AST* new_node); void registerScopeReplacement(AST* original_node, AST* new_node);
ScopingAnalysis(AST* ast, bool globals_from_module); ScopingAnalysis(AST* ast, bool globals_from_module);
ScopeInfo* getScopeInfoForNode(AST* node); std::unique_ptr<ScopeInfo> getScopeInfoForNode(AST* node);
InternedStringPool& getInternedStrings(); InternedStringPool& getInternedStrings();
bool areGlobalsFromModule() { return globals_from_module; } bool areGlobalsFromModule() { return globals_from_module; }
......
...@@ -1159,19 +1159,7 @@ Value ASTInterpreter::createFunction(AST* node, AST_arguments* args) { ...@@ -1159,19 +1159,7 @@ Value ASTInterpreter::createFunction(AST* node, AST_arguments* args) {
u.d.ptr = &defaults[0]; u.d.ptr = &defaults[0];
u.d.s = defaults.size() - 1; u.d.s = defaults.size() - 1;
bool takes_closure; bool takes_closure = md->source->getScopeInfo()->takesClosure();
source_info->scoping->getScopeInfoForNode(node);
// Optimization: when compiling a module, it's nice to not have to run analyses into the
// entire module's source code.
// If we call getScopeInfoForNode, that will trigger an analysis of that function tree,
// but we're only using it here to figure out if that function takes a closure.
// Top level functions never take a closure, so we can skip the analysis.
if (source_info->ast->type == AST_TYPE::Module)
takes_closure = false;
else {
takes_closure = source_info->scoping->getScopeInfoForNode(node)->takesClosure();
}
BoxedClosure* closure = 0; BoxedClosure* closure = 0;
RewriterVar* closure_var = NULL; RewriterVar* closure_var = NULL;
...@@ -1238,8 +1226,7 @@ Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) { ...@@ -1238,8 +1226,7 @@ Value ASTInterpreter::visit_makeFunction(AST_MakeFunction* mkfn) {
Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) { Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
abortJITing(); abortJITing();
AST_ClassDef* node = mkclass->class_def; AST_ClassDef* node = mkclass->class_def;
ScopeInfo* scope_info = source_info->scoping->getScopeInfoForNode(node);
assert(scope_info);
BoxedTuple* basesTuple = BoxedTuple::create(node->bases.size()); BoxedTuple* basesTuple = BoxedTuple::create(node->bases.size());
AUTO_DECREF(basesTuple); AUTO_DECREF(basesTuple);
...@@ -1253,6 +1240,11 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) { ...@@ -1253,6 +1240,11 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
for (AST_expr* d : node->decorator_list) for (AST_expr* d : node->decorator_list)
decorators.push_back(visit_expr(d).o); decorators.push_back(visit_expr(d).o);
FunctionMetadata* md = wrapFunction(node, nullptr, source_info);
ScopeInfo* scope_info = md->source->getScopeInfo();
assert(scope_info);
BoxedClosure* closure = NULL; BoxedClosure* closure = NULL;
if (scope_info->takesClosure()) { if (scope_info->takesClosure()) {
if (this->scope_info->passesThroughClosure()) if (this->scope_info->passesThroughClosure())
...@@ -1261,7 +1253,6 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) { ...@@ -1261,7 +1253,6 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
closure = created_closure; closure = created_closure;
assert(closure); assert(closure);
} }
FunctionMetadata* md = wrapFunction(node, nullptr, source_info);
Box* passed_globals = NULL; Box* passed_globals = NULL;
if (!getMD()->source->scoping->areGlobalsFromModule()) if (!getMD()->source->scoping->areGlobalsFromModule())
......
...@@ -92,7 +92,12 @@ void FunctionMetadata::addVersion(CompiledFunction* compiled) { ...@@ -92,7 +92,12 @@ void FunctionMetadata::addVersion(CompiledFunction* compiled) {
} }
SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags future_flags, AST* ast, BoxedString* fn) SourceInfo::SourceInfo(BoxedModule* m, ScopingAnalysis* scoping, FutureFlags future_flags, AST* ast, BoxedString* fn)
: parent_module(m), scoping(scoping), scope_info(NULL), ast(ast), cfg(NULL), future_flags(future_flags) { : parent_module(m),
scoping(scoping),
scope_info(scoping->getScopeInfoForNode(ast)),
ast(ast),
cfg(NULL),
future_flags(future_flags) {
assert(fn); assert(fn);
// TODO: this is a very bad way of handling this: // TODO: this is a very bad way of handling this:
......
...@@ -183,9 +183,8 @@ Box* SourceInfo::getDocString() { ...@@ -183,9 +183,8 @@ Box* SourceInfo::getDocString() {
} }
ScopeInfo* SourceInfo::getScopeInfo() { ScopeInfo* SourceInfo::getScopeInfo() {
if (!scope_info) assert(scope_info);
scope_info = scoping->getScopeInfoForNode(ast); return scope_info.get();
return scope_info;
} }
LivenessAnalysis* SourceInfo::getLiveness() { LivenessAnalysis* SourceInfo::getLiveness() {
......
...@@ -375,11 +375,6 @@ ScopeInfo* IRGenState::getScopeInfo() { ...@@ -375,11 +375,6 @@ ScopeInfo* IRGenState::getScopeInfo() {
return getSourceInfo()->getScopeInfo(); return getSourceInfo()->getScopeInfo();
} }
ScopeInfo* IRGenState::getScopeInfoForNode(AST* node) {
auto source = getSourceInfo();
return source->scoping->getScopeInfoForNode(node);
}
llvm::Value* IRGenState::getGlobals() { llvm::Value* IRGenState::getGlobals() {
assert(globals); assert(globals);
return globals; return globals;
...@@ -1576,8 +1571,7 @@ private: ...@@ -1576,8 +1571,7 @@ private:
CompilerVariable* evalMakeClass(AST_MakeClass* mkclass, const UnwindInfo& unw_info) { CompilerVariable* evalMakeClass(AST_MakeClass* mkclass, const UnwindInfo& unw_info) {
assert(mkclass->type == AST_TYPE::MakeClass && mkclass->class_def->type == AST_TYPE::ClassDef); assert(mkclass->type == AST_TYPE::MakeClass && mkclass->class_def->type == AST_TYPE::ClassDef);
AST_ClassDef* node = mkclass->class_def; AST_ClassDef* node = mkclass->class_def;
ScopeInfo* scope_info = irstate->getScopeInfoForNode(node);
assert(scope_info);
std::vector<CompilerVariable*> bases; std::vector<CompilerVariable*> bases;
for (auto b : node->bases) { for (auto b : node->bases) {
...@@ -1594,6 +1588,8 @@ private: ...@@ -1594,6 +1588,8 @@ private:
} }
FunctionMetadata* md = wrapFunction(node, nullptr, irstate->getSourceInfo()); FunctionMetadata* md = wrapFunction(node, nullptr, irstate->getSourceInfo());
ScopeInfo* scope_info = md->source->getScopeInfo();
assert(scope_info);
// TODO duplication with _createFunction: // TODO duplication with _createFunction:
llvm::Value* this_closure = NULL; llvm::Value* this_closure = NULL;
...@@ -1644,19 +1640,7 @@ private: ...@@ -1644,19 +1640,7 @@ private:
defaults.push_back(converted); defaults.push_back(converted);
} }
bool takes_closure; bool takes_closure = md->source->scope_info->takesClosure();
// Optimization: when compiling a module, it's nice to not have to run analyses into the
// entire module's source code.
// If we call getScopeInfoForNode, that will trigger an analysis of that function tree,
// but we're only using it here to figure out if that function takes a closure.
// Top level functions never take a closure, so we can skip the analysis.
if (irstate->getSourceInfo()->ast->type == AST_TYPE::Module)
takes_closure = false;
else {
takes_closure = irstate->getScopeInfoForNode(node)->takesClosure();
}
bool is_generator = md->source->is_generator;
llvm::Value* this_closure = NULL; llvm::Value* this_closure = NULL;
if (takes_closure) { if (takes_closure) {
......
...@@ -119,7 +119,6 @@ public: ...@@ -119,7 +119,6 @@ public:
PhiAnalysis* getPhis() { return phis.get(); } PhiAnalysis* getPhis() { return phis.get(); }
ScopeInfo* getScopeInfo(); ScopeInfo* getScopeInfo();
ScopeInfo* getScopeInfoForNode(AST* node);
llvm::MDNode* getFuncDbgInfo() { return func_dbg_info; } llvm::MDNode* getFuncDbgInfo() { return func_dbg_info; }
......
...@@ -443,7 +443,7 @@ private: ...@@ -443,7 +443,7 @@ private:
public: public:
BoxedModule* parent_module; BoxedModule* parent_module;
ScopingAnalysis* scoping; ScopingAnalysis* scoping;
ScopeInfo* scope_info; std::unique_ptr<ScopeInfo> scope_info;
AST* ast; AST* ast;
CFG* cfg; CFG* cfg;
FutureFlags future_flags; FutureFlags future_flags;
......
...@@ -36,14 +36,14 @@ TEST_F(AnalysisTest, augassign) { ...@@ -36,14 +36,14 @@ TEST_F(AnalysisTest, augassign) {
assert(module->body[0]->type == AST_TYPE::FunctionDef); assert(module->body[0]->type == AST_TYPE::FunctionDef);
AST_FunctionDef* func = static_cast<AST_FunctionDef*>(module->body[0]); AST_FunctionDef* func = static_cast<AST_FunctionDef*>(module->body[0]);
ScopeInfo* scope_info = scoping->getScopeInfoForNode(func);
ASSERT_FALSE(scope_info->getScopeTypeOfName(module->interned_strings->get("a")) == ScopeInfo::VarScopeType::GLOBAL);
ASSERT_FALSE(scope_info->getScopeTypeOfName(module->interned_strings->get("b")) == ScopeInfo::VarScopeType::GLOBAL);
FutureFlags future_flags = getFutureFlags(module->body, fn.c_str()); FutureFlags future_flags = getFutureFlags(module->body, fn.c_str());
SourceInfo* si = new SourceInfo(createModule(boxString("augassign"), fn.c_str()), scoping, future_flags, func, boxString(fn)); SourceInfo* si = new SourceInfo(createModule(boxString("augassign"), fn.c_str()), scoping, future_flags, func, boxString(fn));
ScopeInfo* scope_info = si->getScopeInfo();
ASSERT_FALSE(scope_info->getScopeTypeOfName(module->interned_strings->get("a")) == ScopeInfo::VarScopeType::GLOBAL);
ASSERT_FALSE(scope_info->getScopeTypeOfName(module->interned_strings->get("b")) == ScopeInfo::VarScopeType::GLOBAL);
ParamNames param_names(si->ast, si->getInternedStrings()); ParamNames param_names(si->ast, si->getInternedStrings());
CFG* cfg = computeCFG(si, param_names); CFG* cfg = computeCFG(si, param_names);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg); std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg);
...@@ -72,9 +72,9 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) { ...@@ -72,9 +72,9 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) {
FutureFlags future_flags = getFutureFlags(module->body, fn.c_str()); FutureFlags future_flags = getFutureFlags(module->body, fn.c_str());
ScopeInfo* scope_info = scoping->getScopeInfoForNode(func);
std::unique_ptr<SourceInfo> si(new SourceInfo(createModule(boxString("osr" + std::to_string((is_osr << 1) + i_maybe_undefined)), std::unique_ptr<SourceInfo> si(new SourceInfo(createModule(boxString("osr" + std::to_string((is_osr << 1) + i_maybe_undefined)),
fn.c_str()), scoping, future_flags, func, boxString(fn))); fn.c_str()), scoping, future_flags, func, boxString(fn)));
ScopeInfo* scope_info = si->getScopeInfo();
FunctionMetadata* clfunc = new FunctionMetadata(0, false, false, std::move(si)); FunctionMetadata* clfunc = new FunctionMetadata(0, false, false, std::move(si));
CFG* cfg = computeCFG(clfunc->source.get(), clfunc->param_names); CFG* cfg = computeCFG(clfunc->source.get(), clfunc->param_names);
......
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