Skip to content

Commit 9cd8e75

Browse files
authored
Merge pull request #1377 from undingen/new_bst4
BST: convert all nodes to directly operate at vregs instead of names
2 parents 4e10a4f + c0a273f commit 9cd8e75

35 files changed

+4334
-3841
lines changed

src/analysis/function_analysis.cpp

Lines changed: 47 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class LivenessBBVisitor : public NoopBSTVisitor {
5555
VRegMap<Status> statuses;
5656
LivenessAnalysis* analysis;
5757

58-
void _doLoad(int vreg, BST_Name* node) {
58+
void _doLoad(int vreg) {
5959
Status& status = statuses[vreg];
6060
status.addUsage(Status::USED);
6161
}
@@ -70,50 +70,28 @@ class LivenessBBVisitor : public NoopBSTVisitor {
7070

7171
public:
7272
LivenessBBVisitor(LivenessAnalysis* analysis)
73-
: statuses(analysis->cfg->getVRegInfo().getTotalNumOfVRegs()), analysis(analysis) {}
73+
: NoopBSTVisitor(true /* skip child CFG nodes */),
74+
statuses(analysis->cfg->getVRegInfo().getTotalNumOfVRegs()),
75+
analysis(analysis) {}
7476

7577
bool firstIsUse(int vreg) const { return getStatusFirst(vreg) == Status::USED; }
76-
7778
bool firstIsDef(int vreg) const { return getStatusFirst(vreg) == Status::DEFINED; }
7879

79-
bool isKilledAt(BST_Name* node, bool is_live_at_end) { return node->is_kill; }
80-
81-
bool visit_classdef(BST_ClassDef* node) {
82-
for (auto e : node->bases)
83-
e->accept(this);
84-
for (auto e : node->decorator_list)
85-
e->accept(this);
86-
87-
return true;
88-
}
89-
90-
bool visit_functiondef(BST_FunctionDef* node) {
91-
for (auto* d : node->decorator_list)
92-
d->accept(this);
93-
for (auto* d : node->args->defaults)
94-
d->accept(this);
95-
80+
bool visit_vreg(int* vreg, bool is_dst) override {
81+
if (*vreg >= 0) {
82+
if (is_dst)
83+
_doStore(*vreg);
84+
else
85+
_doLoad(*vreg);
86+
}
9687
return true;
9788
}
9889

99-
bool visit_name(BST_Name* node) {
100-
if (node->vreg == -1)
90+
bool visit_deletename(BST_DeleteName* node) override {
91+
if (node->vreg < 0 || node->vreg >= analysis->cfg->getVRegInfo().getNumOfUserVisibleVRegs())
10192
return true;
102-
103-
if (node->ctx_type == AST_TYPE::Load)
104-
_doLoad(node->vreg, node);
105-
else if (node->ctx_type == AST_TYPE::Del) {
106-
// Hack: we don't have a bytecode for temporary-kills:
107-
if (node->vreg >= analysis->cfg->getVRegInfo().getNumOfUserVisibleVRegs())
108-
return true;
109-
_doLoad(node->vreg, node);
110-
_doStore(node->vreg);
111-
} else if (node->ctx_type == AST_TYPE::Store || node->ctx_type == AST_TYPE::Param)
112-
_doStore(node->vreg);
113-
else {
114-
ASSERT(0, "%d", node->ctx_type);
115-
abort();
116-
}
93+
_doLoad(node->vreg);
94+
_doStore(node->vreg);
11795
return true;
11896
}
11997
};
@@ -136,13 +114,6 @@ LivenessAnalysis::LivenessAnalysis(CFG* cfg) : cfg(cfg), result_cache(cfg->getVR
136114
LivenessAnalysis::~LivenessAnalysis() {
137115
}
138116

139-
bool LivenessAnalysis::isKill(BST_Name* node, CFGBlock* parent_block) {
140-
if (node->id.s()[0] != '#')
141-
return false;
142-
143-
return liveness_cache[parent_block]->isKilledAt(node, isLiveAtEnd(node->vreg, parent_block));
144-
}
145-
146117
bool LivenessAnalysis::isLiveAtEnd(int vreg, CFGBlock* block) {
147118
// Is a user-visible name, always live:
148119
if (vreg < block->cfg->getVRegInfo().getNumOfUserVisibleVRegs())
@@ -228,102 +199,55 @@ class DefinednessBBAnalyzer : public BBAnalyzer<DefinednessAnalysis::DefinitionL
228199
virtual void processBB(Map& starting, CFGBlock* block) const;
229200
};
230201

231-
class DefinednessVisitor : public BSTVisitor {
202+
class DefinednessVisitor : public NoopBSTVisitor {
232203
private:
233204
typedef DefinednessBBAnalyzer::Map Map;
234205
Map& state;
235206

236207
void _doSet(int vreg) {
208+
if (vreg == VREG_UNDEFINED)
209+
return;
237210
assert(vreg >= 0 && vreg < state.numVregs());
238211
state[vreg] = DefinednessAnalysis::Defined;
239212
}
240213

241-
void _doSet(BST* t) {
242-
switch (t->type) {
243-
case BST_TYPE::Attribute:
244-
// doesn't affect definedness (yet?)
245-
break;
246-
case BST_TYPE::Name: {
247-
auto name = bst_cast<BST_Name>(t);
248-
if (name->lookup_type == ScopeInfo::VarScopeType::FAST
249-
|| name->lookup_type == ScopeInfo::VarScopeType::CLOSURE) {
250-
assert(name->vreg != -1);
251-
_doSet(name->vreg);
252-
} else if (name->lookup_type == ScopeInfo::VarScopeType::GLOBAL
253-
|| name->lookup_type == ScopeInfo::VarScopeType::NAME) {
254-
assert(name->vreg == -1);
255-
// skip
256-
} else {
257-
RELEASE_ASSERT(0, "%d", static_cast<int>(name->lookup_type));
258-
}
259-
break;
260-
}
261-
case BST_TYPE::Subscript:
262-
break;
263-
case BST_TYPE::Tuple: {
264-
BST_Tuple* tt = bst_cast<BST_Tuple>(t);
265-
for (int i = 0; i < tt->elts.size(); i++) {
266-
_doSet(tt->elts[i]);
267-
}
268-
break;
269-
}
270-
default:
271-
ASSERT(0, "Unknown type for DefinednessVisitor: %d", t->type);
272-
}
273-
}
274-
275214
public:
276-
DefinednessVisitor(Map& state) : state(state) {}
277-
278-
virtual bool visit_assert(BST_Assert* node) { return true; }
279-
virtual bool visit_branch(BST_Branch* node) { return true; }
280-
virtual bool visit_expr(BST_Expr* node) { return true; }
281-
virtual bool visit_invoke(BST_Invoke* node) { return false; }
282-
virtual bool visit_jump(BST_Jump* node) { return true; }
283-
virtual bool visit_print(BST_Print* node) { return true; }
284-
virtual bool visit_raise(BST_Raise* node) { return true; }
285-
virtual bool visit_return(BST_Return* node) { return true; }
286-
287-
virtual bool visit_delete(BST_Delete* node) {
288-
auto t = node->target;
289-
if (t->type == BST_TYPE::Name) {
290-
BST_Name* name = bst_cast<BST_Name>(t);
291-
if (name->lookup_type != ScopeInfo::VarScopeType::GLOBAL
292-
&& name->lookup_type != ScopeInfo::VarScopeType::NAME) {
293-
assert(name->vreg != -1);
294-
state[name->vreg] = DefinednessAnalysis::Undefined;
295-
} else
296-
assert(name->vreg == -1);
297-
} else {
298-
// The CFG pass should reduce all deletes to the "basic" deletes on names/attributes/subscripts.
299-
// If not, probably the best way to do this would be to just do a full BST traversal
300-
// and look for BST_Name's with a ctx of Del
301-
assert(t->type == BST_TYPE::Attribute || t->type == BST_TYPE::Subscript);
302-
}
303-
return true;
215+
DefinednessVisitor(Map& state) : NoopBSTVisitor(true /* skip child CFG nodes */), state(state) {}
216+
bool visit_vreg(int* vreg, bool is_dest) override {
217+
if (*vreg < 0)
218+
return false;
219+
220+
if (is_dest)
221+
state[*vreg] = DefinednessAnalysis::Defined;
222+
else
223+
state[*vreg] = DefinednessAnalysis::Undefined;
224+
return false;
304225
}
305226

306-
virtual bool visit_classdef(BST_ClassDef* node) {
307-
assert(0 && "I think this isn't needed");
308-
//_doSet(node->name);
227+
bool visit_deletename(BST_DeleteName* node) override {
228+
if (node->lookup_type != ScopeInfo::VarScopeType::GLOBAL
229+
&& node->lookup_type != ScopeInfo::VarScopeType::NAME) {
230+
assert(node->vreg >= 0);
231+
state[node->vreg] = DefinednessAnalysis::Undefined;
232+
} else
233+
assert(node->vreg == VREG_UNDEFINED);
309234
return true;
310235
}
311236

312-
virtual bool visit_functiondef(BST_FunctionDef* node) {
313-
assert(0 && "I think this isn't needed");
314-
//_doSet(node->name);
237+
bool visit_copyvreg(BST_CopyVReg* node) override {
238+
// don't visit the vreg it will never get killed
239+
// visit_vreg(&node->vreg_src, false);
240+
_doSet(node->vreg_dst);
315241
return true;
316242
}
317243

318-
virtual bool visit_assign(BST_Assign* node) {
319-
_doSet(node->target);
244+
bool visit_loadname(BST_LoadName* node) override {
245+
// don't visit the vreg it will never get killed
246+
// visit_vreg(&node->vreg, false);
247+
_doSet(node->vreg_dst);
320248
return true;
321249
}
322250

323-
virtual bool visit_arguments(BST_arguments* node) { RELEASE_ASSERT(0, "this shouldn't get hit"); }
324-
325-
virtual bool visit_exec(BST_Exec* node) { return true; }
326-
327251
friend class DefinednessBBAnalyzer;
328252
};
329253

@@ -460,11 +384,13 @@ const VRegSet& PhiAnalysis::getAllRequiredFor(CFGBlock* block) {
460384
}
461385

462386
bool PhiAnalysis::isRequired(int vreg, CFGBlock* block) {
387+
assert(vreg >= 0);
463388
assert(required_phis.count(block));
464389
return required_phis.find(block)->second[vreg];
465390
}
466391

467392
bool PhiAnalysis::isRequiredAfter(int vreg, CFGBlock* block) {
393+
assert(vreg >= 0);
468394
// If there are multiple successors, then none of them are allowed
469395
// to require any phi nodes
470396
if (block->successors.size() != 1)
@@ -475,6 +401,7 @@ bool PhiAnalysis::isRequiredAfter(int vreg, CFGBlock* block) {
475401
}
476402

477403
bool PhiAnalysis::isPotentiallyUndefinedAfter(int vreg, CFGBlock* block) {
404+
assert(vreg >= 0);
478405
for (auto b : block->successors) {
479406
if (isPotentiallyUndefinedAt(vreg, b))
480407
return true;
@@ -483,6 +410,7 @@ bool PhiAnalysis::isPotentiallyUndefinedAfter(int vreg, CFGBlock* block) {
483410
}
484411

485412
bool PhiAnalysis::isPotentiallyUndefinedAt(int vreg, CFGBlock* block) {
413+
assert(vreg >= 0);
486414
assert(definedness.defined_at_beginning.count(block));
487415
return definedness.defined_at_beginning.find(block)->second[vreg] != DefinednessAnalysis::Defined;
488416
}

src/analysis/function_analysis.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@
2626

2727
namespace pyston {
2828

29-
class BST_arguments;
3029
class BST_Jump;
31-
class BST_Name;
3230
class CFG;
3331
class CFGBlock;
3432
class LivenessBBVisitor;
@@ -47,9 +45,6 @@ class LivenessAnalysis {
4745
LivenessAnalysis(CFG* cfg);
4846
~LivenessAnalysis();
4947

50-
// we don't keep track of node->parent_block relationships, so you have to pass both:
51-
bool isKill(BST_Name* node, CFGBlock* parent_block);
52-
5348
bool isLiveAtEnd(int vreg, CFGBlock* block);
5449
};
5550

src/analysis/scoping_analysis.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,11 @@ ScopingResults::ScopingResults(ScopeInfo* scope_info, bool globals_from_module)
3636
deref_info = scope_info->getAllDerefVarsAndInfo();
3737
}
3838

39-
DerefInfo ScopingResults::getDerefInfo(BST_Name* node) const {
39+
DerefInfo ScopingResults::getDerefInfo(BST_LoadName* node) const {
4040
assert(node->lookup_type == ScopeInfo::VarScopeType::DEREF);
4141
assert(node->deref_info.offset != INT_MAX);
4242
return node->deref_info;
4343
}
44-
size_t ScopingResults::getClosureOffset(BST_Name* node) const {
45-
assert(node->lookup_type == ScopeInfo::VarScopeType::CLOSURE);
46-
assert(node->closure_offset != -1);
47-
return node->closure_offset;
48-
}
4944

5045
class YieldVisitor : public NoopASTVisitor {
5146
public:

0 commit comments

Comments
 (0)