[cfe-commits] r46137 - in /cfe/trunk: Analysis/DeadStores.cpp Analysis/GRConstants.cpp Analysis/LiveVariables.cpp include/clang/Analysis/Analyses/LiveVariables.h include/clang/Analysis/FlowSensitive/DataflowSolver.h include/clang/Analysis/FlowSensitive/DataflowValues.h

Ted Kremenek kremenek at apple.com
Thu Jan 17 10:25:22 PST 2008


Author: kremenek
Date: Thu Jan 17 12:25:22 2008
New Revision: 46137

URL: http://llvm.org/viewvc/llvm-project?rev=46137&view=rev
Log:
Added support to dataflow solver to (when requested) also record dataflow
values for the block-level expressions.

Modified 'LiveVariables' to provide the option to clients to record
liveness information for block-level expressions (using the above feature).

Modified 'DeadStores' to conform to the new interface of 'LiveVariables'.

Modified 'GRConstants' to compute liveness information for block-level
expressions.

Modified:
    cfe/trunk/Analysis/DeadStores.cpp
    cfe/trunk/Analysis/GRConstants.cpp
    cfe/trunk/Analysis/LiveVariables.cpp
    cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
    cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
    cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h

Modified: cfe/trunk/Analysis/DeadStores.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/DeadStores.cpp?rev=46137&r1=46136&r2=46137&view=diff

==============================================================================
--- cfe/trunk/Analysis/DeadStores.cpp (original)
+++ cfe/trunk/Analysis/DeadStores.cpp Thu Jan 17 12:25:22 2008
@@ -80,7 +80,7 @@
   LiveVariables L(cfg);
   L.runOnCFG(cfg);
   DeadStoreObs A(Ctx, Diags);
-  L.runOnAllBlocks(cfg,A);
+  L.runOnAllBlocks(cfg,&A);
 }
 
 } // end namespace clang

Modified: cfe/trunk/Analysis/GRConstants.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRConstants.cpp?rev=46137&r1=46136&r2=46137&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Thu Jan 17 12:25:22 2008
@@ -189,6 +189,7 @@
     cfg = &c;    
     Liveness = new LiveVariables(c);
     Liveness->runOnCFG(c);
+    Liveness->runOnAllBlocks(c, NULL, true);
   }
   
   StateTy getInitialState() {
@@ -274,9 +275,6 @@
 
 GRConstants::StateTy
 GRConstants::RemoveSubExprMappings(StateTy M) {
-#if 0
-  return M;
-#else
   for (StateTy::iterator I = M.begin(), E = M.end();
        I!=E && I.getKey().getKind() == DSPtr::IsSubExp; ++I) {
     // Note: we can assign a new map to M since the iterators are
@@ -286,16 +284,12 @@
   }
 
   return M;
-#endif
 }
 
 
 GRConstants::StateTy
 GRConstants::RemoveDescendantMappings(Stmt* S, GRConstants::StateTy State,
                                       unsigned Levels) {
-#if 1
-  return State;
-#else
   typedef Stmt::child_iterator iterator;
   
   for (iterator I=S->child_begin(), E=S->child_end(); I!=E; ++I)
@@ -317,7 +311,6 @@
     }
   
   return State;
-#endif
 }
 
 void GRConstants::DoStmt(Stmt* S) {  
@@ -357,8 +350,11 @@
 
 
 void GRConstants::VisitBinAssign(BinaryOperator* B) {
-  if (DeclRefExpr* D = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParens()))
-    AddBinding(D->getDecl(), GetBinding(B->getRHS()));
+  if (DeclRefExpr* D = dyn_cast<DeclRefExpr>(B->getLHS()->IgnoreParens())) {
+    ExprVariantTy V = GetBinding(B->getRHS());
+    AddBinding(D->getDecl(), V);
+    AddBinding(B, V);
+  }
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=46137&r1=46136&r2=46137&view=diff

==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/Analysis/LiveVariables.cpp Thu Jan 17 12:25:22 2008
@@ -165,11 +165,12 @@
 }
 
 void LiveVariables::runOnAllBlocks(const CFG& cfg,
-                                   LiveVariables::ObserverTy& Obs) {
+                                   LiveVariables::ObserverTy* Obs,
+                                   bool recordStmtValues) {
   Solver S(*this);
   ObserverTy* OldObserver = getAnalysisData().Observer;
-  getAnalysisData().Observer = &Obs;
-  S.runOnAllBlocks(cfg);
+  getAnalysisData().Observer = Obs;
+  S.runOnAllBlocks(cfg, recordStmtValues);
   getAnalysisData().Observer = OldObserver;
 }
 

