[cfe-commits] r46475 - in /cfe/trunk: Analysis/GRConstants.cpp Analysis/GREngine.cpp Driver/ASTConsumers.cpp include/clang/Analysis/Analyses/GRConstants.h include/clang/Analysis/PathSensitive/ExplodedGraph.h include/clang/Analysis/PathSensitive/GREngine.h

Ted Kremenek kremenek at apple.com
Mon Jan 28 16:33:40 PST 2008


Author: kremenek
Date: Mon Jan 28 18:33:40 2008
New Revision: 46475

URL: http://llvm.org/viewvc/llvm-project?rev=46475&view=rev
Log:
Driver now passes the top-level FunctionDecl* to GRConstants.

Refactoring: for GREngine and GRConstants, pushed references to CFG, ASTContext,
and the top-level FunctionDecl into ExplodedGraphImpl.

Modified:
    cfe/trunk/Analysis/GRConstants.cpp
    cfe/trunk/Analysis/GREngine.cpp
    cfe/trunk/Driver/ASTConsumers.cpp
    cfe/trunk/include/clang/Analysis/Analyses/GRConstants.h
    cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h

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

==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Mon Jan 28 18:33:40 2008
@@ -149,7 +149,7 @@
 
   
 class VISIBILITY_HIDDEN ValueManager {
-  ASTContext* Ctx;
+  ASTContext& Ctx;
   
   typedef  llvm::FoldingSet<llvm::FoldingSetNodeWrapper<APSInt> > APSIntSetTy;
   APSIntSetTy APSIntSet;
@@ -157,12 +157,10 @@
   llvm::BumpPtrAllocator BPAlloc;
   
 public:
-  ValueManager() {}
+  ValueManager(ASTContext& ctx) : Ctx(ctx) {}
   ~ValueManager();
   
-  void setContext(ASTContext* ctx) { Ctx = ctx; }
-  ASTContext* getContext() const { return Ctx; }
-  
+  ASTContext& getContext() const { return Ctx; }  
   APSInt& getValue(const APSInt& X);      
 
 };
@@ -385,8 +383,8 @@
     assert (CastExpr->getType()->isIntegerType());
     
     APSInt X(getValue());  
-    X.extOrTrunc(ValMgr.getContext()->getTypeSize(CastExpr->getType(),
-                                                  CastExpr->getLocStart()));
+    X.extOrTrunc(ValMgr.getContext().getTypeSize(CastExpr->getType(),
+                                                 CastExpr->getLocStart()));
     return ValMgr.getValue(X);
   }
   
@@ -547,7 +545,8 @@
 public:
   typedef ValueMapTy StateTy;
   typedef GRNodeBuilder<GRConstants> NodeBuilder;
-  typedef ExplodedNode<StateTy> NodeTy;
+  typedef ExplodedGraph<GRConstants> GraphTy;
+  typedef GraphTy::NodeTy NodeTy;
   
   class NodeSet {
     typedef llvm::SmallVector<NodeTy*,3> ImplTy;
@@ -573,6 +572,9 @@
   };
                                                               
 protected:
+  /// G - the simulation graph.
+  GraphTy& G;
+  
   /// Liveness - live-variables information the ValueDecl* and block-level
   ///  Expr* in the CFG.  Used to prune out dead state.
   LiveVariables* Liveness;
@@ -587,9 +589,6 @@
   /// ValueMgr - Object that manages the data for all created RValues.
   ValueManager ValMgr;
   
-  /// cfg - the current CFG.
-  CFG* cfg;
-  
   /// StmtEntryNode - The immediate predecessor node.
   NodeTy* StmtEntryNode;
   
@@ -598,32 +597,29 @@
   
   bool StateCleaned;
   
-  ASTContext* getContext() const { return ValMgr.getContext(); }
+  ASTContext& getContext() const { return G.getContext(); }
   
 public:
