[cfe-commits] r47010 - in /cfe/trunk: Analysis/GRBlockCounter.cpp Analysis/GRConstants.cpp Analysis/GREngine.cpp include/clang/Analysis/PathSensitive/GRBlockCounter.h include/clang/Analysis/PathSensitive/GREngine.h include/clang/Analysis/PathSensitive/GRWorkList.h
Ted Kremenek
kremenek at apple.com
Tue Feb 12 10:08:19 PST 2008
Author: kremenek
Date: Tue Feb 12 12:08:17 2008
New Revision: 47010
URL: http://llvm.org/viewvc/llvm-project?rev=47010&view=rev
Log:
Added GRBlockCounter class, which tracks the number of times blocks
have been visited in a path. Added GRBlockCounter as an item to be
enqueued to the worklist.
Modified "ProcessBranch" in GRConstants to prune branches with symbolic
conditions that have been already taken.
Added:
cfe/trunk/Analysis/GRBlockCounter.cpp
cfe/trunk/include/clang/Analysis/PathSensitive/GRBlockCounter.h
Modified:
cfe/trunk/Analysis/GRConstants.cpp
cfe/trunk/Analysis/GREngine.cpp
cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h
cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h
Added: cfe/trunk/Analysis/GRBlockCounter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRBlockCounter.cpp?rev=47010&view=auto
==============================================================================
--- cfe/trunk/Analysis/GRBlockCounter.cpp (added)
+++ cfe/trunk/Analysis/GRBlockCounter.cpp Tue Feb 12 12:08:17 2008
@@ -0,0 +1,54 @@
+//==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines GRBlockCounter, an abstract data type used to count
+// the number of times a given block has been visited along a path
+// analyzed by GREngine.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+#include "llvm/ADT/ImmutableMap.h"
+
+using namespace clang;
+
+typedef llvm::ImmutableMap<unsigned,unsigned> CountMap;
+
+static inline CountMap GetMap(void* D) {
+ return CountMap(static_cast<CountMap::TreeTy*>(D));
+}
+
+static inline CountMap::Factory& GetFactory(void* F) {
+ return *static_cast<CountMap::Factory*>(F);
+}
+
+unsigned GRBlockCounter::getNumVisited(unsigned BlockID) const {
+ CountMap M = GetMap(Data);
+ CountMap::TreeTy* T = M.SlimFind(BlockID);
+ return T ? T->getValue().second : 0;
+}
+
+GRBlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
+ F = new CountMap::Factory(Alloc);
+}
+
+GRBlockCounter::Factory::~Factory() {
+ delete static_cast<CountMap*>(F);
+}
+
+GRBlockCounter
+GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC, unsigned BlockID) {
+ return GRBlockCounter(GetFactory(F).Add(GetMap(BC.Data), BlockID,
+ BC.getNumVisited(BlockID)+1).getRoot());
+}
+
+GRBlockCounter
+GRBlockCounter::Factory::GetEmptyCounter() {
+ return GRBlockCounter(GetFactory(F).GetEmptyMap().getRoot());
+}
Modified: cfe/trunk/Analysis/GRConstants.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRConstants.cpp?rev=47010&r1=47009&r2=47010&view=diff
==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Tue Feb 12 12:08:17 2008
@@ -375,23 +375,45 @@
}
}
- // Process the true branch.
- bool isFeasible = true;
+ // Get the current block counter.
+ GRBlockCounter BC = builder.getBlockCounter();
+
+ unsigned NumVisited = BC.getNumVisited(builder.getTargetBlock(true)->getBlockID());
- StateTy St = Assume(PrevState, V, true, isFeasible);
+ if (isa<nonlval::ConcreteInt>(V) ||
+ BC.getNumVisited(builder.getTargetBlock(true)->getBlockID()) < 1) {
+
+ // Process the true branch.
- if (isFeasible)
- builder.generateNode(St, true);
- else {
- builder.markInfeasible(true);
- isFeasible = true;
+ bool isFeasible = true;
+
+ StateTy St = Assume(PrevState, V, true, isFeasible);
+
+ if (isFeasible)
+ builder.generateNode(St, true);
+ else
+ builder.markInfeasible(true);
}
+ else
+ builder.markInfeasible(true);
- // Process the false branch.
- St = Assume(PrevState, V, false, isFeasible);
+ NumVisited = BC.getNumVisited(builder.getTargetBlock(true)->getBlockID());
+
- if (isFeasible)
- builder.generateNode(St, false);
+ if (isa<nonlval::ConcreteInt>(V) ||
+ BC.getNumVisited(builder.getTargetBlock(false)->getBlockID()) < 1) {
+
+ // Process the false branch.
+
+ bool isFeasible = false;
+
+ StateTy St = Assume(PrevState, V, false, isFeasible);
+
+ if (isFeasible)
+ builder.generateNode(St, false);
+ else
+ builder.markInfeasible(false);
+ }
else
builder.markInfeasible(false);
}
Modified: cfe/trunk/Analysis/GREngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GREngine.cpp?rev=47010&r1=47009&r2=47010&view=diff
==============================================================================
--- cfe/trunk/Analysis/GREngine.cpp (original)
+++ cfe/trunk/Analysis/GREngine.cpp Tue Feb 12 12:08:17 2008
@@ -71,6 +71,9 @@
// starting location in the function.
BlockEdge StartLoc(getCFG(), Entry, Succ);
+ // Set the current block counter to being empty.
+ WList->setBlockCounter(BCounterFactory.GetEmptyCounter());
+
// Generate the root.
GenerateNode(StartLoc, getInitialState());
}
@@ -78,6 +81,11 @@
while (Steps && WList->hasWork()) {
--Steps;
const GRWorkListUnit& WU = WList->Dequeue();
+
+ // Set the current block counter.
+ WList->setBlockCounter(WU.getBlockCounter());
+
+ // Retrieve the node.
ExplodedNodeImpl* Node = WU.getNode();
// Dispatch on the location type.
@@ -138,6 +146,12 @@
void GREngineImpl::HandleBlockEntrance(const BlockEntrance& L,
ExplodedNodeImpl* Pred) {
+ // Increment the block counter.
+ GRBlockCounter Counter = WList->getBlockCounter();
+ Counter = BCounterFactory.IncrementCount(Counter, L.getBlock()->getBlockID());
+ WList->setBlockCounter(Counter);
+
+ // Process the entrance of the block.
if (Stmt* S = L.getFirstStmt()) {
GRStmtNodeBuilderImpl Builder(L.getBlock(), 0, Pred, this);
ProcessStmt(S, Builder);
@@ -196,7 +210,7 @@
ExplodedNodeImpl* Pred) {
assert (B->succ_size() == 2);
- GRBranchNodeBuilderImpl Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
+ GRBranchNodeBuilderImpl Builder(B, *(B->succ_begin()), *(B->succ_begin()+1),
Pred, this);
ProcessBranch(Cond, Term, Builder);
@@ -244,7 +258,7 @@
}
// Only add 'Node' to the worklist if it was freshly generated.
- if (IsNew) WList->Enqueue(GRWorkListUnit(Node));
+ if (IsNew) WList->Enqueue(Node);
}
GRStmtNodeBuilderImpl::GRStmtNodeBuilderImpl(CFGBlock* b, unsigned idx,
@@ -325,5 +339,5 @@
if (!GeneratedFalse) generateNodeImpl(Pred->State, false);
for (DeferredTy::iterator I=Deferred.begin(), E=Deferred.end(); I!=E; ++I)
- if (!(*I)->isSink()) Eng.WList->Enqueue(GRWorkListUnit(*I));
+ if (!(*I)->isSink()) Eng.WList->Enqueue(*I);
}
Added: cfe/trunk/include/clang/Analysis/PathSensitive/GRBlockCounter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRBlockCounter.h?rev=47010&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRBlockCounter.h (added)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRBlockCounter.h Tue Feb 12 12:08:17 2008
@@ -0,0 +1,50 @@
+//==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines GRBlockCounter, an abstract data type used to count
+// the number of times a given block has been visited along a path
+// analyzed by GREngine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
+#define LLVM_CLANG_ANALYSIS_GRBLOCKCOUNTER
+
+namespace llvm {
+ class BumpPtrAllocator;
+}
+
+namespace clang {
+
+class GRBlockCounter {
+ void* Data;
+
+ GRBlockCounter(void* D) : Data(D) {}
+
+public:
+ GRBlockCounter() : Data(0) {}
+
+ unsigned getNumVisited(unsigned BlockID) const;
+
+ class Factory {
+ void* F;
+ public:
+ Factory(llvm::BumpPtrAllocator& Alloc);
+ ~Factory();
+
+ GRBlockCounter GetEmptyCounter();
+ GRBlockCounter IncrementCount(GRBlockCounter BC, unsigned BlockID);
+ };
+
+ friend class Factory;
+};
+
+} // end clang namespace
+
+#endif
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=47010&r1=47009&r2=47010&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GREngine.h Tue Feb 12 12:08:17 2008
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines a generic engine for intraprocedural, path-sensitive,
-// dataflow analysis via graph reachability engine.
+// dataflow analysis via graph reachability.
//
//===----------------------------------------------------------------------===//
@@ -17,6 +17,7 @@
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
#include "clang/Analysis/PathSensitive/GRWorkList.h"
+#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
#include "llvm/ADT/OwningPtr.h"
namespace clang {
@@ -47,7 +48,12 @@
/// the order that nodes are processed.
GRWorkList* WList;
- void GenerateNode(const ProgramPoint& Loc, void* State,
+ /// BCounterFactory - A factory object for created GRBlockCounter objects.
+ /// These are used to record for key nodes in the ExplodedGraph the
+ /// number of times different CFGBlocks have been visited along a path.
+ GRBlockCounter::Factory BCounterFactory;
+
+ void GenerateNode(const ProgramPoint& Loc, void* State,
ExplodedNodeImpl* Pred = NULL);
/// getInitialState - Gets the void* representing the initial 'state'
@@ -78,7 +84,8 @@
GREngineImpl& operator=(const GREngineImpl&);
protected:
- GREngineImpl(ExplodedGraphImpl* g, GRWorkList* wl) : G(g), WList(wl) {}
+ GREngineImpl(ExplodedGraphImpl* g, GRWorkList* wl)
+ : G(g), WList(wl), BCounterFactory(g->getAllocator()) {}
public:
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of
@@ -183,8 +190,13 @@
ExplodedNodeImpl* getPredecessor() const { return Pred; }
const ExplodedGraphImpl& getGraph() const { return *Eng.G; }
+ GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
- ExplodedNodeImpl* generateNodeImpl(void* State, bool branch);
+ ExplodedNodeImpl* generateNodeImpl(void* State, bool branch);
+
+ CFGBlock* getTargetBlock(bool branch) const {
+ return branch ? DstT : DstF;
+ }
void markInfeasible(bool branch) {
if (branch) GeneratedTrue = true;
@@ -221,6 +233,14 @@
return static_cast<NodeTy*>(NB.generateNodeImpl(state, branch));
}
+ GRBlockCounter getBlockCounter() const {
+ return NB.getBlockCounter();
+ }
+
+ CFGBlock* getTargetBlock(bool branch) const {
+ return NB.getTargetBlock(branch);
+ }
+
inline void markInfeasible(bool branch) {
NB.markInfeasible(branch);
}
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h?rev=47010&r1=47009&r2=47010&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h Tue Feb 12 12:08:17 2008
@@ -15,39 +15,59 @@
#ifndef LLVM_CLANG_ANALYSIS_GRWORKLIST
#define LLVM_CLANG_ANALYSIS_GRWORKLIST
+#include "clang/Analysis/PathSensitive/GRBlockCounter.h"
+
namespace clang {
class ExplodedNodeImpl;
class GRWorkListUnit {
ExplodedNodeImpl* Node;
+ GRBlockCounter Counter;
CFGBlock* Block;
unsigned BlockIdx;
public:
- GRWorkListUnit(ExplodedNodeImpl* N, CFGBlock* B, unsigned idx)
- : Node(N), Block(B), BlockIdx(idx) {}
-
- explicit GRWorkListUnit(ExplodedNodeImpl* N)
- : Node(N), Block(NULL), BlockIdx(0) {}
-
- ExplodedNodeImpl* getNode() const { return Node; }
- CFGBlock* getBlock() const { return Block; }
- unsigned getIndex() const { return BlockIdx; }
+ GRWorkListUnit(ExplodedNodeImpl* N, GRBlockCounter C,
+ CFGBlock* B, unsigned idx)
+ : Node(N),
+ Counter(C),
+ Block(B),
+ BlockIdx(idx) {}
+
+ explicit GRWorkListUnit(ExplodedNodeImpl* N, GRBlockCounter C)
+ : Node(N),
+ Counter(C),
+ Block(NULL),
+ BlockIdx(0) {}
+
+ ExplodedNodeImpl* getNode() const { return Node; }
+ GRBlockCounter getBlockCounter() const { return Counter; }
+ CFGBlock* getBlock() const { return Block; }
+ unsigned getIndex() const { return BlockIdx; }
};
class GRWorkList {
+ GRBlockCounter CurrentCounter;
public:
virtual ~GRWorkList();
virtual bool hasWork() const = 0;
+
virtual void Enqueue(const GRWorkListUnit& U) = 0;
- void Enqueue(ExplodedNodeImpl* N, CFGBlock& B, unsigned idx) {
- Enqueue(GRWorkListUnit(N,&B,idx));
+ void Enqueue(ExplodedNodeImpl* N, CFGBlock& B, unsigned idx) {
+ Enqueue(GRWorkListUnit(N, CurrentCounter, &B, idx));
+ }
+
+ void Enqueue(ExplodedNodeImpl* N) {
+ Enqueue(GRWorkListUnit(N, CurrentCounter));
}
virtual GRWorkListUnit Dequeue() = 0;
+ void setBlockCounter(GRBlockCounter C) { CurrentCounter = C; }
+ GRBlockCounter getBlockCounter() const { return CurrentCounter; }
+
static GRWorkList* MakeDFS();
};
} // end clang namespace
More information about the cfe-commits
mailing list