[PATCH] D24509: [LCSSA] Cache LoopExits to avoid wasted work

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 13 07:43:31 PDT 2016


reames created this revision.
reames added reviewers: chandlerc, wmi, hfinkel, xur, majnemer.
reames added a subscriber: llvm-commits.
Herald added a subscriber: mcrosier.

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%.  


https://reviews.llvm.org/D24509

Files:
  lib/Transforms/Utils/LCSSA.cpp

Index: lib/Transforms/Utils/LCSSA.cpp
===================================================================
--- lib/Transforms/Utils/LCSSA.cpp
+++ lib/Transforms/Utils/LCSSA.cpp
@@ -63,19 +63,25 @@
 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.
+  DenseMap<Loop*, SmallVector<BasicBlock *, 8>> 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 SmallVector<BasicBlock *, 8> &ExitBlocks = LoopExitBlocks[L];
 
     if (ExitBlocks.empty())
       continue;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24509.71165.patch
Type: text/x-patch
Size: 1302 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160913/89833df5/attachment.bin>


More information about the llvm-commits mailing list