From e5ffa900f8cf486fae4f542d72d84e6bab0129ae Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 7 Apr 2008 09:59:07 +0000 Subject: [PATCH] Make GVN more memory efficient, particularly on code that contains a large number of allocations, which GVN can't optimize anyways. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49329 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Analysis/Dominators.h | 4 ++++ lib/Transforms/Scalar/GVN.cpp | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h index 8d333de6b0b..65cfb569aaa 100644 --- a/include/llvm/Analysis/Dominators.h +++ b/include/llvm/Analysis/Dominators.h @@ -103,6 +103,10 @@ public: return C; } + size_t getNumChildren() const { + return Children.size(); + } + void setIDom(DomTreeNodeBase *NewIDom) { assert(IDom && "No immediate dominator?"); if (IDom != NewIDom) { diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index c966311c9e6..9a03c21593c 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1593,6 +1593,11 @@ bool GVN::processInstruction(Instruction *I, ValueNumberedSet &currAvail, if (StoreInst *SI = dyn_cast(I)) return processStore(SI, toErase); + // Allocations are always uniquely numbered, so we can save time and memory + // by fast failing them. + if (isa(I)) + return false; + if (MemCpyInst* M = dyn_cast(I)) { MemoryDependenceAnalysis& MD = getAnalysis(); @@ -1692,6 +1697,7 @@ bool GVN::iterateOnFunction(Function &F) { SmallVector toErase; DenseMap lastSeenLoad; + DenseMap numChildrenVisited; // Top-down walk of the dominator tree for (df_iterator DI = df_begin(DT.getRootNode()), @@ -1704,8 +1710,16 @@ bool GVN::iterateOnFunction(Function &F) { BasicBlock* BB = DI->getBlock(); // A block inherits AVAIL_OUT from its dominator - if (DI->getIDom() != 0) + if (DI->getIDom() != 0) { currAvail = availableOut[DI->getIDom()->getBlock()]; + + numChildrenVisited[DI->getIDom()]++; + + if (numChildrenVisited[DI->getIDom()] == DI->getIDom()->getNumChildren()) { + availableOut.erase(DI->getIDom()->getBlock()); + numChildrenVisited.erase(DI->getIDom()); + } + } for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {