Commit 00bb5d2f authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by GitHub

Merge pull request #1384 from undingen/bst_preparation_for_gapless

BST: remove some of the remaining pointers, earlier boxed code destruction
parents 106533f9 ae58d063
......@@ -32,7 +32,9 @@ template <typename T> class BBAnalyzer {
public:
typedef VRegMap<T> Map;
typedef llvm::DenseMap<CFGBlock*, Map> AllMap;
const CodeConstants& code_constants;
BBAnalyzer(const CodeConstants& code_constants) : code_constants(code_constants) {}
virtual ~BBAnalyzer() {}
virtual T merge(T from, T into) const = 0;
......
......@@ -70,7 +70,7 @@ private:
public:
LivenessBBVisitor(LivenessAnalysis* analysis)
: NoopBSTVisitor(true /* skip child CFG nodes */),
: NoopBSTVisitor(analysis->code_constants),
statuses(analysis->cfg->getVRegInfo().getTotalNumOfVRegs()),
analysis(analysis) {}
......@@ -96,7 +96,8 @@ public:
}
};
LivenessAnalysis::LivenessAnalysis(CFG* cfg) : cfg(cfg), result_cache(cfg->getVRegInfo().getTotalNumOfVRegs()) {
LivenessAnalysis::LivenessAnalysis(CFG* cfg, const CodeConstants& code_constants)
: cfg(cfg), code_constants(code_constants), result_cache(cfg->getVRegInfo().getTotalNumOfVRegs()) {
Timer _t("LivenessAnalysis()", 100);
for (CFGBlock* b : cfg->blocks) {
......@@ -182,7 +183,8 @@ private:
typedef DefinednessAnalysis::DefinitionLevel DefinitionLevel;
public:
DefinednessBBAnalyzer() {}
DefinednessBBAnalyzer(const CodeConstants& code_constants)
: BBAnalyzer<DefinednessAnalysis::DefinitionLevel>(code_constants) {}
virtual DefinitionLevel merge(DefinitionLevel from, DefinitionLevel into) const {
assert(from != DefinitionLevel::Unknown);
......@@ -212,7 +214,8 @@ private:
}
public:
DefinednessVisitor(Map& state) : NoopBSTVisitor(true /* skip child CFG nodes */), state(state) {}
DefinednessVisitor(const CodeConstants& code_constants, Map& state)
: NoopBSTVisitor(code_constants), state(state) {}
bool visit_vreg(int* vreg, bool is_dest) override {
if (*vreg < 0)
return false;
......@@ -252,7 +255,7 @@ public:
};
void DefinednessBBAnalyzer::processBB(Map& starting, CFGBlock* block) const {
DefinednessVisitor visitor(starting);
DefinednessVisitor visitor(code_constants, starting);
for (int i = 0; i < block->body.size(); i++) {
block->body[i]->accept(&visitor);
......@@ -267,7 +270,8 @@ void DefinednessBBAnalyzer::processBB(Map& starting, CFGBlock* block) const {
}
}
void DefinednessAnalysis::run(VRegMap<DefinednessAnalysis::DefinitionLevel> initial_map, CFGBlock* initial_block) {
void DefinednessAnalysis::run(const CodeConstants& code_constants,
VRegMap<DefinednessAnalysis::DefinitionLevel> initial_map, CFGBlock* initial_block) {
Timer _t("DefinednessAnalysis()", 10);
// Don't run this twice:
......@@ -278,8 +282,8 @@ void DefinednessAnalysis::run(VRegMap<DefinednessAnalysis::DefinitionLevel> init
assert(initial_map.numVregs() == nvregs);
auto&& vreg_info = cfg->getVRegInfo();
computeFixedPoint(std::move(initial_map), initial_block, DefinednessBBAnalyzer(), false, defined_at_beginning,
defined_at_end);
computeFixedPoint(std::move(initial_map), initial_block, DefinednessBBAnalyzer(code_constants), false,
defined_at_beginning, defined_at_end);
for (const auto& p : defined_at_end) {
assert(p.second.numVregs() == nvregs);
......@@ -327,7 +331,7 @@ PhiAnalysis::PhiAnalysis(VRegMap<DefinednessAnalysis::DefinitionLevel> initial_m
int num_vregs = initial_map.numVregs();
assert(num_vregs == vreg_info.getTotalNumOfVRegs());
definedness.run(std::move(initial_map), initial_block);
definedness.run(liveness->getCodeConstants(), std::move(initial_map), initial_block);
Timer _t("PhiAnalysis()", 10);
......@@ -415,11 +419,11 @@ bool PhiAnalysis::isPotentiallyUndefinedAt(int vreg, CFGBlock* block) {
return definedness.defined_at_beginning.find(block)->second[vreg] != DefinednessAnalysis::Defined;
}
std::unique_ptr<LivenessAnalysis> computeLivenessInfo(CFG* cfg) {
std::unique_ptr<LivenessAnalysis> computeLivenessInfo(CFG* cfg, const CodeConstants& code_constants) {
static StatCounter counter("num_liveness_analysis");
counter.log();
return std::unique_ptr<LivenessAnalysis>(new LivenessAnalysis(cfg));
return std::unique_ptr<LivenessAnalysis>(new LivenessAnalysis(cfg, code_constants));
}
std::unique_ptr<PhiAnalysis> computeRequiredPhis(const ParamNames& args, CFG* cfg, LivenessAnalysis* liveness) {
......
......@@ -34,6 +34,7 @@ class LivenessBBVisitor;
class LivenessAnalysis {
private:
CFG* cfg;
const CodeConstants& code_constants;
friend class LivenessBBVisitor;
typedef llvm::DenseMap<CFGBlock*, std::unique_ptr<LivenessBBVisitor>> LivenessCacheMap;
......@@ -42,10 +43,11 @@ private:
VRegMap<llvm::DenseMap<CFGBlock*, bool>> result_cache;
public:
LivenessAnalysis(CFG* cfg);
LivenessAnalysis(CFG* cfg, const CodeConstants& code_constants);
~LivenessAnalysis();
bool isLiveAtEnd(int vreg, CFGBlock* block);
const CodeConstants& getCodeConstants() const { return code_constants; }
};
class PhiAnalysis;
......@@ -66,7 +68,7 @@ private:
public:
DefinednessAnalysis() {}
void run(VRegMap<DefinitionLevel> initial_map, CFGBlock* initial_block);
void run(const CodeConstants& code_constants, VRegMap<DefinitionLevel> initial_map, CFGBlock* initial_block);
DefinitionLevel isDefinedAtEnd(int vreg, CFGBlock* block);
const VRegSet& getDefinedVregsAtEnd(CFGBlock* block);
......@@ -100,7 +102,7 @@ public:
bool isPotentiallyUndefinedAt(int vreg, CFGBlock* block);
};
std::unique_ptr<LivenessAnalysis> computeLivenessInfo(CFG*);
std::unique_ptr<LivenessAnalysis> computeLivenessInfo(CFG*, const CodeConstants&);
std::unique_ptr<PhiAnalysis> computeRequiredPhis(const ParamNames&, CFG*, LivenessAnalysis*);
std::unique_ptr<PhiAnalysis> computeRequiredPhis(const OSREntryDescriptor*, LivenessAnalysis*);
}
......
......@@ -89,17 +89,16 @@ private:
ExprTypeMap& expr_types;
TypeSpeculations& type_speculations;
TypeAnalysis::SpeculationLevel speculation;
const CodeConstants& code_constants;
BasicBlockTypePropagator(CFGBlock* block, TypeMap& initial, ExprTypeMap& expr_types,
TypeSpeculations& type_speculations, TypeAnalysis::SpeculationLevel speculation,
const CodeConstants& code_constants)
: block(block),
: StmtVisitor(code_constants),
block(block),
sym_table(initial),
expr_types(expr_types),
type_speculations(type_speculations),
speculation(speculation),
code_constants(code_constants) {}
speculation(speculation) {}
void run() {
for (int i = 0; i < block->body.size(); i++) {
......@@ -280,10 +279,11 @@ private:
void visit_callattr(BST_CallAttr* node) override {
CompilerType* t = getType(node->vreg_value);
CompilerType* func = t->getattrType(node->attr, false);
InternedString attr = getCodeConstants().getInternedString(node->index_attr);
CompilerType* func = t->getattrType(attr, false);
if (VERBOSITY() >= 2 && func == UNDEF) {
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno);
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), attr.c_str(), node->lineno);
print_bst(node, code_constants);
printf("\n");
}
......@@ -293,10 +293,11 @@ private:
void visit_callclsattr(BST_CallClsAttr* node) override {
CompilerType* t = getType(node->vreg_value);
CompilerType* func = t->getattrType(node->attr, true);
InternedString attr = getCodeConstants().getInternedString(node->index_attr);
CompilerType* func = t->getattrType(attr, true);
if (VERBOSITY() >= 2 && func == UNDEF) {
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno);
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), attr.c_str(), node->lineno);
print_bst(node, code_constants);
printf("\n");
}
......@@ -380,7 +381,8 @@ private:
auto name_scope = node->lookup_type;
if (name_scope == ScopeInfo::VarScopeType::GLOBAL) {
if (node->id.s() == "None")
InternedString id = getCodeConstants().getInternedString(node->index_id);
if (id.s() == "None")
t = NONE;
} else if (name_scope == ScopeInfo::VarScopeType::FAST || name_scope == ScopeInfo::VarScopeType::CLOSURE)
t = getType(node->vreg);
......@@ -390,7 +392,8 @@ private:
void visit_loadattr(BST_LoadAttr* node) override {
CompilerType* t = getType(node->vreg_value);
CompilerType* rtn = t->getattrType(node->attr, node->clsonly);
InternedString attr = getCodeConstants().getInternedString(node->index_attr);
CompilerType* rtn = t->getattrType(attr, node->clsonly);
if (speculation != TypeAnalysis::NONE) {
BoxedClass* speculated_class = predictClassFor(node);
......@@ -398,7 +401,7 @@ private:
}
if (VERBOSITY() >= 2 && rtn == UNDEF) {
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), node->attr.c_str(), node->lineno);
printf("Think %s.%s is undefined, at %d\n", t->debugName().c_str(), attr.c_str(), node->lineno);
print_bst(node, code_constants);
printf("\n");
}
......@@ -479,7 +482,7 @@ private:
}
void visit_makeclass(BST_MakeClass* mkclass) override {
BST_ClassDef* node = mkclass->class_def;
auto* node = bst_cast<BST_ClassDef>(getCodeConstants().getFuncOrClass(mkclass->index_class_def).first);
for (int i = 0; i < node->num_decorator; ++i) {
getType(node->decorator[i]);
......@@ -505,7 +508,7 @@ private:
}
void visit_makefunction(BST_MakeFunction* mkfn) override {
BST_FunctionDef* node = mkfn->function_def;
auto* node = bst_cast<BST_FunctionDef>(getCodeConstants().getFuncOrClass(mkfn->index_func_def).first);
for (int i = 0; i < node->num_defaults + node->num_decorator; ++i) {
getType(node->elts[i]);
......
This diff is collapsed.
......@@ -222,7 +222,7 @@ RewriterVar* JitFragmentWriter::imm(uint64_t val) {
return loadConst(val);
}
RewriterVar* JitFragmentWriter::imm(void* val) {
RewriterVar* JitFragmentWriter::imm(const void* val) {
return loadConst((uint64_t)val);
}
......@@ -246,7 +246,7 @@ RewriterVar* JitFragmentWriter::emitBinop(BST_stmt* node, RewriterVar* lhs, Rewr
RewriterVar* JitFragmentWriter::emitCallattr(BST_stmt* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
const llvm::ArrayRef<RewriterVar*> args,
std::vector<BoxedString*>* keyword_names) {
const std::vector<BoxedString*>* keyword_names) {
#if ENABLE_BASELINEJIT_ICS
RewriterVar* attr_var = imm(attr);
RewriterVar* flags_var = imm(flags.asInt());
......@@ -520,7 +520,7 @@ RewriterVar* JitFragmentWriter::emitRepr(RewriterVar* v) {
RewriterVar* JitFragmentWriter::emitRuntimeCall(BST_stmt* node, RewriterVar* obj, ArgPassSpec argspec,
const llvm::ArrayRef<RewriterVar*> args,
std::vector<BoxedString*>* keyword_names) {
const std::vector<BoxedString*>* keyword_names) {
#if ENABLE_BASELINEJIT_ICS
RewriterVar* argspec_var = imm(argspec.asInt());
RewriterVar::SmallVector call_args;
......@@ -1001,7 +1001,7 @@ void JitFragmentWriter::assertNameDefinedHelper(const char* id) {
}
Box* JitFragmentWriter::callattrHelper(Box* obj, BoxedString* attr, CallattrFlags flags, Box** args,
std::vector<BoxedString*>* keyword_names) {
const std::vector<BoxedString*>* keyword_names) {
auto arg_tuple = getTupleFromArgsArray(&args[0], flags.argspec.totalPassed());
Box* r = callattr(obj, attr, flags, std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple),
std::get<3>(arg_tuple), keyword_names);
......@@ -1060,7 +1060,7 @@ BORROWED(Box*) JitFragmentWriter::notHelper(Box* b) {
}
Box* JitFragmentWriter::runtimeCallHelper(Box* obj, ArgPassSpec argspec, Box** args,
std::vector<BoxedString*>* keyword_names) {
const std::vector<BoxedString*>* keyword_names) {
auto arg_tuple = getTupleFromArgsArray(&args[0], argspec.totalPassed());
Box* r = runtimeCall(obj, argspec, std::get<0>(arg_tuple), std::get<1>(arg_tuple), std::get<2>(arg_tuple),
std::get<3>(arg_tuple), keyword_names);
......
......@@ -264,13 +264,13 @@ public:
RewriterVar* getInterp();
RewriterVar* imm(uint64_t val);
RewriterVar* imm(void* val);
RewriterVar* imm(const void* val);
RewriterVar* emitAugbinop(BST_stmt* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitApplySlice(RewriterVar* target, RewriterVar* lower, RewriterVar* upper);
RewriterVar* emitBinop(BST_stmt* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCallattr(BST_stmt* node, RewriterVar* obj, BoxedString* attr, CallattrFlags flags,
const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names);
const llvm::ArrayRef<RewriterVar*> args, const std::vector<BoxedString*>* keyword_names);
RewriterVar* emitCompare(BST_stmt* node, RewriterVar* lhs, RewriterVar* rhs, int op_type);
RewriterVar* emitCreateDict();
void emitDictSet(RewriterVar* dict, RewriterVar* k, RewriterVar* v);
......@@ -301,7 +301,8 @@ public:
RewriterVar* emitNotNonzero(RewriterVar* v);
RewriterVar* emitRepr(RewriterVar* v);
RewriterVar* emitRuntimeCall(BST_stmt* node, RewriterVar* obj, ArgPassSpec argspec,
const llvm::ArrayRef<RewriterVar*> args, std::vector<BoxedString*>* keyword_names);
const llvm::ArrayRef<RewriterVar*> args,
const std::vector<BoxedString*>* keyword_names);
RewriterVar* emitUnaryop(RewriterVar* v, int op_type);
std::vector<RewriterVar*> emitUnpackIntoArray(RewriterVar* v, uint64_t num);
RewriterVar* emitYield(RewriterVar* v);
......@@ -359,7 +360,7 @@ private:
static void assertNameDefinedHelper(const char* id);
static Box* callattrHelper(Box* obj, BoxedString* attr, CallattrFlags flags, Box** args,
std::vector<BoxedString*>* keyword_names);
const std::vector<BoxedString*>* keyword_names);
static Box* createDictHelper(uint64_t num, Box** keys, Box** values);
static Box* createListHelper(uint64_t num, Box** data);
static Box* createSetHelper(uint64_t num, Box** data);
......@@ -368,7 +369,8 @@ private:
static BORROWED(Box*) hasnextHelper(Box* b);
static BORROWED(Box*) nonzeroHelper(Box* b);
static BORROWED(Box*) notHelper(Box* b);
static Box* runtimeCallHelper(Box* obj, ArgPassSpec argspec, Box** args, std::vector<BoxedString*>* keyword_names);
static Box* runtimeCallHelper(Box* obj, ArgPassSpec argspec, Box** args,
const std::vector<BoxedString*>* keyword_names);
void _emitGetLocal(RewriterVar* val_var, const char* name);
void _emitJump(CFGBlock* b, RewriterVar* block_next, ExitInfo& exit_info);
......
......@@ -344,8 +344,8 @@ private:
SymbolTable* sym_table;
bool created_new_sym_table;
SymTableDstVRegDeleter(SymbolTable* sym_table)
: NoopBSTVisitor(true /* skip child CFG nodes */), sym_table(sym_table), created_new_sym_table(false) {}
SymTableDstVRegDeleter(const CodeConstants& code_constants, SymbolTable* sym_table)
: NoopBSTVisitor(code_constants), sym_table(sym_table), created_new_sym_table(false) {}
protected:
bool visit_vreg(int* vreg, bool is_dst = false) override {
......@@ -361,9 +361,9 @@ protected:
}
public:
static std::pair<SymbolTable*, bool /* created_new_sym_table */> removeDestVRegsFromSymTable(SymbolTable* sym_table,
BST_Invoke* stmt) {
SymTableDstVRegDeleter visitor(sym_table);
static std::pair<SymbolTable*, bool /* created_new_sym_table */>
removeDestVRegsFromSymTable(const CodeConstants& code_constants, SymbolTable* sym_table, BST_Invoke* stmt) {
SymTableDstVRegDeleter visitor(code_constants, sym_table);
stmt->accept(&visitor);
return std::make_pair(visitor.sym_table, visitor.created_new_sym_table);
}
......@@ -739,7 +739,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
bool created_new_sym_table = false;
if (last_inst->type == BST_TYPE::Invoke && bst_cast<BST_Invoke>(last_inst)->exc_dest == block)
std::tie(sym_table, created_new_sym_table) = SymTableDstVRegDeleter::removeDestVRegsFromSymTable(
sym_table, bst_cast<BST_Invoke>(last_inst));
irstate->getCodeConstants(), sym_table, bst_cast<BST_Invoke>(last_inst));
generator->copySymbolsFrom(sym_table);
for (auto&& p : *definedness_tables[pred]) {
......@@ -1119,7 +1119,7 @@ std::pair<CompiledFunction*, llvm::Function*> doCompile(BoxedCode* code, SourceI
computeBlockSetClosure(blocks);
}
LivenessAnalysis* liveness = source->getLiveness();
LivenessAnalysis* liveness = source->getLiveness(code->code_constants);
std::unique_ptr<PhiAnalysis> phis;
if (entry_descriptor)
......
......@@ -54,9 +54,9 @@
namespace pyston {
LivenessAnalysis* SourceInfo::getLiveness() {
LivenessAnalysis* SourceInfo::getLiveness(const CodeConstants& code_constants) {
if (!liveness_info)
liveness_info = computeLivenessInfo(cfg);
liveness_info = computeLivenessInfo(cfg, code_constants);
return liveness_info.get();
}
......
This diff is collapsed.
......@@ -116,7 +116,7 @@ public:
SourceInfo* getSourceInfo() { return source_info; }
LivenessAnalysis* getLiveness() { return source_info->getLiveness(); }
LivenessAnalysis* getLiveness() { return source_info->getLiveness(getCodeConstants()); }
PhiAnalysis* getPhis() { return phis.get(); }
const ScopingResults& getScopeInfo();
......
This diff is collapsed.
......@@ -258,7 +258,7 @@ class BST_StoreName : public BST_stmt {
public:
int vreg_value = VREG_UNDEFINED;
InternedString id;
int index_id = VREG_UNDEFINED;
ScopeInfo::VarScopeType lookup_type;
int vreg = VREG_UNDEFINED;
......@@ -272,7 +272,7 @@ public:
class BST_StoreAttr : public BST_stmt {
public:
InternedString attr;
int index_attr = VREG_UNDEFINED;
int vreg_target = VREG_UNDEFINED;
int vreg_value = VREG_UNDEFINED;
......@@ -299,7 +299,7 @@ public:
class BST_LoadName : public BST_stmt_with_dest {
public:
InternedString id;
int index_id = VREG_UNDEFINED;
ScopeInfo::VarScopeType lookup_type;
// LoadName does not kill this vreg
int vreg = VREG_UNDEFINED;
......@@ -314,7 +314,7 @@ public:
class BST_LoadAttr : public BST_stmt_with_dest {
public:
InternedString attr;
int index_attr = VREG_UNDEFINED;
int vreg_value = VREG_UNDEFINED;
bool clsonly = false;
......@@ -359,8 +359,7 @@ public:
const int num_args;
const int num_keywords;
// used during execution stores all keyword names
std::unique_ptr<std::vector<BoxedString*>> keywords_names;
int index_keyword_names = -1;
BST_Call(BST_TYPE::BST_TYPE type, int num_args, int num_keywords)
: BST_stmt_with_dest(type), num_args(num_args), num_keywords(num_keywords) {}
......@@ -377,7 +376,7 @@ public:
class BST_CallAttr : public BST_Call {
public:
int vreg_value = VREG_UNDEFINED;
InternedString attr;
int index_attr = VREG_UNDEFINED;
int elts[1];
BSTVARVREGS2CALL(CallAttr, num_args, num_keywords, elts)
......@@ -386,7 +385,7 @@ public:
class BST_CallClsAttr : public BST_Call {
public:
int vreg_value = VREG_UNDEFINED;
InternedString attr;
int index_attr = VREG_UNDEFINED;
int elts[1];
BSTVARVREGS2CALL(CallClsAttr, num_args, num_keywords, elts)
......@@ -404,10 +403,8 @@ public:
class BST_ClassDef : public BST_stmt {
public:
BoxedCode* code;
InternedString name;
int vreg_bases_tuple;
int index_name = VREG_UNDEFINED;
int vreg_bases_tuple = VREG_UNDEFINED;
const int num_decorator;
int decorator[1];
......@@ -422,14 +419,14 @@ public:
class BST_DeleteAttr : public BST_stmt {
public:
int vreg_value = VREG_UNDEFINED;
InternedString attr;
int index_attr = VREG_UNDEFINED;
BSTFIXEDVREGS(DeleteAttr, BST_stmt)
};
class BST_DeleteName : public BST_stmt {
public:
InternedString id;
int index_id = VREG_UNDEFINED;
ScopeInfo::VarScopeType lookup_type;
int vreg = VREG_UNDEFINED;
......@@ -469,9 +466,7 @@ public:
class BST_FunctionDef : public BST_stmt {
public:
InternedString name; // if the name is not set this is a lambda
BoxedCode* code;
int index_name = VREG_UNDEFINED; // if the name is not set this is a lambda
const int num_decorator;
const int num_defaults;
......@@ -563,18 +558,20 @@ public:
class BST_MakeFunction : public BST_stmt_with_dest {
public:
BST_FunctionDef* function_def;
const int index_func_def;
BST_MakeFunction(BST_FunctionDef* fd) : BST_stmt_with_dest(BST_TYPE::MakeFunction, fd->lineno), function_def(fd) {}
BST_MakeFunction(BST_FunctionDef* fd, int index_func_def)
: BST_stmt_with_dest(BST_TYPE::MakeFunction, fd->lineno), index_func_def(index_func_def) {}
BSTNODE(MakeFunction)
};
class BST_MakeClass : public BST_stmt_with_dest {
public:
BST_ClassDef* class_def;
const int index_class_def;
BST_MakeClass(BST_ClassDef* cd) : BST_stmt_with_dest(BST_TYPE::MakeClass, cd->lineno), class_def(cd) {}
BST_MakeClass(BST_ClassDef* cd, int index_class_def)
: BST_stmt_with_dest(BST_TYPE::MakeClass, cd->lineno), index_class_def(index_class_def) {}
BSTNODE(MakeClass)
};
......@@ -722,14 +719,15 @@ template <typename T> T* bst_cast(BST_stmt* node) {
return static_cast<T*>(node);
}
class CodeConstants;
class BSTVisitor {
public:
const bool skip_visit_child_cfg;
// if skip_visit_child_cfg is set function and class defs will not visit their body nodes.
BSTVisitor(bool skip_visit_child_cfg) : skip_visit_child_cfg(skip_visit_child_cfg) {}
const CodeConstants& code_constants;
BSTVisitor(const CodeConstants& code_constants) : code_constants(code_constants) {}
virtual ~BSTVisitor() {}
const CodeConstants& getCodeConstants() const { return code_constants; }
// pseudo
virtual bool visit_vreg(int* vreg, bool is_dst = false) { RELEASE_ASSERT(0, ""); }
......@@ -790,7 +788,7 @@ public:
class NoopBSTVisitor : public BSTVisitor {
protected:
public:
NoopBSTVisitor(bool skip_visit_child_cfg) : BSTVisitor(skip_visit_child_cfg) {}
NoopBSTVisitor(const CodeConstants& code_constants) : BSTVisitor(code_constants) {}
virtual ~NoopBSTVisitor() {}
virtual bool visit_assert(BST_Assert* node) override { return false; }
......@@ -850,8 +848,12 @@ public:
class StmtVisitor {
protected:
public:
const CodeConstants& code_constants;
StmtVisitor(const CodeConstants& code_constants) : code_constants(code_constants) {}
virtual ~StmtVisitor() {}
const CodeConstants& getCodeConstants() const { return code_constants; }
virtual void visit_assert(BST_Assert* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_augbinop(BST_AugBinOp* node) { RELEASE_ASSERT(0, ""); }
virtual void visit_binop(BST_BinOp* node) { RELEASE_ASSERT(0, ""); }
......@@ -906,20 +908,18 @@ public:
virtual void visit_yield(BST_Yield* node) { RELEASE_ASSERT(0, ""); }
};
class CodeConstants;
void print_bst(BST_stmt* bst, const CodeConstants& code_constants);
class PrintVisitor : public BSTVisitor {
private:
llvm::raw_ostream& stream;
const CodeConstants& code_constants;
int indent;
void printIndent();
void printOp(AST_TYPE::AST_TYPE op_type);
public:
PrintVisitor(const CodeConstants& code_constants, int indent, llvm::raw_ostream& stream)
: BSTVisitor(false /* visit child CFG */), stream(stream), code_constants(code_constants), indent(indent) {}
: BSTVisitor(code_constants), stream(stream), indent(indent) {}
virtual ~PrintVisitor() {}
void flush() { stream.flush(); }
......@@ -978,11 +978,6 @@ public:
virtual bool visit_unpackintoarray(BST_UnpackIntoArray* node);
virtual bool visit_yield(BST_Yield* node);
};
// Given an BST node, return a vector of the node plus all its descendents.
// This is useful for analyses that care more about the constituent nodes than the
// exact tree structure; ex, finding all "global" directives.
void flatten(llvm::ArrayRef<BST_stmt*> roots, std::vector<BST_stmt*>& output, bool expand_scopes);
};
}
#endif
This diff is collapsed.
......@@ -168,7 +168,8 @@ public:
int getNumOfCrossBlockVRegs() const { return num_vregs_cross_block; }
bool hasVRegsAssigned() const { return num_vregs != -1; }
void assignVRegs(CFG* cfg, const ParamNames& param_names, llvm::DenseMap<int*, InternedString>& id_vreg);
void assignVRegs(const CodeConstants& code_constants, CFG* cfg, const ParamNames& param_names,
llvm::DenseMap<int*, InternedString>& id_vreg);
};
// Control Flow Graph
......
......@@ -86,6 +86,14 @@ public:
bool isCompilerCreatedName() const;
static InternedString unsafe(BoxedString* str) {
#ifndef NDEBUG
return InternedString(str, NULL);
#else
return InternedString(str);
#endif
}
friend class InternedStringPool;
friend struct std::hash<InternedString>;
friend struct std::less<InternedString>;
......
......@@ -484,6 +484,7 @@ public:
};
// Data about a single textual function definition.
class CodeConstants;
class SourceInfo {
private:
std::unique_ptr<LivenessAnalysis> liveness_info;
......@@ -499,7 +500,7 @@ public:
// between ast.h and core/types.h
int ast_type;
LivenessAnalysis* getLiveness();
LivenessAnalysis* getLiveness(const CodeConstants& code_constants);
SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags future_flags, int ast_type, bool is_generator);
~SourceInfo();
......
......@@ -4047,6 +4047,10 @@ BORROWED(BoxedFloat*) CodeConstants::getFloatConstant(double d) const {
void CodeConstants::dealloc() const {
decrefArray(owned_refs.data(), owned_refs.size());
owned_refs.clear();
for (auto&& e : funcs_and_classes) {
Py_DECREF(e.second);
}
funcs_and_classes.clear();
}
#ifndef Py_REF_DEBUG
......
......@@ -1079,6 +1079,8 @@ private:
// all objects we need to decref when the code object dies
mutable std::vector<Box*> owned_refs;
mutable std::vector<std::pair<BST_stmt*, BoxedCode*>> funcs_and_classes;
// Note: DenseMap doesn't work here since we don't prevent the tombstone/empty
// keys from reaching it.
mutable std::unordered_map<int64_t, BoxedInt*> int_constants;
......@@ -1086,6 +1088,9 @@ private:
// it's not a big deal if we get misses.
mutable std::unordered_map<int64_t, BoxedFloat*> float_constants;
// TODO: when we support tuple constants inside vregs we can remove it and just use a normal constant vreg for it
std::vector<std::unique_ptr<std::vector<BoxedString*>>> keyword_names;
public:
CodeConstants() {}
CodeConstants(CodeConstants&&) = default;
......@@ -1094,17 +1099,37 @@ public:
BORROWED(Box*) getConstant(int vreg) const { return constants[-(vreg + 1)]; }
InternedString getInternedString(int vreg) const { return InternedString::unsafe((BoxedString*)getConstant(vreg)); }
// returns the vreg num for the constant (which is a negative number)
int createVRegEntryForConstant(Box* o) {
constants.push_back(o);
return -constants.size();
}
void addOwnedRef(Box* o) const { owned_refs.emplace_back(o); }
BORROWED(BoxedInt*) getIntConstant(int64_t n) const;
BORROWED(BoxedFloat*) getFloatConstant(double d) const;
std::pair<BST_stmt*, BORROWED(BoxedCode*)> getFuncOrClass(int constant) const {
return funcs_and_classes[constant];
}
int addInternedString(InternedString s) { return createVRegEntryForConstant(s.getBox()); }
int addFuncOrClass(BST_stmt* stmt, STOLEN(BoxedCode*) code) {
funcs_and_classes.emplace_back(stmt, code);
return funcs_and_classes.size() - 1;
}
int addKeywordNames(llvm::ArrayRef<BoxedString*> name) {
keyword_names.emplace_back(new std::vector<BoxedString*>(name.begin(), name.end()));
return keyword_names.size() - 1;
}
const std::vector<BoxedString*>* getKeywordNames(int constant) const { return keyword_names[constant].get(); }
void dealloc() const;
};
......
......@@ -25,6 +25,18 @@ protected:
}
};
static BoxedCode* getCodeObjectOfFirstMakeFunction(BoxedCode* module_code) {
BoxedCode* code = NULL;
for (BST_stmt* stmt : module_code->source->cfg->blocks[0]->body) {
if (stmt->type != BST_TYPE::MakeFunction)
continue;
code = module_code->code_constants.getFuncOrClass(bst_cast<BST_MakeFunction>(stmt)->index_func_def).second;
break;
}
assert(code);
return code;
}
// this test use functions (VRegInfo::getVReg) which are only available in a debug build
#ifndef NDEBUG
TEST_F(AnalysisTest, augassign) {
......@@ -52,16 +64,10 @@ TEST_F(AnalysisTest, augassign) {
ParamNames param_names(args, *module->interned_strings.get());
// Hack to get at the cfg:
CFG* cfg = NULL;
for (BST_stmt* stmt : module_code->source->cfg->blocks[0]->body) {
if (stmt->type != BST_TYPE::MakeFunction)
continue;
cfg = bst_cast<BST_MakeFunction>(stmt)->function_def->code->source->cfg;
break;
}
assert(cfg);
BoxedCode* code = getCodeObjectOfFirstMakeFunction(module_code);
CFG* cfg = code->source->cfg;
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, code->code_constants);
auto&& vregs = cfg->getVRegInfo();
//cfg->print();
......@@ -96,16 +102,9 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) {
auto module_code = computeAllCFGs(module, true, future_flags, boxString(fn), main_module);
// Hack to get at the cfg:
BoxedCode* code = NULL;
for (BST_stmt* stmt : module_code->source->cfg->blocks[0]->body) {
if (stmt->type != BST_TYPE::MakeFunction)
continue;
code = bst_cast<BST_MakeFunction>(stmt)->function_def->code;
break;
}
assert(code);
BoxedCode* code = getCodeObjectOfFirstMakeFunction(module_code);
CFG* cfg = code->source->cfg;
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, module_code->code_constants);
// cfg->print();
......
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