[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