From: Zhongxing Xu Date: Thu, 6 Aug 2009 06:28:40 +0000 (+0000) Subject: Core analysis engine template cleanup step 2: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=38b02b912e1a55c912f603c4369431264d36a381;p=clang Core analysis engine template cleanup step 2: merge ExplodedGraphImpl and ExplodedGraph. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78291 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index a414208269..70eb1da8f2 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -358,15 +358,15 @@ public: /// getEngine - Return the analysis engine used to analyze a given /// function or method. - GRExprEngine& getEngine() { return Eng; } + GRExprEngine &getEngine() { return Eng; } /// getGraph - Get the exploded graph created by the analysis engine /// for the analyzed method or function. - ExplodedGraph& getGraph(); + ExplodedGraph &getGraph(); /// getStateManager - Return the state manager used by the analysis /// engine. - GRStateManager& getStateManager(); + GRStateManager &getStateManager(); virtual void GeneratePathDiagnostic(PathDiagnostic& PD, BugReportEquivClass& R); @@ -402,7 +402,7 @@ public: GRBugReporter& getBugReporter() { return BR; } - ExplodedGraph& getGraph() { return BR.getGraph(); } + ExplodedGraph &getGraph() { return BR.getGraph(); } void addNotableSymbol(SymbolRef Sym) { // FIXME: For now forward to GRBugReporter. diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h index 73cfd9cce6..9f11cc9a0a 100644 --- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h +++ b/include/clang/Analysis/PathSensitive/ExplodedGraph.h @@ -48,7 +48,7 @@ class GREndPathNodebuilderImpl; class ExplodedNode : public llvm::FoldingSetNode { protected: - friend class ExplodedGraphImpl; + friend class ExplodedGraph; friend class GRCoreEngineImpl; friend class GRStmtNodeBuilderImpl; friend class GRBranchNodeBuilderImpl; @@ -192,17 +192,19 @@ public: static void SetAuditor(Auditor* A); }; +// FIXME: Is this class necessary? +class InterExplodedGraphMap { + llvm::DenseMap M; + friend class ExplodedGraph; -template -struct GRTrait { - static inline void Profile(llvm::FoldingSetNodeID& ID, const StateTy* St) { - St->Profile(ID); - } +public: + ExplodedNode* getMappedNode(const ExplodedNode* N) const; + + InterExplodedGraphMap() {}; + virtual ~InterExplodedGraphMap() {} }; -class InterExplodedGraphMapImpl; - -class ExplodedGraphImpl { +class ExplodedGraph { protected: friend class GRCoreEngineImpl; friend class GRStmtNodeBuilderImpl; @@ -224,7 +226,10 @@ protected: /// EndNodes - The nodes in the simulation graph which have been /// specially marked as the endpoint of an abstract simulation path. EndNodesTy EndNodes; - + + /// Nodes - The nodes in the graph. + llvm::FoldingSet Nodes; + /// Allocator - BumpPtrAllocator to create nodes. llvm::BumpPtrAllocator Allocator; @@ -241,14 +246,18 @@ protected: /// NumNodes - The number of nodes in the graph. unsigned NumNodes; - /// getNodeImpl - Retrieve the node associated with a (Location,State) - /// pair, where 'State' is represented as an opaque void*. This method - /// is intended to be used only by GRCoreEngineImpl. - virtual ExplodedNode* getNodeImpl(const ProgramPoint& L, - const void* State, - bool* IsNew) = 0; +public: + /// getNode - Retrieve the node associated with a (Location,State) pair, + /// where the 'Location' is a ProgramPoint in the CFG. If no node for + /// this pair exists, it is created. IsNew is set to true if + /// the node was freshly created. + + ExplodedNode* getNode(const ProgramPoint& L, const GRState *State, + bool* IsNew = 0); - virtual ExplodedGraphImpl* MakeEmptyGraph() const = 0; + ExplodedGraph* MakeEmptyGraph() const { + return new ExplodedGraph(cfg, CodeDecl, Ctx); + } /// addRoot - Add an untyped node to the set of roots. ExplodedNode* addRoot(ExplodedNode* V) { @@ -261,203 +270,73 @@ protected: EndNodes.push_back(V); return V; } - - // ctor. - ExplodedGraphImpl(CFG& c, Decl& cd, ASTContext& ctx) + + ExplodedGraph(CFG& c, Decl& cd, ASTContext& ctx) : cfg(c), CodeDecl(cd), Ctx(ctx), NumNodes(0) {} -public: - virtual ~ExplodedGraphImpl() {} + virtual ~ExplodedGraph() {} unsigned num_roots() const { return Roots.size(); } unsigned num_eops() const { return EndNodes.size(); } bool empty() const { return NumNodes == 0; } unsigned size() const { return NumNodes; } - - llvm::BumpPtrAllocator& getAllocator() { return Allocator; } - CFG& getCFG() { return cfg; } - ASTContext& getContext() { return Ctx; } - - Decl& getCodeDecl() { return CodeDecl; } - const Decl& getCodeDecl() const { return CodeDecl; } - - const FunctionDecl* getFunctionDecl() const { - return llvm::dyn_cast(&CodeDecl); - } - - typedef llvm::DenseMap NodeMap; - - ExplodedGraphImpl* Trim(const ExplodedNode* const * NBeg, - const ExplodedNode* const * NEnd, - InterExplodedGraphMapImpl *M, - llvm::DenseMap *InverseMap) const; -}; - -class InterExplodedGraphMapImpl { - llvm::DenseMap M; - friend class ExplodedGraphImpl; - void add(const ExplodedNode* From, ExplodedNode* To); - -protected: - ExplodedNode* getMappedImplNode(const ExplodedNode* N) const; - - InterExplodedGraphMapImpl(); -public: - virtual ~InterExplodedGraphMapImpl() {} -}; - -//===----------------------------------------------------------------------===// -// Type-specialized ExplodedGraph classes. -//===----------------------------------------------------------------------===// - -class InterExplodedGraphMap : public InterExplodedGraphMapImpl { -public: - InterExplodedGraphMap() {}; - ~InterExplodedGraphMap() {}; - - ExplodedNode* getMappedNode(const ExplodedNode* N) const { - return static_cast(getMappedImplNode(N)); - } -}; - -template -class ExplodedGraph : public ExplodedGraphImpl { -public: - typedef STATE StateTy; - typedef ExplodedNode NodeTy; - typedef llvm::FoldingSet AllNodesTy; - -protected: - virtual ExplodedNode* getNodeImpl(const ProgramPoint& L, - const void* State, - bool* IsNew) { - - return getNode(L, static_cast(State), IsNew); - } - /// Nodes - The nodes in the graph. - AllNodesTy Nodes; - -protected: - virtual ExplodedGraphImpl* MakeEmptyGraph() const { - return new ExplodedGraph(cfg, CodeDecl, Ctx); - } - -public: - ExplodedGraph(CFG& c, Decl& cd, ASTContext& ctx) - : ExplodedGraphImpl(c, cd, ctx) {} - - /// getNode - Retrieve the node associated with a (Location,State) pair, - /// where the 'Location' is a ProgramPoint in the CFG. If no node for - /// this pair exists, it is created. IsNew is set to true if - /// the node was freshly created. - NodeTy* getNode(const ProgramPoint& L, const GRState* State, - bool* IsNew = NULL) { - - // Profile 'State' to determine if we already have an existing node. - llvm::FoldingSetNodeID profile; - void* InsertPos = 0; - - NodeTy::Profile(profile, L, State); - NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos); - - if (!V) { - // Allocate a new node. - V = (NodeTy*) Allocator.Allocate(); - new (V) NodeTy(L, State); - - // Insert the node into the node set and return it. - Nodes.InsertNode(V, InsertPos); - - ++NumNodes; - - if (IsNew) *IsNew = true; - } - else - if (IsNew) *IsNew = false; - - return V; - } - // Iterators. + typedef ExplodedNode NodeTy; + typedef llvm::FoldingSet AllNodesTy; typedef NodeTy** roots_iterator; - typedef const NodeTy** const_roots_iterator; + typedef NodeTy* const * const_roots_iterator; typedef NodeTy** eop_iterator; - typedef const NodeTy** const_eop_iterator; - typedef typename AllNodesTy::iterator node_iterator; - typedef typename AllNodesTy::const_iterator const_node_iterator; + typedef NodeTy* const * const_eop_iterator; + typedef AllNodesTy::iterator node_iterator; + typedef AllNodesTy::const_iterator const_node_iterator; - node_iterator nodes_begin() { - return Nodes.begin(); - } + node_iterator nodes_begin() { return Nodes.begin(); } - node_iterator nodes_end() { - return Nodes.end(); - } + node_iterator nodes_end() { return Nodes.end(); } - const_node_iterator nodes_begin() const { - return Nodes.begin(); - } + const_node_iterator nodes_begin() const { return Nodes.begin(); } - const_node_iterator nodes_end() const { - return Nodes.end(); - } + const_node_iterator nodes_end() const { return Nodes.end(); } - roots_iterator roots_begin() { - return reinterpret_cast(Roots.begin()); - } + roots_iterator roots_begin() { return Roots.begin(); } - roots_iterator roots_end() { - return reinterpret_cast(Roots.end()); - } + roots_iterator roots_end() { return Roots.end(); } - const_roots_iterator roots_begin() const { - return const_cast(this)->roots_begin(); - } + const_roots_iterator roots_begin() const { return Roots.begin(); } - const_roots_iterator roots_end() const { - return const_cast(this)->roots_end(); - } + const_roots_iterator roots_end() const { return Roots.end(); } - eop_iterator eop_begin() { - return reinterpret_cast(EndNodes.begin()); - } + eop_iterator eop_begin() { return EndNodes.begin(); } - eop_iterator eop_end() { - return reinterpret_cast(EndNodes.end()); - } + eop_iterator eop_end() { return EndNodes.end(); } - const_eop_iterator eop_begin() const { - return const_cast(this)->eop_begin(); - } + const_eop_iterator eop_begin() const { return EndNodes.begin(); } - const_eop_iterator eop_end() const { - return const_cast(this)->eop_end(); + const_eop_iterator eop_end() const { return EndNodes.end(); } + + llvm::BumpPtrAllocator& getAllocator() { return Allocator; } + CFG& getCFG() { return cfg; } + ASTContext& getContext() { return Ctx; } + + Decl& getCodeDecl() { return CodeDecl; } + const Decl& getCodeDecl() const { return CodeDecl; } + + const FunctionDecl* getFunctionDecl() const { + return llvm::dyn_cast(&CodeDecl); } + typedef llvm::DenseMap NodeMap; + std::pair Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd, - llvm::DenseMap *InverseMap = 0) const { - - if (NBeg == NEnd) - return std::make_pair((ExplodedGraph*) 0, - (InterExplodedGraphMap*) 0); - - assert (NBeg < NEnd); - - const ExplodedNode* const* NBegImpl = - (const ExplodedNode* const*) NBeg; - const ExplodedNode* const* NEndImpl = - (const ExplodedNode* const*) NEnd; - - llvm::OwningPtr M(new InterExplodedGraphMap()); + llvm::DenseMap *InverseMap = 0) const; - ExplodedGraphImpl* G = ExplodedGraphImpl::Trim(NBegImpl, NEndImpl, M.get(), - InverseMap); - - return std::make_pair(static_cast(G), M.take()); - } + ExplodedGraph* TrimInternal(const ExplodedNode* const * NBeg, + const ExplodedNode* const * NEnd, + InterExplodedGraphMap *M, + llvm::DenseMap *InverseMap) const; }; class ExplodedNodeSet { diff --git a/include/clang/Analysis/PathSensitive/GRCoreEngine.h b/include/clang/Analysis/PathSensitive/GRCoreEngine.h index a8c741f748..df49f9b914 100644 --- a/include/clang/Analysis/PathSensitive/GRCoreEngine.h +++ b/include/clang/Analysis/PathSensitive/GRCoreEngine.h @@ -49,7 +49,7 @@ protected: friend class GREndPathNodeBuilderImpl; /// G - The simulation graph. Each node is a (location,state) pair. - llvm::OwningPtr G; + llvm::OwningPtr G; /// WList - A set of queued nodes that need to be processed by the /// worklist algorithm. It is up to the implementation of WList to decide @@ -61,14 +61,14 @@ protected: /// number of times different CFGBlocks have been visited along a path. GRBlockCounter::Factory BCounterFactory; - void GenerateNode(const ProgramPoint& Loc, const void* State, + void GenerateNode(const ProgramPoint& Loc, const GRState* State, ExplodedNode* Pred); /// getInitialState - Gets the void* representing the initial 'state' /// of the analysis. This is simply a wrapper (implemented /// in GRCoreEngine) that performs type erasure on the initial /// state returned by the checker object. - virtual const void* getInitialState() = 0; + virtual const GRState* getInitialState() = 0; void HandleBlockEdge(const BlockEdge& E, ExplodedNode* Pred); void HandleBlockEntrance(const BlockEntrance& E, ExplodedNode* Pred); @@ -98,7 +98,7 @@ private: GRCoreEngineImpl& operator=(const GRCoreEngineImpl&); protected: - GRCoreEngineImpl(ExplodedGraphImpl* g, GRWorkList* wl) + GRCoreEngineImpl(ExplodedGraph* g, GRWorkList* wl) : G(g), WList(wl), BCounterFactory(g->getAllocator()) {} public: @@ -142,16 +142,16 @@ public: } ExplodedNode* - generateNodeImpl(const ProgramPoint &PP, const void* State, + generateNodeImpl(const ProgramPoint &PP, const GRState* State, ExplodedNode* Pred); ExplodedNode* - generateNodeImpl(const Stmt* S, const void* State, ExplodedNode* Pred, + generateNodeImpl(const Stmt* S, const GRState* State, ExplodedNode* Pred, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, const void *tag = 0); ExplodedNode* - generateNodeImpl(const Stmt* S, const void* State, + generateNodeImpl(const Stmt* S, const GRState* State, ProgramPoint::Kind K = ProgramPoint::PostStmtKind, const void *tag = 0) { ExplodedNode* N = getLastNode(); @@ -160,7 +160,7 @@ public: } ExplodedNode* - generateNodeImpl(const Stmt* S, const void* State, const void *tag = 0) { + generateNodeImpl(const Stmt* S, const GRState* State, const void *tag = 0) { ExplodedNode* N = getLastNode(); assert (N && "Predecessor of new node is infeasible."); return generateNodeImpl(S, State, N, ProgramPoint::PostStmtKind, tag); @@ -325,10 +325,10 @@ public: ~GRBranchNodeBuilderImpl(); ExplodedNode* getPredecessor() const { return Pred; } - const ExplodedGraphImpl& getGraph() const { return *Eng.G; } + const ExplodedGraph& getGraph() const { return *Eng.G; } GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();} - ExplodedNode* generateNodeImpl(const void* State, bool branch); + ExplodedNode* generateNodeImpl(const GRState* State, bool branch); CFGBlock* getTargetBlock(bool branch) const { return branch ? DstT : DstF; @@ -349,7 +349,7 @@ public: template class GRBranchNodeBuilder { typedef STATE StateTy; - typedef ExplodedGraph GraphTy; + typedef ExplodedGraph GraphTy; typedef typename GraphTy::NodeTy NodeTy; GRBranchNodeBuilderImpl& NB; @@ -425,7 +425,7 @@ public: Iterator begin() { return Iterator(DispatchBlock.succ_begin()); } Iterator end() { return Iterator(DispatchBlock.succ_end()); } - ExplodedNode* generateNodeImpl(const Iterator& I, const void* State, + ExplodedNode* generateNodeImpl(const Iterator& I, const GRState* State, bool isSink); Expr* getTarget() const { return E; } @@ -435,7 +435,7 @@ public: template class GRIndirectGotoNodeBuilder { typedef STATE StateTy; - typedef ExplodedGraph GraphTy; + typedef ExplodedGraph GraphTy; typedef typename GraphTy::NodeTy NodeTy; GRIndirectGotoNodeBuilderImpl& NB; @@ -492,9 +492,9 @@ public: Iterator end() { return Iterator(Src->succ_rend()); } ExplodedNode* generateCaseStmtNodeImpl(const Iterator& I, - const void* State); + const GRState* State); - ExplodedNode* generateDefaultCaseNodeImpl(const void* State, + ExplodedNode* generateDefaultCaseNodeImpl(const GRState* State, bool isSink); Expr* getCondition() const { return Condition; } @@ -504,7 +504,7 @@ public: template class GRSwitchNodeBuilder { typedef STATE StateTy; - typedef ExplodedGraph GraphTy; + typedef ExplodedGraph GraphTy; typedef typename GraphTy::NodeTy NodeTy; GRSwitchNodeBuilderImpl& NB; @@ -554,7 +554,7 @@ public: return getBlockCounter().getNumVisited(B.getBlockID()); } - ExplodedNode* generateNodeImpl(const void* State, + ExplodedNode* generateNodeImpl(const GRState* State, const void *tag = 0, ExplodedNode *P = 0); @@ -604,13 +604,13 @@ public: typedef SUBENGINE SubEngineTy; typedef typename SubEngineTy::StateTy StateTy; typedef typename StateTy::ManagerTy StateManagerTy; - typedef ExplodedGraph GraphTy; + typedef ExplodedGraph GraphTy; typedef typename GraphTy::NodeTy NodeTy; protected: SubEngineTy& SubEngine; - virtual const void* getInitialState() { + virtual const GRState* getInitialState() { return SubEngine.getInitialState(); } diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 53456ca287..d3a50b0d36 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -34,8 +34,8 @@ namespace clang { class GRExprEngine { public: typedef GRState StateTy; - typedef ExplodedGraph GraphTy; - typedef GraphTy::NodeTy NodeTy; + typedef ExplodedGraph GraphTy; + typedef GraphTy::NodeTy NodeTy; // Builders. typedef GRStmtNodeBuilder StmtNodeBuilder; diff --git a/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h b/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h index e54b31dfe8..9de8624caf 100644 --- a/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h +++ b/include/clang/Analysis/PathSensitive/GRSimpleAPICheck.h @@ -26,7 +26,7 @@ class BugReporter; class ASTContext; class GRExprEngine; class PathDiagnosticClient; -template class ExplodedGraph; +class ExplodedGraph; class GRSimpleAPICheck : public GRAuditor { diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index f60b866d65..c31e1fc608 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -349,17 +349,6 @@ public: }; }; -template<> struct GRTrait { - static inline void* toPtr(GRState* St) { return (void*) St; } - static inline GRState* toState(void* P) { return (GRState*) P; } - static inline void Profile(llvm::FoldingSetNodeID& profile, GRState* St) { - // At this point states have already been uniqued. Just - // add the pointer. - profile.AddPointer(St); - } -}; - - class GRStateSet { typedef llvm::SmallPtrSet ImplTy; ImplTy Impl; @@ -468,7 +457,7 @@ public: const GRState *getInitialState(); ASTContext &getContext() { return ValueMgr.getContext(); } - const ASTContext &getContext() const { return ValueMgr.getContext(); } + const ASTContext &getContext() const { return ValueMgr.getContext(); } const Decl &getCodeDecl() { return codedecl; } GRTransferFuncs& getTransferFuncs() { return *TF; } diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 19a031a1ae..af4fd384e8 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -1286,8 +1286,7 @@ BugReportEquivClass::~BugReportEquivClass() { GRBugReporter::~GRBugReporter() { FlushReports(); } BugReporterData::~BugReporterData() {} -ExplodedGraph& -GRBugReporter::getGraph() { return Eng.getGraph(); } +ExplodedGraph &GRBugReporter::getGraph() { return Eng.getGraph(); } GRStateManager& GRBugReporter::getStateManager() { return Eng.getStateManager(); } @@ -1332,9 +1331,9 @@ void BugReporter::FlushReports() { // PathDiagnostics generation. //===----------------------------------------------------------------------===// -static std::pair*, NodeBackMap*>, +static std::pair, std::pair > -MakeReportGraph(const ExplodedGraph* G, +MakeReportGraph(const ExplodedGraph* G, const ExplodedNode** NStart, const ExplodedNode** NEnd) { @@ -1342,7 +1341,7 @@ MakeReportGraph(const ExplodedGraph* G, // error nodes to the root. In the new graph we should only have one // error node unless there are two or more error nodes with the same minimum // path length. - ExplodedGraph* GTrim; + ExplodedGraph* GTrim; InterExplodedGraphMap* NMap; llvm::DenseMap InverseMap; @@ -1350,7 +1349,7 @@ MakeReportGraph(const ExplodedGraph* G, // Create owning pointers for GTrim and NMap just to ensure that they are // released when this function exists. - llvm::OwningPtr > AutoReleaseGTrim(GTrim); + llvm::OwningPtr AutoReleaseGTrim(GTrim); llvm::OwningPtr AutoReleaseNMap(NMap); // Find the (first) error node in the trimmed graph. We just need to consult @@ -1358,7 +1357,7 @@ MakeReportGraph(const ExplodedGraph* G, // in the new graph. std::queue WS; - typedef llvm::DenseMap IndexMapTy; + typedef llvm::DenseMap IndexMapTy; IndexMapTy IndexMap; for (const ExplodedNode** I = NStart; I != NEnd; ++I) @@ -1372,9 +1371,8 @@ MakeReportGraph(const ExplodedGraph* G, // Create a new (third!) graph with a single path. This is the graph // that will be returned to the caller. - ExplodedGraph *GNew = - new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(), - GTrim->getContext()); + ExplodedGraph *GNew = new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(), + GTrim->getContext()); // Sometimes the trimmed graph can contain a cycle. Perform a reverse BFS // to the root node, and then construct a new graph that contains only @@ -1418,8 +1416,7 @@ MakeReportGraph(const ExplodedGraph* G, // Create the equivalent node in the new graph with the same state // and location. - ExplodedNode* NewN = - GNew->getNode(N->getLocation(), N->getState()); + ExplodedNode* NewN = GNew->getNode(N->getLocation(), N->getState()); // Store the mapping to the original node. llvm::DenseMap::iterator IMitr=InverseMap.find(N); @@ -1576,7 +1573,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, // Construct a new graph that contains only a single path from the error // node to a root. - const std::pair*, NodeBackMap*>, + const std::pair, std::pair >& GPair = MakeReportGraph(&getGraph(), &Nodes[0], &Nodes[0] + Nodes.size()); @@ -1588,7 +1585,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, assert(R && "No original report found for sliced graph."); - llvm::OwningPtr > ReportGraph(GPair.first.first); + llvm::OwningPtr ReportGraph(GPair.first.first); llvm::OwningPtr BackMap(GPair.first.second); const ExplodedNode *N = GPair.second.first; diff --git a/lib/Analysis/ExplodedGraph.cpp b/lib/Analysis/ExplodedGraph.cpp index f80aa113e4..88bb120f5d 100644 --- a/lib/Analysis/ExplodedGraph.cpp +++ b/lib/Analysis/ExplodedGraph.cpp @@ -127,13 +127,56 @@ ExplodedNode::NodeGroup::~NodeGroup() { if (getKind() == SizeOther) delete &getVector(getPtr()); } -ExplodedGraphImpl* -ExplodedGraphImpl::Trim(const ExplodedNode* const* BeginSources, - const ExplodedNode* const* EndSources, - InterExplodedGraphMapImpl* M, - llvm::DenseMap *InverseMap) -const { +ExplodedNode *ExplodedGraph::getNode(const ProgramPoint& L, + const GRState* State, bool* IsNew) { + // Profile 'State' to determine if we already have an existing node. + llvm::FoldingSetNodeID profile; + void* InsertPos = 0; + NodeTy::Profile(profile, L, State); + NodeTy* V = Nodes.FindNodeOrInsertPos(profile, InsertPos); + + if (!V) { + // Allocate a new node. + V = (NodeTy*) Allocator.Allocate(); + new (V) NodeTy(L, State); + + // Insert the node into the node set and return it. + Nodes.InsertNode(V, InsertPos); + + ++NumNodes; + + if (IsNew) *IsNew = true; + } + else + if (IsNew) *IsNew = false; + + return V; +} + +std::pair +ExplodedGraph::Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd, + llvm::DenseMap *InverseMap) const { + + if (NBeg == NEnd) + return std::make_pair((ExplodedGraph*) 0, + (InterExplodedGraphMap*) 0); + + assert (NBeg < NEnd); + + llvm::OwningPtr M(new InterExplodedGraphMap()); + + ExplodedGraph* G = TrimInternal(NBeg, NEnd, M.get(), InverseMap); + + return std::make_pair(static_cast(G), M.take()); +} + +ExplodedGraph* +ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources, + const ExplodedNode* const* EndSources, + InterExplodedGraphMap* M, + llvm::DenseMap *InverseMap) const { + typedef llvm::DenseSet Pass1Ty; Pass1Ty Pass1; @@ -177,7 +220,7 @@ const { return 0; // Create an empty graph. - ExplodedGraphImpl* G = MakeEmptyGraph(); + ExplodedGraph* G = MakeEmptyGraph(); // ===- Pass 2 (forward DFS to construct the new graph) -=== while (!WL2.empty()) { @@ -190,7 +233,7 @@ const { // Create the corresponding node in the new graph and record the mapping // from the old node to the new node. - ExplodedNode* NewN = G->getNodeImpl(N->getLocation(), N->State, NULL); + ExplodedNode* NewN = G->getNode(N->getLocation(), N->State, NULL); Pass2[N] = NewN; // Also record the reverse mapping from the new node to the old node. @@ -238,12 +281,10 @@ const { } ExplodedNode* -InterExplodedGraphMapImpl::getMappedImplNode(const ExplodedNode* N) const { +InterExplodedGraphMap::getMappedNode(const ExplodedNode* N) const { llvm::DenseMap::iterator I = M.find(N); return I == M.end() ? 0 : I->second; } -InterExplodedGraphMapImpl::InterExplodedGraphMapImpl() {} - diff --git a/lib/Analysis/GRCoreEngine.cpp b/lib/Analysis/GRCoreEngine.cpp index e0b53a8a7f..492b4fe336 100644 --- a/lib/Analysis/GRCoreEngine.cpp +++ b/lib/Analysis/GRCoreEngine.cpp @@ -341,11 +341,11 @@ void GRCoreEngineImpl::HandlePostStmt(const PostStmt& L, CFGBlock* B, /// GenerateNode - Utility method to generate nodes, hook up successors, /// and add nodes to the worklist. -void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, const void* State, - ExplodedNode* Pred) { +void GRCoreEngineImpl::GenerateNode(const ProgramPoint& Loc, + const GRState* State, ExplodedNode* Pred) { bool IsNew; - ExplodedNode* Node = G->getNodeImpl(Loc, State, &IsNew); + ExplodedNode* Node = G->getNode(Loc, State, &IsNew); if (Pred) Node->addPredecessor(Pred); // Link 'Node' with its predecessor. @@ -383,7 +383,7 @@ void GRStmtNodeBuilderImpl::GenerateAutoTransition(ExplodedNode* N) { } bool IsNew; - ExplodedNode* Succ = Eng.G->getNodeImpl(Loc, N->State, &IsNew); + ExplodedNode* Succ = Eng.G->getNode(Loc, N->State, &IsNew); Succ->addPredecessor(N); if (IsNew) @@ -426,7 +426,7 @@ static inline PostStmt GetPostLoc(const Stmt* S, ProgramPoint::Kind K, } ExplodedNode* -GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State, +GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const GRState* State, ExplodedNode* Pred, ProgramPoint::Kind K, const void *tag) { @@ -437,10 +437,10 @@ GRStmtNodeBuilderImpl::generateNodeImpl(const Stmt* S, const void* State, ExplodedNode* GRStmtNodeBuilderImpl::generateNodeImpl(const ProgramPoint &Loc, - const void* State, + const GRState* State, ExplodedNode* Pred) { bool IsNew; - ExplodedNode* N = Eng.G->getNodeImpl(Loc, State, &IsNew); + ExplodedNode* N = Eng.G->getNode(Loc, State, &IsNew); N->addPredecessor(Pred); Deferred.erase(Pred); @@ -454,8 +454,8 @@ GRStmtNodeBuilderImpl::generateNodeImpl(const ProgramPoint &Loc, return NULL; } -ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State, - bool branch) { +ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const GRState* State, + bool branch) { // If the branch has been marked infeasible we should not generate a node. if (!isFeasible(branch)) @@ -464,7 +464,7 @@ ExplodedNode* GRBranchNodeBuilderImpl::generateNodeImpl(const void* State, bool IsNew; ExplodedNode* Succ = - Eng.G->getNodeImpl(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew); + Eng.G->getNode(BlockEdge(Src, branch ? DstT : DstF), State, &IsNew); Succ->addPredecessor(Pred); @@ -492,12 +492,12 @@ GRBranchNodeBuilderImpl::~GRBranchNodeBuilderImpl() { ExplodedNode* GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I, - const void* St, + const GRState* St, bool isSink) { bool IsNew; ExplodedNode* Succ = - Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()), St, &IsNew); + Eng.G->getNode(BlockEdge(Src, I.getBlock()), St, &IsNew); Succ->addPredecessor(Pred); @@ -517,11 +517,11 @@ GRIndirectGotoNodeBuilderImpl::generateNodeImpl(const Iterator& I, ExplodedNode* GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, - const void* St) { + const GRState* St) { bool IsNew; - ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, I.getBlock()), + ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, I.getBlock()), St, &IsNew); Succ->addPredecessor(Pred); @@ -535,7 +535,7 @@ GRSwitchNodeBuilderImpl::generateCaseStmtNodeImpl(const Iterator& I, ExplodedNode* -GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St, +GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const GRState* St, bool isSink) { // Get the block for the default case. @@ -544,7 +544,7 @@ GRSwitchNodeBuilderImpl::generateDefaultCaseNodeImpl(const void* St, bool IsNew; - ExplodedNode* Succ = Eng.G->getNodeImpl(BlockEdge(Src, DefaultBlock), + ExplodedNode* Succ = Eng.G->getNode(BlockEdge(Src, DefaultBlock), St, &IsNew); Succ->addPredecessor(Pred); @@ -566,14 +566,14 @@ GREndPathNodeBuilderImpl::~GREndPathNodeBuilderImpl() { } ExplodedNode* -GREndPathNodeBuilderImpl::generateNodeImpl(const void* State, +GREndPathNodeBuilderImpl::generateNodeImpl(const GRState* State, const void *tag, ExplodedNode* P) { HasGeneratedNode = true; bool IsNew; ExplodedNode* Node = - Eng.G->getNodeImpl(BlockEntrance(&B, tag), State, &IsNew); + Eng.G->getNode(BlockEntrance(&B, tag), State, &IsNew); Node->addPredecessor(P ? P : Pred);