[IRCE] Preserve DomTree and LCSSA
authorSanjoy Das <sanjoy@playingwithpointers.com>
Tue, 2 Aug 2016 19:31:54 +0000 (19:31 +0000)
committerSanjoy Das <sanjoy@playingwithpointers.com>
Tue, 2 Aug 2016 19:31:54 +0000 (19:31 +0000)
This changes IRCE to "preserve" LCSSA and DomTree by recomputing them.
It still does not preserve LoopSimplify.

llvm-svn: 277505

llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
llvm/test/Transforms/IRCE/single-access-no-preloop.ll
llvm/test/Transforms/IRCE/single-access-with-preloop.ll

index 52e94fa..dd3459f 100644 (file)
@@ -570,6 +570,7 @@ class LoopConstrainer {
   Function &F;
   LLVMContext &Ctx;
   ScalarEvolution &SE;
+  DominatorTree &DT;
 
   // Information about the original loop we started out with.
   Loop &OriginalLoop;
@@ -590,11 +591,12 @@ class LoopConstrainer {
 
 public:
   LoopConstrainer(Loop &L, LoopInfo &LI, const LoopStructure &LS,
-                  ScalarEvolution &SE, InductiveRangeCheck::Range R)
+                  ScalarEvolution &SE, DominatorTree &DT,
+                  InductiveRangeCheck::Range R)
       : F(*L.getHeader()->getParent()), Ctx(L.getHeader()->getContext()),
-        SE(SE), OriginalLoop(L), OriginalLoopInfo(LI), LatchTakenCount(nullptr),
-        OriginalPreheader(nullptr), MainLoopPreheader(nullptr), Range(R),
-        MainLoopStructure(LS) {}
+        SE(SE), DT(DT), OriginalLoop(L), OriginalLoopInfo(LI),
+        LatchTakenCount(nullptr), OriginalPreheader(nullptr),
+        MainLoopPreheader(nullptr), Range(R), MainLoopStructure(LS) {}
 
   // Entry point for the algorithm.  Returns true on success.
   bool run();
@@ -1274,6 +1276,9 @@ bool LoopConstrainer::run() {
   addToParentLoopIfNeeded(PreLoop.Blocks);
   addToParentLoopIfNeeded(PostLoop.Blocks);
 
+  DT.recalculate(F);
+  formLCSSARecursively(OriginalLoop, DT, &OriginalLoopInfo, &SE);
+
   return true;
 }
 
@@ -1444,8 +1449,9 @@ bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
   if (!SafeIterRange.hasValue())
     return false;
 
+  auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
   LoopConstrainer LC(*L, getAnalysis<LoopInfoWrapperPass>().getLoopInfo(), LS,
-                     SE, SafeIterRange.getValue());
+                     SE, DT, SafeIterRange.getValue());
   bool Changed = LC.run();
 
   if (Changed) {
index 76f134c..77288a0 100644 (file)
@@ -31,12 +31,13 @@ define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32
 ; CHECK: br i1 true, label %in.bounds, label %out.of.bounds
 
 ; CHECK: main.exit.selector:
-; CHECK-NEXT: [[continue:%[^ ]+]] = icmp slt i32 %idx.next, %n
+; CHECK-NEXT: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds ]
+; CHECK-NEXT: [[continue:%[^ ]+]] = icmp slt i32 %idx.next.lcssa, %n
 ; CHECK-NEXT: br i1 [[continue]], label %main.pseudo.exit, label %exit.loopexit
 
 ; CHECK: main.pseudo.exit:
-; CHECK-NEXT: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next, %main.exit.selector ]
-; CHECK-NEXT: %indvar.end = phi i32 [ 0, %loop.preheader ], [ %idx.next, %main.exit.selector ]
+; CHECK-NEXT: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ]
+; CHECK-NEXT: %indvar.end = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ]
 ; CHECK-NEXT: br label %postloop
 
 ; CHECK: postloop:
@@ -102,7 +103,7 @@ define void @single_access_no_preloop_with_offset(i32 *%arr, i32 *%a_len_ptr, i3
 ; CHECK: br i1 [[continue_main_loop]], label %loop, label %main.exit.selector
 
 ; CHECK: main.pseudo.exit:
-; CHECK:  %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next, %main.exit.selector ]
+; CHECK:  %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ]
 ; CHECK:  br label %postloop
 
 ; CHECK: loop.postloop:
index f80c463..204c24c 100644 (file)
@@ -53,7 +53,7 @@ define void @single_access_with_preloop(i32 *%arr, i32 *%a_len_ptr, i32 %n, i32
 ; CHECK: br i1 [[continue_mainloop_cond]], label %loop, label %main.exit.selector
 
 ; CHECK: main.exit.selector:
-; CHECK: [[mainloop_its_left:[^ ]+]] = icmp slt i32 %idx.next, %n
+; CHECK: [[mainloop_its_left:[^ ]+]] = icmp slt i32 %idx.next.lcssa, %n
 ; CHECK: br i1 [[mainloop_its_left]], label %main.pseudo.exit, label %exit.loopexit
 
 ; CHECK: in.bounds.preloop: