aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LCSSA.cpp
diff options
context:
space:
mode:
authorPhilip Reames <listmail@philipreames.com>2016-09-19 23:30:23 +0000
committerPhilip Reames <listmail@philipreames.com>2016-09-19 23:30:23 +0000
commitb1472ffed724488700ae6191a6f245e012aa67b1 (patch)
treecc0b2d4e807e09cf4324f8ffeafcaf817084a304 /llvm/lib/Transforms/Utils/LCSSA.cpp
parentae273b6ba2e838cd2fe277c94d6987620146af71 (diff)
downloadllvm-b1472ffed724488700ae6191a6f245e012aa67b1.zip
llvm-b1472ffed724488700ae6191a6f245e012aa67b1.tar.gz
llvm-b1472ffed724488700ae6191a6f245e012aa67b1.tar.bz2
[LCSSA] Cache LoopExits to avoid wasted work
When looking at the scribus_1.3 example from https://llvm.org/bugs/show_bug.cgi?id=10584, I noticed that we were spending a large amount of time computing loop exits in LCSSA. This code appears to be written with the assumption that LoopExits are stored in the Loop and thus cheap to query. This is not true, so we should cache the result across the potentially long running loop which tends to visit a small handful of Loops. On the particular example from 10584, this change drops the time spent in LCSSA computation by about 80%. Differential Revision: https://reviews.llvm.org/D24509 llvm-svn: 281949
Diffstat (limited to 'llvm/lib/Transforms/Utils/LCSSA.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LCSSA.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp
index 33c1837..ac403cc 100644
--- a/llvm/lib/Transforms/Utils/LCSSA.cpp
+++ b/llvm/lib/Transforms/Utils/LCSSA.cpp
@@ -63,19 +63,25 @@ static bool isExitBlock(BasicBlock *BB,
bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
DominatorTree &DT, LoopInfo &LI) {
SmallVector<Use *, 16> UsesToRewrite;
- SmallVector<BasicBlock *, 8> ExitBlocks;
SmallSetVector<PHINode *, 16> PHIsToRemove;
PredIteratorCache PredCache;
bool Changed = false;
+ // Cache the Loop ExitBlocks across this loop. We expect to get a lot of
+ // instructions within the same loops, computing the exit blocks is
+ // expensive, and we're not mutating the loop structure.
+ SmallDenseMap<Loop*, SmallVector<BasicBlock *,1>> LoopExitBlocks;
+
while (!Worklist.empty()) {
UsesToRewrite.clear();
- ExitBlocks.clear();
Instruction *I = Worklist.pop_back_val();
BasicBlock *InstBB = I->getParent();
Loop *L = LI.getLoopFor(InstBB);
- L->getExitBlocks(ExitBlocks);
+ if (!LoopExitBlocks.count(L))
+ L->getExitBlocks(LoopExitBlocks[L]);
+ assert(LoopExitBlocks.count(L));
+ const SmallVectorImpl<BasicBlock *> &ExitBlocks = LoopExitBlocks[L];
if (ExitBlocks.empty())
continue;