[SROA] Fix the loop exit placement to be prior to indexing the splits
[oota-llvm.git] / lib / Transforms / Scalar / StructurizeCFG.cpp
index d2206e380c1eaf338d64f9a90c59431417df247d..7fe87f9319b6a164b1612cc0de2d3726c04132c9 100644 (file)
@@ -10,6 +10,7 @@
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SCCIterator.h"
+#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/RegionInfo.h"
 #include "llvm/Analysis/RegionIterator.h"
 #include "llvm/Analysis/RegionPass.h"
@@ -166,6 +167,7 @@ class StructurizeCFG : public RegionPass {
   Region *ParentRegion;
 
   DominatorTree *DT;
+  LoopInfo *LI;
 
   RNVector Order;
   BBSet Visited;
@@ -247,6 +249,7 @@ public:
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequiredID(LowerSwitchID);
     AU.addRequired<DominatorTreeWrapperPass>();
+    AU.addRequired<LoopInfo>();
     AU.addPreserved<DominatorTreeWrapperPass>();
     RegionPass::getAnalysisUsage(AU);
   }
@@ -301,8 +304,9 @@ void StructurizeCFG::analyzeLoops(RegionNode *N) {
     for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
       BasicBlock *Succ = Term->getSuccessor(i);
 
-      if (Visited.count(Succ))
+      if (Visited.count(Succ) && LI->isLoopHeader(Succ) ) {
         Loops[Succ] = BB;
+      }
     }
   }
 }
@@ -365,39 +369,41 @@ void StructurizeCFG::gatherPredicates(RegionNode *N) {
   BBPredicates &Pred = Predicates[BB];
   BBPredicates &LPred = LoopPreds[BB];
 
-  for (BasicBlock *Predecessor : predecessors(BB)) {
+  for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
+       PI != PE; ++PI) {
+
     // Ignore it if it's a branch from outside into our region entry
-    if (!ParentRegion->contains(Predecessor))
+    if (!ParentRegion->contains(*PI))
       continue;
 
-    Region *R = RI->getRegionFor(Predecessor);
+    Region *R = RI->getRegionFor(*PI);
     if (R == ParentRegion) {
 
       // It's a top level block in our region
-      BranchInst *Term = cast<BranchInst>(Predecessor->getTerminator());
+      BranchInst *Term = cast<BranchInst>((*PI)->getTerminator());
       for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
         BasicBlock *Succ = Term->getSuccessor(i);
         if (Succ != BB)
           continue;
 
-        if (Visited.count(Predecessor)) {
+        if (Visited.count(*PI)) {
           // Normal forward edge
           if (Term->isConditional()) {
             // Try to treat it like an ELSE block
             BasicBlock *Other = Term->getSuccessor(!i);
             if (Visited.count(Other) && !Loops.count(Other) &&
-                !Pred.count(Other) && !Pred.count(Predecessor)) {
+                !Pred.count(Other) && !Pred.count(*PI)) {
 
               Pred[Other] = BoolFalse;
-              Pred[Predecessor] = BoolTrue;
+              Pred[*PI] = BoolTrue;
               continue;
             }
           }
-          Pred[Predecessor] = buildCondition(Term, i, false);
+          Pred[*PI] = buildCondition(Term, i, false);
 
         } else {
           // Back edge
-          LPred[Predecessor] = buildCondition(Term, i, true);
+          LPred[*PI] = buildCondition(Term, i, true);
         }
       }
 
@@ -572,8 +578,11 @@ void StructurizeCFG::killTerminator(BasicBlock *BB) {
   if (!Term)
     return;
 
-  for (BasicBlock *Succ : successors(BB))
-    delPhiValues(BB, Succ);
+  for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
+       SI != SE; ++SI) {
+
+    delPhiValues(BB, *SI);
+  }
 
   Term->eraseFromParent();
 }
@@ -587,7 +596,10 @@ void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
     BasicBlock *Dominator = nullptr;
 
     // Find all the edges from the sub region to the exit
-    for (BasicBlock *BB : predecessors(OldExit)) {
+    for (pred_iterator I = pred_begin(OldExit), E = pred_end(OldExit);
+         I != E;) {
+
+      BasicBlock *BB = *I++;
       if (!SubRegion->contains(BB))
         continue;
 
@@ -854,6 +866,7 @@ bool StructurizeCFG::runOnRegion(Region *R, RGPassManager &RGM) {
   ParentRegion = R;
 
   DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+  LI = &getAnalysis<LoopInfo>();
 
   orderNodes();
   collectInfos();