summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-08-17 17:39:21 +0000
committerDan Gohman <gohman@apple.com>2010-08-17 17:39:21 +0000
commit5047ca0c02a3d35797413ac8a5651a6ee9537f15 (patch)
tree86ee6fb8748b856e298fb39bd89dd2382ed8655f
parenta92773660485af9faea69911de59a0f99e8e9561 (diff)
downloadbcm5719-llvm-5047ca0c02a3d35797413ac8a5651a6ee9537f15.tar.gz
bcm5719-llvm-5047ca0c02a3d35797413ac8a5651a6ee9537f15.zip
When rotating loops, put the original header at the bottom of the
loop, making the resulting loop significantly less ugly. Also, zap its trivial PHI nodes, since it's easy. llvm-svn: 111255
-rw-r--r--llvm/lib/Transforms/Scalar/LoopRotation.cpp20
-rw-r--r--llvm/test/Transforms/LoopRotate/phi-duplicate.ll22
2 files changed, 37 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
index 1e4bfa94be5..31957ddac14 100644
--- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
@@ -261,6 +261,26 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) {
// NewHeader is now the header of the loop.
L->moveToHeader(NewHeader);
+ // Move the original header to the bottom of the loop, where it now more
+ // naturally belongs. This isn't necessary for correctness, and CodeGen can
+ // usually reorder blocks on its own to fix things like this up, but it's
+ // still nice to keep the IR readable.
+ //
+ // The original header should have only one predecessor at this point, since
+ // we checked that the loop had a proper preheader and unique backedge before
+ // we started.
+ assert(OrigHeader->getSinglePredecessor() &&
+ "Original loop header has too many predecessors after loop rotation!");
+ OrigHeader->moveAfter(OrigHeader->getSinglePredecessor());
+
+ // Also, since this original header only has one predecessor, zap its
+ // PHI nodes, which are now trivial.
+ FoldSingleEntryPHINodes(OrigHeader);
+
+ // TODO: We could just go ahead and merge OrigHeader into its predecessor
+ // at this point, if we don't mind updating dominator info.
+
+ // Establish a new preheader, update dominators, etc.
preserveCanonicalLoopForm(LPM);
++NumRotated;
diff --git a/llvm/test/Transforms/LoopRotate/phi-duplicate.ll b/llvm/test/Transforms/LoopRotate/phi-duplicate.ll
index 9a64e2a9a83..5403e723ee1 100644
--- a/llvm/test/Transforms/LoopRotate/phi-duplicate.ll
+++ b/llvm/test/Transforms/LoopRotate/phi-duplicate.ll
@@ -27,9 +27,21 @@ for.body: ; preds = %for.cond
for.end: ; preds = %for.cond
ret void
}
-; Should only end up with one phi.
-; CHECK: for.body:
-; CHECK-NEXT: %j.02 = phi i64
-; CHECK-NOT: phi
-; CHECK: ret void
+; Should only end up with one phi. Also, the original for.cond block should
+; be moved to the end of the loop so that the new loop header pleasantly
+; ends up at the top.
+
+; CHECK: define void @test
+; CHECK-NEXT: entry:
+; CHECK-NEXT: icmp slt i64
+; CHECK-NEXT: br i1
+; CHECK-NOT: :
+; CHECK: bb.nph:
+; CHECK-NEXT: br label %for.body
+; CHECK-NOT: :
+; CHECK: for.body:
+; CHECK-NEXT: %j.02 = phi i64
+; CHECK-NOT: phi
+; CHECK: ret void
+; CHECK-NEXT: }
OpenPOWER on IntegriCloud