diff options
author | Dan Gohman <gohman@apple.com> | 2010-08-17 17:39:21 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-08-17 17:39:21 +0000 |
commit | 5047ca0c02a3d35797413ac8a5651a6ee9537f15 (patch) | |
tree | 86ee6fb8748b856e298fb39bd89dd2382ed8655f | |
parent | a92773660485af9faea69911de59a0f99e8e9561 (diff) | |
download | bcm5719-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.cpp | 20 | ||||
-rw-r--r-- | llvm/test/Transforms/LoopRotate/phi-duplicate.ll | 22 |
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: } |