-  GRConstants() : Liveness(NULL), Builder(NULL), cfg(NULL),
-    StmtEntryNode(NULL), CurrentStmt(NULL) {}
+  GRConstants(GraphTy& g) : G(g), Liveness(NULL), Builder(NULL), 
+      ValMgr(G.getContext()), StmtEntryNode(NULL), CurrentStmt(NULL) {
     
-  ~GRConstants() { delete Liveness; }
-  
-  /// getCFG - Returns the CFG associated with this analysis.
-  CFG& getCFG() { assert (cfg); return *cfg; }
-      
-  /// Initialize - Initialize the checker's state based on the specified
-  ///  CFG.  This results in liveness information being computed for
-  ///  each block-level statement in the CFG.
-  void Initialize(CFG& c, ASTContext& ctx) {
-    cfg = &c;
-    ValMgr.setContext(&ctx);
+    // Compute liveness information.
+    CFG& c = G.getCFG();
     Liveness = new LiveVariables(c);
     Liveness->runOnCFG(c);
     Liveness->runOnAllBlocks(c, NULL, true);
   }
+    
+  ~GRConstants() { delete Liveness; }
+  
+  /// getCFG - Returns the CFG associated with this analysis.
+  CFG& getCFG() { return G.getCFG(); }
   
   /// getInitialState - Return the initial state used for the root vertex
   ///  in the ExplodedGraph.
   StateTy getInitialState() {
-    return StateMgr.GetEmptyMap();
+    StateTy St = StateMgr.GetEmptyMap();
+    return St;
   }
 
   /// ProcessStmt - Called by GREngine. Used to generate new successor
@@ -910,7 +906,7 @@
         NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
 
         QualType T = U->getType();
-        unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
+        unsigned bits = getContext().getTypeSize(T, U->getLocStart());
         APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
         NonLValue R2 = NonLValue::GetValue(ValMgr, One);
         
@@ -924,7 +920,7 @@
         NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
         
         QualType T = U->getType();
-        unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
+        unsigned bits = getContext().getTypeSize(T, U->getLocStart());
         APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
         NonLValue R2 = NonLValue::GetValue(ValMgr, One);
         
@@ -938,7 +934,7 @@
         NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
         
         QualType T = U->getType();
-        unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
+        unsigned bits = getContext().getTypeSize(T, U->getLocStart());
         APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
         NonLValue R2 = NonLValue::GetValue(ValMgr, One);        
         
@@ -952,7 +948,7 @@
         NonLValue R1 = cast<NonLValue>(GetValue(St, L1));
         
         QualType T = U->getType();
-        unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
+        unsigned bits = getContext().getTypeSize(T, U->getLocStart());
         APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
         NonLValue R2 = NonLValue::GetValue(ValMgr, One);       
         
@@ -1235,8 +1231,8 @@
 #endif
 
 namespace clang {
-void RunGRConstants(CFG& cfg, ASTContext& Ctx) {
-  GREngine<GRConstants> Engine(cfg, Ctx);
+void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx) {
+  GREngine<GRConstants> Engine(cfg, FD, Ctx);
   Engine.ExecuteWorkList();  
 #ifndef NDEBUG
   llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants");

Modified: cfe/trunk/Analysis/GREngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GREngine.cpp?rev=46475&r1=46474&r2=46475&view=diff

==============================================================================
--- cfe/trunk/Analysis/GREngine.cpp (original)
+++ cfe/trunk/Analysis/GREngine.cpp Mon Jan 28 18:33:40 2008
@@ -56,7 +56,7 @@
   if (G->num_roots() == 0) { // Initialize the analysis by constructing
     // the root if none exists.
     
-    CFGBlock* Entry = &cfg.getEntry();
+    CFGBlock* Entry = &getCFG().getEntry();
     
     assert (Entry->empty() && 
             "Entry block must be empty.");
@@ -69,7 +69,7 @@
     
     // Construct an edge representing the
     // starting location in the function.
-    BlockEdge StartLoc(cfg, Entry, Succ);
+    BlockEdge StartLoc(getCFG(), Entry, Succ);
     
     // Generate the root.
     GenerateNode(StartLoc, getInitialState());
@@ -110,9 +110,10 @@
   CFGBlock* Blk = L.getDst();
   
   // Check if we are entering the EXIT block. 
-  if (Blk == &cfg.getExit()) {
+  if (Blk == &getCFG().getExit()) {
     
-    assert (cfg.getExit().size() == 0 && "EXIT block cannot contain Stmts.");
+    assert (getCFG().getExit().size() == 0 
+            && "EXIT block cannot contain Stmts.");
 
     // Process the final state transition.    
     void* State = ProcessEOP(Blk, Pred->State);
@@ -154,7 +155,7 @@
     assert (B->succ_size() == 1 &&
             "Blocks with no terminator should have at most 1 successor.");
     
-    GenerateNode(BlockEdge(cfg,B,*(B->succ_begin())), Pred->State, Pred);    
+    GenerateNode(BlockEdge(getCFG(),B,*(B->succ_begin())), Pred->State, Pred);    
   }
 }
 

Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=46475&r1=46474&r2=46475&view=diff

==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Mon Jan 28 18:33:40 2008
@@ -566,14 +566,12 @@
 // GRConstants - Perform intra-procedural, path-sensitive constant propagation.
 
 namespace {
-  class GRConstantsVisitor : public CFGVisitor {
+  class GRConstantsVisitor : public ASTConsumer {
     ASTContext* Ctx;
   public:
-    virtual void Initialize(ASTContext &Context) { Ctx = &Context; }
     
-    virtual void VisitCFG(CFG& C) {
-      RunGRConstants(C, *Ctx);
-    }
+    virtual void Initialize(ASTContext &Context) { Ctx = &Context; }    
+    virtual void HandleTopLevelDecl(Decl *D);
   };
 } // end anonymous namespace
 
@@ -581,6 +579,20 @@
   return new GRConstantsVisitor();
 }
 
+void GRConstantsVisitor::HandleTopLevelDecl(Decl *D) {
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+
+  if (!FD || !FD->getBody())
+    return;
+
+  DeclPrinter().PrintFunctionDeclStart(FD);
+  llvm::cerr << '\n';
+  
+  CFG *C = CFG::buildCFG(FD->getBody());
+  RunGRConstants(*C, *FD, *Ctx);
+  delete C;
+}
+
 //===----------------------------------------------------------------------===//
 // LLVM Emitter
 

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/GRConstants.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/GRConstants.h Mon Jan 28 18:33:40 2008
@@ -23,7 +23,7 @@
   ///  on a provided CFG.  This interface will eventually be replaced with
   ///  something more elaborate as the requirements on the interface become
   ///  clearer.
-  void RunGRConstants(CFG& cfg, ASTContext& Ctx);
+  void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx);
   
 } // end clang namespace
 

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h?rev=46475&r1=46474&r2=46475&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ExplodedGraph.h Mon Jan 28 18:33:40 2008
@@ -29,7 +29,11 @@
 class GREngineImpl;
 class ExplodedNodeImpl;
 class GRNodeBuilderImpl;
+class CFG;
+class ASTContext;
+class FunctionDecl;
 
+  
 class ExplodedNodeImpl : public llvm::FoldingSetNode {
 protected:
   friend class ExplodedGraphImpl;
@@ -210,6 +214,15 @@
   
   /// Allocator - BumpPtrAllocator to create nodes.
   llvm::BumpPtrAllocator Allocator;
+  
+  /// cfg - The CFG associated with this analysis graph.
+  CFG& cfg;
+  
+  /// FD - The function declaration of the function being analyzed.
+  FunctionDecl& FD;
+  
+  /// Ctx - The ASTContext used to "interpret" FD.
+  ASTContext& Ctx;
 
   /// getNodeImpl - Retrieve the node associated with a (Location,State)
   ///  pair, where 'State' is represented as an opaque void*.  This method
@@ -228,12 +241,20 @@
     EndNodes.push_back(V);
     return V;
   }
+  
+  // ctor.
+  ExplodedGraphImpl(CFG& c, FunctionDecl& f, ASTContext& ctx)
+    : cfg(c), FD(f), Ctx(ctx) {}
 
 public:
   virtual ~ExplodedGraphImpl();
 
   unsigned num_roots() const { return Roots.size(); }
   unsigned num_eops() const { return EndNodes.size(); }
+  
+  CFG& getCFG() { return cfg; }
+  ASTContext& getContext() { return Ctx; }
+  FunctionDecl& getFunctionDecl() { return FD; }
 };
   
 template <typename CHECKER>
@@ -243,7 +264,7 @@
   typedef typename CHECKER::StateTy   StateTy;
   typedef ExplodedNode<StateTy>       NodeTy;
   
-protected:
+protected:  
   llvm::OwningPtr<CheckerTy> CheckerState;
 
 protected:
@@ -253,7 +274,8 @@
   }
     
 public:
