Commit ec3be90d authored by Marius Wachtler's avatar Marius Wachtler

BSTVisitor: pass code constants always in

we will soon need this
parent 357585c9
......@@ -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,9 @@ private:
public:
LivenessBBVisitor(LivenessAnalysis* analysis)
: statuses(analysis->cfg->getVRegInfo().getTotalNumOfVRegs()), analysis(analysis) {}
: NoopBSTVisitor(analysis->code_constants),
statuses(analysis->cfg->getVRegInfo().getTotalNumOfVRegs()),
analysis(analysis) {}
bool firstIsUse(int vreg) const { return getStatusFirst(vreg) == Status::USED; }
bool firstIsDef(int vreg) const { return getStatusFirst(vreg) == Status::DEFINED; }
......@@ -94,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) {
......@@ -180,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);
......@@ -210,7 +214,8 @@ private:
}
public:
DefinednessVisitor(Map& state) : 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;
......@@ -250,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);
......@@ -265,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:
......@@ -276,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);
......@@ -325,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);
......@@ -413,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++) {
......
......@@ -182,6 +182,7 @@ public:
Box** getVRegs() { return vregs; }
const ScopingResults& getScopeInfo() { return scope_info; }
const CodeConstants& getCodeConstants() { return getCode()->code_constants; }
LivenessAnalysis* getLiveness() { return source_info->getLiveness(getCodeConstants()); }
void addSymbol(int vreg, Box* value, bool allow_duplicates);
void setGenerator(Box* gen);
......@@ -487,7 +488,7 @@ void ASTInterpreter::doStore(int vreg, STOLEN(Value) value) {
return;
}
if (jit) {
bool is_live = source_info->getLiveness()->isLiveAtEnd(vreg, current_block);
bool is_live = getLiveness()->isLiveAtEnd(vreg, current_block);
if (is_live)
jit->emitSetLocal(vreg, value);
else
......@@ -658,7 +659,7 @@ Box* ASTInterpreter::doOSR(BST_Jump* node) {
static StatCounter ast_osrs("num_ast_osrs");
ast_osrs.log();
LivenessAnalysis* liveness = source_info->getLiveness();
LivenessAnalysis* liveness = getLiveness();
std::unique_ptr<PhiAnalysis> phis = computeRequiredPhis(getCode()->param_names, source_info->cfg, liveness);
llvm::SmallVector<int, 16> dead_vregs;
......@@ -1538,7 +1539,7 @@ Value ASTInterpreter::getVReg(int vreg, bool is_kill) {
if (is_kill) {
is_live = false;
} else {
is_live = source_info->getLiveness()->isLiveAtEnd(vreg, current_block);
is_live = getLiveness()->isLiveAtEnd(vreg, current_block);
}
if (is_live) {
......@@ -1595,7 +1596,7 @@ Value ASTInterpreter::visit_loadname(BST_LoadName* node) {
bool is_live = true;
if (node->lookup_type == ScopeInfo::VarScopeType::FAST) {
assert(node->vreg >= 0);
is_live = source_info->getLiveness()->isLiveAtEnd(node->vreg, current_block);
is_live = getLiveness()->isLiveAtEnd(node->vreg, current_block);
}
if (is_live)
......@@ -1696,7 +1697,7 @@ void ASTInterpreter::visit_storename(BST_StoreName* node) {
if (jit) {
bool is_live = true;
if (!closure)
is_live = source_info->getLiveness()->isLiveAtEnd(node->vreg, current_block);
is_live = getLiveness()->isLiveAtEnd(node->vreg, current_block);
if (is_live) {
if (closure) {
jit->emitSetLocalClosure(node, value);
......
......@@ -344,7 +344,8 @@ private:
SymbolTable* sym_table;
bool created_new_sym_table;
SymTableDstVRegDeleter(SymbolTable* sym_table) : 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 {
......@@ -360,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);
}
......@@ -738,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]) {
......@@ -1118,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();
}
......
......@@ -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();
......
......@@ -722,12 +722,15 @@ template <typename T> T* bst_cast(BST_stmt* node) {
return static_cast<T*>(node);
}
class CodeConstants;
class BSTVisitor {
public:
BSTVisitor() {}
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, ""); }
......@@ -788,7 +791,7 @@ public:
class NoopBSTVisitor : public BSTVisitor {
protected:
public:
NoopBSTVisitor() {}
NoopBSTVisitor(const CodeConstants& code_constants) : BSTVisitor(code_constants) {}
virtual ~NoopBSTVisitor() {}
virtual bool visit_assert(BST_Assert* node) override { return false; }
......@@ -848,8 +851,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, ""); }
......@@ -904,20 +911,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)
: stream(stream), code_constants(code_constants), indent(indent) {}
: BSTVisitor(code_constants), stream(stream), indent(indent) {}
virtual ~PrintVisitor() {}
void flush() { stream.flush(); }
......
......@@ -2916,8 +2916,8 @@ public:
enum Step { TrackBlockUsage = 0, UserVisible, CrossBlock, SingleBlockUse } step;
AssignVRegsVisitor(llvm::DenseMap<int*, InternedString>& id_vreg)
: current_block(0), next_vreg(0), id_vreg(id_vreg) {}
AssignVRegsVisitor(const CodeConstants& code_constants, llvm::DenseMap<int*, InternedString>& id_vreg)
: NoopBSTVisitor(code_constants), current_block(0), next_vreg(0), id_vreg(id_vreg) {}
bool visit_vreg(int* vreg, bool is_dst = false) override {
if (is_dst) {
......@@ -3035,11 +3035,12 @@ public:
}
};
void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names, llvm::DenseMap<int*, InternedString>& id_vreg) {
void VRegInfo::assignVRegs(const CodeConstants& code_constants, CFG* cfg, const ParamNames& param_names,
llvm::DenseMap<int*, InternedString>& id_vreg) {
assert(!hasVRegsAssigned());
// warning: don't rearrange the steps, they need to be run in this exact order!
AssignVRegsVisitor visitor(id_vreg);
AssignVRegsVisitor visitor(code_constants, id_vreg);
for (auto step : { AssignVRegsVisitor::TrackBlockUsage, AssignVRegsVisitor::UserVisible,
AssignVRegsVisitor::CrossBlock, AssignVRegsVisitor::SingleBlockUse }) {
visitor.step = step;
......@@ -3347,7 +3348,7 @@ static std::pair<CFG*, CodeConstants> computeCFG(llvm::ArrayRef<AST_stmt*> body,
}
}
rtn->getVRegInfo().assignVRegs(rtn, param_names, visitor.id_vreg);
rtn->getVRegInfo().assignVRegs(visitor.code_constants, rtn, param_names, visitor.id_vreg);
if (VERBOSITY("cfg") >= 2) {
......
......@@ -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
......
......@@ -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();
......
......@@ -61,7 +61,7 @@ TEST_F(AnalysisTest, augassign) {
}
assert(cfg);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg);
std::unique_ptr<LivenessAnalysis> liveness = computeLivenessInfo(cfg, module_code->code_constants);
auto&& vregs = cfg->getVRegInfo();
//cfg->print();
......@@ -105,7 +105,7 @@ void doOsrTest(bool is_osr, bool i_maybe_undefined) {
}
assert(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