]> granicus.if.org Git - clang/commitdiff
Migrated LiveVariables to use the new DataflowStmtVisitor interface. The code
authorTed Kremenek <kremenek@apple.com>
Wed, 12 Sep 2007 19:10:52 +0000 (19:10 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 12 Sep 2007 19:10:52 +0000 (19:10 +0000)
is much simpler now.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41885 91177308-0d34-0410-b5e6-96231b3b80d8

Analysis/LiveVariables.cpp

index 40d4f764b30a9d7e1e7c27659a2ce1582b9138e3..b6079e0a70f11336c89995a47a3b64394bbb2824 100644 (file)
@@ -15,7 +15,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/CFG.h"
-#include "clang/AST/StmtVisitor.h"
+#include "clang/Analysis/DataflowStmtVisitor.h"
 #include "clang/Lex/IdentifierTable.h"
 #include "llvm/ADT/SmallPtrSet.h"
 
@@ -112,7 +112,8 @@ public:
 
 namespace {
 
-class LivenessTFuncs : public StmtVisitor<LivenessTFuncs,void> {
+class LivenessTFuncs : public DataflowStmtVisitor<LivenessTFuncs,
+                                              dataflow::backward_analysis_tag> {
   LiveVariables& L;
   llvm::BitVector Live;
   llvm::BitVector KilledAtLeastOnce;
@@ -120,22 +121,21 @@ class LivenessTFuncs : public StmtVisitor<LivenessTFuncs,void> {
   const CFGBlock* CurrentBlock;
   bool blockPreviouslyProcessed;
   LiveVariablesObserver* Observer;
+
 public:
   LivenessTFuncs(LiveVariables& l, LiveVariablesObserver* A = NULL)
     : L(l), CurrentStmt(NULL), CurrentBlock(NULL),
-      blockPreviouslyProcessed(false), Observer(A)
-  {
+      blockPreviouslyProcessed(false), Observer(A) {
     Live.resize(l.getNumDecls());
     KilledAtLeastOnce.resize(l.getNumDecls());
   }
-
-  void VisitStmt(Stmt* S);
+  
   void VisitDeclRefExpr(DeclRefExpr* DR);
   void VisitBinaryOperator(BinaryOperator* B);
   void VisitAssign(BinaryOperator* B);
-  void VisitStmtExpr(StmtExpr* S);
   void VisitDeclStmt(DeclStmt* DS);
   void VisitUnaryOperator(UnaryOperator* U);
+  void ObserveStmt(Stmt* S);
 
   unsigned getIdx(const VarDecl* D) {
     LiveVariables::VarInfoMap& V = L.getVarInfoMap();
@@ -149,47 +149,19 @@ public:
   LiveVariables::VarInfo& KillVar(VarDecl* D);
 };
 
-void LivenessTFuncs::VisitStmt(Stmt* S) {
-  if (Observer)
-    Observer->ObserveStmt(S,L,Live);
-    
-  // Evaluate the transfer functions for all subexpressions.  Note that
-  // each invocation of "Visit" will have a side-effect: "Liveness" and "Kills"
-  // will be updated.  
-  for (Stmt::child_iterator I = S->child_begin(),E = S->child_end(); I != E;++I)
-    Visit(*I);
+void LivenessTFuncs::ObserveStmt(Stmt* S) { 
+  if (Observer) Observer->ObserveStmt(S,L,Live); 
 }
 
 void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
-  if (Observer)
-    Observer->ObserveStmt(DR,L,Live);
-    
   // Register a use of the variable.
   if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
     Live.set(getIdx(V));
 }
-
-void LivenessTFuncs::VisitStmtExpr(StmtExpr* S) {
-  // Do nothing.  The substatements of S are segmented into separate
-  // statements in the CFG.
-}
   
-void LivenessTFuncs::VisitBinaryOperator(BinaryOperator* B) {
-  switch (B->getOpcode()) {
-    case BinaryOperator::LAnd:
-    case BinaryOperator::LOr:
-    case BinaryOperator::Comma:
-      // Do nothing.  These operations are broken up into multiple
-      // statements in the CFG.  All these expressions do is return
-      // the value of their subexpressions, but these subexpressions will
-      // be evalualated elsewhere in the CFG.
-      break;
-      
-    // FIXME: handle '++' and '--'
-    default:        
-      if (B->isAssignmentOp()) VisitAssign(B);
-      else VisitStmt(B);
-  }
+void LivenessTFuncs::VisitBinaryOperator(BinaryOperator* B) {     
+  if (B->isAssignmentOp()) VisitAssign(B);
+  else VisitStmt(B);
 }
 
 void LivenessTFuncs::VisitUnaryOperator(UnaryOperator* U) {
@@ -243,10 +215,7 @@ LiveVariables::VarInfo& LivenessTFuncs::KillVar(VarDecl* D) {
   return I->second.V;
 }  
 
-void LivenessTFuncs::VisitAssign(BinaryOperator* B) {
-  if (Observer)
-    Observer->ObserveStmt(B,L,Live);
-    
+void LivenessTFuncs::VisitAssign(BinaryOperator* B) {    
   // Check if we are assigning to a variable.
   Stmt* LHS = B->getLHS();
   
@@ -286,6 +255,7 @@ llvm::BitVector* LivenessTFuncs::getBlockEntryLiveness(const CFGBlock* B) {
   return (I == BMap.end()) ? NULL : &(I->second);  
 }
 
+  
 bool LivenessTFuncs::ProcessBlock(const CFGBlock* B) {
 
   CurrentBlock = B;
@@ -304,7 +274,7 @@ bool LivenessTFuncs::ProcessBlock(const CFGBlock* B) {
       Live |= *V;
 
   if (Observer)
-    Observer->ObserveBlockExit(B,L,Live);
+    Observer->ObserveBlockExit(B,L,Live);    
       
   // Tentatively mark all variables alive at the end of the current block
   // as being alive during the whole block.  We then cull these out as
@@ -313,17 +283,13 @@ bool LivenessTFuncs::ProcessBlock(const CFGBlock* B) {
          I=L.getVarInfoMap().begin(), E=L.getVarInfoMap().end(); I != E; ++I)
     if (Live[I->second.Idx])
       I->second.V.AliveBlocks.set(B->getBlockID());                              
-  
-  // March up the statements and process the transfer functions.
-  for (CFGBlock::const_reverse_iterator I=B->rbegin(), E=B->rend(); I!=E; ++I) {
-    CurrentStmt = *I;
-    Visit(CurrentStmt);    
-  }
 
+  // Visit the statements in reverse order;
+  VisitBlock(B);
+  
   // Compare the computed "Live" values with what we already have
   // for the entry to this block.
   bool hasChanged = false;
-
   
   if (!blockPreviouslyProcessed) {
     // We have not previously calculated liveness information for this block.