-  ExplodedGraph() : CheckerState(new CheckerTy()) {}
+  ExplodedGraph(CFG& c, FunctionDecl& fd, ASTContext& ctx)
+    : ExplodedGraphImpl(c, fd, ctx), CheckerState(new CheckerTy(*this)) {}
   
   /// getCheckerState - Returns the internal checker state associated
   ///  with the exploded graph.  Ownership remains with the ExplodedGraph

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h?rev=46475&r1=46474&r2=46475&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h Mon Jan 28 18:33:40 2008
@@ -21,8 +21,6 @@
 
 namespace clang {
   
-class CFG;
-class ASTContext;
 class GRNodeBuilderImpl;
 class GRWorkList;
   
@@ -31,9 +29,6 @@
   friend class GRNodeBuilderImpl;
   
   typedef llvm::DenseMap<Stmt*,Stmt*> ParentMapTy;
-
-  /// cfg - The control-flow graph of the function being analyzed.
-  CFG& cfg;
     
   /// G - The simulation graph.  Each node is a (location,state) pair.
   llvm::OwningPtr<ExplodedGraphImpl> G;
@@ -77,8 +72,7 @@
   GREngineImpl& operator=(const GREngineImpl&);
   
 protected:  
-  GREngineImpl(CFG& c, ExplodedGraphImpl* g, GRWorkList* wl)
-   : cfg(c), G(g), WList(wl) {}
+  GREngineImpl(ExplodedGraphImpl* g, GRWorkList* wl) : G(g), WList(wl) {}
   
 public:
   /// ExecuteWorkList - Run the worklist algorithm for a maximum number of
@@ -86,6 +80,8 @@
   bool ExecuteWorkList(unsigned Steps = 1000000);
   
   virtual ~GREngineImpl() {}
+  
+  CFG& getCFG() { return G->getCFG(); }
 };
   
 class GRNodeBuilderImpl {
@@ -108,7 +104,7 @@
   ~GRNodeBuilderImpl();
   
   const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
-
+  
   inline ExplodedNodeImpl* getLastNode() {
     return LastNode ? (LastNode->isInfeasible() ? NULL : LastNode) : NULL;
   }
@@ -170,8 +166,7 @@
 protected:
   // A local reference to the checker that avoids an indirect access
   // via the Graph.
-  CheckerTy* Checker;
-  
+  CheckerTy* Checker;  
   
   virtual void* getInitialState() {
     return GRTrait<StateTy>::toPtr(getCheckerState().getInitialState());
@@ -196,20 +191,16 @@
 public:  
   /// Construct a GREngine object to analyze the provided CFG using
   ///  a DFS exploration of the exploded graph.
-  GREngine(CFG& cfg, ASTContext& Ctx)
-  : GREngineImpl(cfg, new GraphTy(), GRWorkList::MakeDFS()),
-      Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {
-    Checker->Initialize(cfg, Ctx);
-  }
+  GREngine(CFG& cfg, FunctionDecl& fd, ASTContext& ctx)
+    : GREngineImpl(new GraphTy(cfg, fd, ctx), GRWorkList::MakeDFS()),
+      Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {}
   
   /// Construct a GREngine object to analyze the provided CFG and to
   ///  use the provided worklist object to execute the worklist algorithm.
   ///  The GREngine object assumes ownership of 'wlist'.
-  GREngine(CFG& cfg, GRWorkList* wlist) 
-    : GREngineImpl(cfg, new GraphTy(), wlist),
-      Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {
-    Checker->Initialize(cfg);
-  }
+  GREngine(CFG& cfg, FunctionDecl& fd, ASTContext& ctx, GRWorkList* wlist)
+    : GREngineImpl(new GraphTy(cfg, fd, ctx), wlist),
+      Checker(static_cast<GraphTy*>(G.get())->getCheckerState()) {}
   
   virtual ~GREngine() {}
   





More information about the cfe-commits mailing list