@@ -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
7171public: 
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
136114LivenessAnalysis::~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- 
146117bool  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  {
232203private: 
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- 
275214public: 
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
462386bool  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
467392bool  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
477403bool  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
485412bool  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}
0 commit comments