Modified: cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h?rev=46137&r1=46136&r2=46137&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/LiveVariables.h Thu Jan 17 12:25:22 2008
@@ -70,6 +70,12 @@
   /// IsLive - Return true if a variable is live at beginning of a
   /// specified block.
   bool isLive(const CFGBlock* B, const VarDecl* D) const;
+                                              
+  /// IsLive - Returns true if a variable is live at the beginning of the
+  ///  the statement.  This query only works if liveness information
+  ///  has been recorded at the statement level (see runOnAllBlocks), and
+  ///  only returns liveness information for block-level expressions.
+  bool isLive(const Stmt* S, const VarDecl* D) const;
   
   /// IsLive - Return true if a variable is live according to the
   ///  provided livness bitvector.
@@ -93,7 +99,13 @@
   void InitializeValues(const CFG& cfg);
   
   void runOnCFG(CFG& cfg);
-  void runOnAllBlocks(const CFG& cfg, ObserverTy& Obs);
+                                              
+  /// runOnAllBlocks - Propagate the dataflow values once for each block,
+  ///  starting from the current dataflow values.  'recordStmtValues' indicates
+  ///  whether the method should store dataflow values per each individual
+  ///  block-level expression.
+  void runOnAllBlocks(const CFG& cfg, ObserverTy* Obs,
+                      bool recordStmtValues=false);
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h?rev=46137&r1=46136&r2=46137&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowSolver.h Thu Jan 17 12:25:22 2008
@@ -140,12 +140,12 @@
   ~DataflowSolver() {}  
   
   /// runOnCFG - Computes dataflow values for all blocks in a CFG.
