From 5fe4d9deb543a19f557e3d85c5f33867af97cd96 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 7 Oct 2009 00:42:52 +0000 Subject: Change ExplodedNode to have its NodeGroups all BumpPtrAllocated, avoiding malloc() traffic when adding successors/predecessors to a node. This was done by introducing BumpVector, which is essentially SmallVector with all memory being BumpPtrAllocated (this can certainly be cleaned up or moved into llvm/ADT). This change yields a 1.8% speed increase when running the analyzer (with -analyzer-store=region) on a small benchmark file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83439 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ExplodedGraph.cpp | 61 ++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 35 deletions(-) (limited to 'lib/Analysis/ExplodedGraph.cpp') diff --git a/lib/Analysis/ExplodedGraph.cpp b/lib/Analysis/ExplodedGraph.cpp index 463b171249..0dc81a4225 100644 --- a/lib/Analysis/ExplodedGraph.cpp +++ b/lib/Analysis/ExplodedGraph.cpp @@ -43,53 +43,48 @@ void ExplodedNode::SetAuditor(ExplodedNode::Auditor* A) { // ExplodedNode. //===----------------------------------------------------------------------===// -static inline std::vector& getVector(void* P) { - return *reinterpret_cast*>(P); +static inline BumpVector& getVector(void* P) { + return *reinterpret_cast*>(P); } -void ExplodedNode::Profile(llvm::FoldingSetNodeID& ID, - const ProgramPoint& Loc, - const GRState* state) { - ID.Add(Loc); - ID.AddPointer(state); -} - -void ExplodedNode::addPredecessor(ExplodedNode* V) { +void ExplodedNode::addPredecessor(ExplodedNode* V, ExplodedGraph &G) { assert (!V->isSink()); - Preds.addNode(V); - V->Succs.addNode(this); + Preds.addNode(V, G); + V->Succs.addNode(this, G); #ifndef NDEBUG if (NodeAuditor) NodeAuditor->AddEdge(V, this); #endif } -void ExplodedNode::NodeGroup::addNode(ExplodedNode* N) { - - assert ((reinterpret_cast(N) & Mask) == 0x0); - assert (!getFlag()); +void ExplodedNode::NodeGroup::addNode(ExplodedNode* N, ExplodedGraph &G) { + assert((reinterpret_cast(N) & Mask) == 0x0); + assert(!getFlag()); if (getKind() == Size1) { if (ExplodedNode* NOld = getNode()) { - std::vector* V = new std::vector(); - assert ((reinterpret_cast(V) & Mask) == 0x0); - V->push_back(NOld); - V->push_back(N); + BumpVectorContext &Ctx = G.getNodeAllocator(); + BumpVector *V = + G.getAllocator().Allocate >(); + new (V) BumpVector(Ctx, 4); + + assert((reinterpret_cast(V) & Mask) == 0x0); + V->push_back(NOld, Ctx); + V->push_back(N, Ctx); P = reinterpret_cast(V) | SizeOther; - assert (getPtr() == (void*) V); - assert (getKind() == SizeOther); + assert(getPtr() == (void*) V); + assert(getKind() == SizeOther); } else { P = reinterpret_cast(N); - assert (getKind() == Size1); + assert(getKind() == Size1); } } else { - assert (getKind() == SizeOther); - getVector(getPtr()).push_back(N); + assert(getKind() == SizeOther); + getVector(getPtr()).push_back(N, G.getNodeAllocator()); } } - unsigned ExplodedNode::NodeGroup::size() const { if (getFlag()) return 0; @@ -100,7 +95,7 @@ unsigned ExplodedNode::NodeGroup::size() const { return getVector(getPtr()).size(); } -ExplodedNode** ExplodedNode::NodeGroup::begin() const { +ExplodedNode **ExplodedNode::NodeGroup::begin() const { if (getFlag()) return NULL; @@ -119,14 +114,10 @@ ExplodedNode** ExplodedNode::NodeGroup::end() const { else { // Dereferencing end() is undefined behaviour. The vector is not empty, so // we can dereference the last elem and then add 1 to the result. - return const_cast(&getVector(getPtr()).back()) + 1; + return const_cast(getVector(getPtr()).end()); } } -ExplodedNode::NodeGroup::~NodeGroup() { - if (getKind() == SizeOther) delete &getVector(getPtr()); -} - ExplodedNode *ExplodedGraph::getNode(const ProgramPoint& L, const GRState* State, bool* IsNew) { // Profile 'State' to determine if we already have an existing node. @@ -138,7 +129,7 @@ ExplodedNode *ExplodedGraph::getNode(const ProgramPoint& L, if (!V) { // Allocate a new node. - V = (NodeTy*) Allocator.Allocate(); + V = (NodeTy*) getAllocator().Allocate(); new (V) NodeTy(L, State); // Insert the node into the node set and return it. @@ -253,7 +244,7 @@ ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources, if (PI == Pass2.end()) continue; - NewN->addPredecessor(PI->second); + NewN->addPredecessor(PI->second, *G); } // In the case that some of the intended successors of NewN have already @@ -263,7 +254,7 @@ ExplodedGraph::TrimInternal(const ExplodedNode* const* BeginSources, for (ExplodedNode **I=N->Succs.begin(), **E=N->Succs.end(); I!=E; ++I) { Pass2Ty::iterator PI = Pass2.find(*I); if (PI != Pass2.end()) { - PI->second->addPredecessor(NewN); + PI->second->addPredecessor(NewN, *G); continue; } -- cgit v1.2.3-18-g5258