Tweak the LICM code to reuse the first sub-loop instead of creating a new one
authorRoman Gareev <gareevroman@gmail.com>
Mon, 15 Feb 2016 14:48:50 +0000 (14:48 +0000)
committerRoman Gareev <gareevroman@gmail.com>
Mon, 15 Feb 2016 14:48:50 +0000 (14:48 +0000)
LICM starts with an *empty* AST, and then merges in each sub-loop. While the
add code is appropriate for sub-loop 2 and up, it's utterly unnecessary for
sub-loop 1. If the AST starts off empty, we can just clone/move the contents
of the subloop into the containing AST.

Reviewed-by: Philip Reames <listmail@philipreames.com>
Differential Revision: http://reviews.llvm.org/D16753

llvm-svn: 260892

llvm/lib/Transforms/Scalar/LICM.cpp

index 4fb0604..3a0615b 100644 (file)
@@ -164,6 +164,11 @@ namespace {
 
     /// Simple Analysis hook. Delete loop L from alias set map.
     void deleteAnalysisLoop(Loop *L) override;
+
+    /// Returns an owning pointer to an alias set which incorporates aliasing
+    /// info from all subloops of L, but does not include instructions in L
+    /// itself.
+    AliasSetTracker *collectAliasInfoFromSubLoops(Loop *L);
   };
 }
 
@@ -202,20 +207,7 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) {
 
   assert(L->isLCSSAForm(*DT) && "Loop is not in LCSSA form.");
 
-  CurAST = new AliasSetTracker(*AA);
-  // Collect Alias info from subloops.
-  for (Loop *InnerL : L->getSubLoops()) {
-    AliasSetTracker *InnerAST = LoopToAliasSetMap[InnerL];
-    assert(InnerAST && "Where is my AST?");
-
-    // What if InnerLoop was modified by other passes ?
-    CurAST->add(*InnerAST);
-
-    // Once we've incorporated the inner loop's AST into ours, we don't need the
-    // subloop's anymore.
-    delete InnerAST;
-    LoopToAliasSetMap.erase(InnerL);
-  }
+  CurAST = collectAliasInfoFromSubLoops(L);
 
   CurLoop = L;
 
@@ -1065,6 +1057,32 @@ bool llvm::promoteLoopAccessesToScalars(AliasSet &AS,
   return Changed;
 }
 
+/// Returns an owning pointer to an alias set which incorporates aliasing info
+/// from all subloops of L, but does not include instructions in L itself.
+///
+AliasSetTracker *LICM::collectAliasInfoFromSubLoops(Loop *L) {
+  AliasSetTracker *CurAST = nullptr;
+  for (Loop *InnerL : L->getSubLoops()) {
+    AliasSetTracker *InnerAST = LoopToAliasSetMap[InnerL];
+    assert(InnerAST && "Where is my AST?");
+
+    if (CurAST != nullptr) {
+      // What if InnerLoop was modified by other passes ?
+      CurAST->add(*InnerAST);
+
+      // Once we've incorporated the inner loop's AST into ours, we don't need
+      // the subloop's anymore.
+      delete InnerAST;
+    } else {
+      CurAST = InnerAST;
+    }
+    LoopToAliasSetMap.erase(InnerL);
+  }
+  if (CurAST == nullptr)
+    CurAST = new AliasSetTracker(*AA);
+  return CurAST;
+}
+
 /// Simple analysis hook. Clone alias set info.
 ///
 void LICM::cloneBasicBlockAnalysis(BasicBlock *From, BasicBlock *To, Loop *L) {