-  void runOnCFG(CFG& cfg) {
+  void runOnCFG(CFG& cfg, bool recordStmtValues = false) {
     // Set initial dataflow values and boundary conditions.
     D.InitializeValues(cfg);     
     // Solve the dataflow equations.  This will populate D.EdgeDataMap
     // with dataflow values.
-    SolveDataflowEquations(cfg);    
+    SolveDataflowEquations(cfg, recordStmtValues);
   }
   
   /// runOnBlock - Computes dataflow values for a given block.  This
@@ -153,23 +153,29 @@
   ///  dataflow values using runOnCFG, as runOnBlock is intended to
   ///  only be used for querying the dataflow values within a block
   ///  with and Observer object.
-  void runOnBlock(const CFGBlock* B) {
+  void runOnBlock(const CFGBlock* B, bool recordStmtValues) {
     BlockDataMapTy& M = D.getBlockDataMap();
     typename BlockDataMapTy::iterator I = M.find(B);
 
     if (I != M.end()) {
       TF.getVal().copyValues(I->second);
-      ProcessBlock(B);
+      ProcessBlock(B, recordStmtValues);
     }
   }
   
-  void runOnBlock(const CFGBlock& B) { runOnBlock(&B); }
-  void runOnBlock(CFG::iterator& I) { runOnBlock(*I); }
-  void runOnBlock(CFG::const_iterator& I) { runOnBlock(*I); }
+  void runOnBlock(const CFGBlock& B, bool recordStmtValues) {
+    runOnBlock(&B, recordStmtValues);
+  }  
+  void runOnBlock(CFG::iterator& I, bool recordStmtValues) {
+    runOnBlock(*I, recordStmtValues);
+  }
+  void runOnBlock(CFG::const_iterator& I, bool recordStmtValues) {
+    runOnBlock(*I, recordStmtValues);
+  }
 
-  void runOnAllBlocks(const CFG& cfg) {
+  void runOnAllBlocks(const CFG& cfg, bool recordStmtValues = false) {
     for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
-      runOnBlock(I);
+      runOnBlock(I, recordStmtValues);
   }
   
   //===----------------------------------------------------===//
@@ -180,13 +186,13 @@
  
   /// SolveDataflowEquations - Perform the actual worklist algorithm
   ///  to compute dataflow values.
-  void SolveDataflowEquations(CFG& cfg) {
+  void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
     EnqueueFirstBlock(cfg,AnalysisDirTag());
     
     while (!WorkList.isEmpty()) {
       const CFGBlock* B = WorkList.dequeue();
       ProcessMerge(cfg,B);
-      ProcessBlock(B);
+      ProcessBlock(B, recordStmtValues);
       UpdateEdges(cfg,B,TF.getVal());
     }
   }
@@ -228,9 +234,11 @@
   
 
   /// ProcessBlock - Process the transfer functions for a given block.
-  void ProcessBlock(const CFGBlock* B) {
-    for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E; ++I)
+  void ProcessBlock(const CFGBlock* B, bool recordStmtValues) {
+    for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I) {
       TF.BlockStmt_Visit(const_cast<Stmt*>(*I));
+      if (recordStmtValues) D.getStmtDataMap()[*I] = TF.getVal();
+    }      
   }
 
   /// UpdateEdges - After processing the transfer functions for a

Modified: cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h?rev=46137&r1=46136&r2=46137&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h (original)
+++ cfe/trunk/include/clang/Analysis/FlowSensitive/DataflowValues.h Thu Jan 17 12:25:22 2008
@@ -50,6 +50,7 @@
   typedef _AnalysisDirTag                          AnalysisDirTag;
   typedef llvm::DenseMap<ProgramPoint, ValTy>      EdgeDataMapTy;
   typedef llvm::DenseMap<const CFGBlock*, ValTy>   BlockDataMapTy;
+  typedef llvm::DenseMap<const Stmt*, ValTy>       StmtDataMapTy;
 
   //===--------------------------------------------------------------------===//
   // Predicates.
@@ -73,6 +74,9 @@
   //===--------------------------------------------------------------------===//
 
 public:
+  DataflowValues() : StmtDataMap(NULL) {}
+  ~DataflowValues() { delete StmtDataMap; }
+  
   /// InitializeValues - Invoked by the solver to initialize state needed for
   ///  dataflow analysis.  This method is usually specialized by subclasses.
   void InitializeValues(const CFG& cfg) {};  
@@ -102,7 +106,24 @@
   
   const ValTy& getBlockData(const CFGBlock* B) const {
     return const_cast<DataflowValues*>(this)->getBlockData(B);
-  }  
+  }
+  
+  /// getStmtData - Retrieves the dataflow values associated with a 
+  ///  specified Stmt.  If the dataflow analysis is a forward analysis,
+  ///  this data corresponds to the point immediately after a Stmt. 
+  ///  If the analysis is a backwards analysis, it is associated with
+  ///  the point before a Stmt.  This data is only computed for block-level
+  ///  expressions, and only when requested when the analysis is executed.
+  ValTy& getStmtData(const Stmt* S) {
+    assert (StmtDataMap && "Dataflow values were not computed for statements.");
+    typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
+    assert (I != StmtDataMap->end() && "No data associated with statement.");
+    return I->second;
+  }
+  
+  const ValTy& getStmtData(const Stmt* S) const {
+    return const_cast<DataflowValues*>(this)->getStmtData(S);
+  }
   
   /// getEdgeDataMap - Retrieves the internal map between CFG edges and
   ///  dataflow values.  Usually used by a dataflow solver to compute
@@ -117,6 +138,17 @@
   /// to the dataflow values at the end of the block.
   BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
   const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
+  
+  /// getStmtDataMap - Retrieves the internal map between Stmts and
+  /// dataflow values.
+  StmtDataMapTy& getStmtDataMap() {
+    if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
+    return *StmtDataMap;
+  }
+    
+  const StmtDataMapTy& getStmtDataMap() const {
+    return const_cast<DataflowValues*>(this)->getStmtDataMap();
+  }
 
   /// getAnalysisData - Retrieves the meta data associated with a 
   ///  dataflow analysis for analyzing a particular CFG.  
@@ -132,6 +164,7 @@
 protected:
   EdgeDataMapTy      EdgeDataMap;
   BlockDataMapTy     BlockDataMap;
+  StmtDataMapTy*     StmtDataMap;
   AnalysisDataTy     AnalysisData;
 };          
 





More information about the cfe-commits mailing list