Add simplifyLoopLatch to LoopRotate pass.

This folds a simple loop tail into a loop latch. It covers the common (in fortran) case of postincrement loops. It's a "free" way to expose this type of loop to downstream loop optimizations that bail out on non-canonical loops (getLoopLatch is a heavily used check).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick 2012-02-14 00:00:23 +00:00
parent c3a825b76c
commit f6629ab847
2 changed files with 142 additions and 0 deletions

View File

@ -19,6 +19,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
@ -52,6 +53,7 @@ namespace {
}
bool runOnLoop(Loop *L, LPPassManager &LPM);
void simplifyLoopLatch(Loop *L);
bool rotateLoop(Loop *L);
private:
@ -73,6 +75,11 @@ Pass *llvm::createLoopRotatePass() { return new LoopRotate(); }
bool LoopRotate::runOnLoop(Loop *L, LPPassManager &LPM) {
LI = &getAnalysis<LoopInfo>();
// Simplify the loop latch before attempting to rotate the header
// upward. Rotation may not be needed if the loop tail can be folded into the
// loop exit.
simplifyLoopLatch(L);
// One loop can be rotated multiple times.
bool MadeChange = false;
while (rotateLoop(L))
@ -146,6 +153,102 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
}
}
/// Determine whether the instructions in this range my be safely and cheaply
/// speculated. This is not an important enough situation to develop complex
/// heuristics. We handle a single arithmetic instruction along with any type
/// conversions.
static bool shouldSpeculateInstrs(BasicBlock::iterator Begin,
BasicBlock::iterator End) {
bool seenIncrement = false;
for (BasicBlock::iterator I = Begin; I != End; ++I) {
if (!isSafeToSpeculativelyExecute(I))
return false;
if (isa<DbgInfoIntrinsic>(I))
continue;
switch (I->getOpcode()) {
default:
return false;
case Instruction::GetElementPtr:
// GEPs are cheap if all indices are constant.
if (!cast<GEPOperator>(I)->hasAllConstantIndices())
return false;
// fall-thru to increment case
case Instruction::Add:
case Instruction::Sub:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
if (seenIncrement)
return false;
seenIncrement = true;
break;
case Instruction::Trunc:
case Instruction::ZExt:
case Instruction::SExt:
// ignore type conversions
break;
}
}
return true;
}
/// Fold the loop tail into the loop exit by speculating the loop tail
/// instructions. Typically, this is a single post-increment. In the case of a
/// simple 2-block loop, hoisting the increment can be much better than
/// duplicating the entire loop header. In the cast of loops with early exits,
/// rotation will not work anyway, but simplifyLoopLatch will put the loop in
/// canonical form so downstream passes can handle it.
///
/// I don't believe this invalidates SCEV.
void LoopRotate::simplifyLoopLatch(Loop *L) {
BasicBlock *Latch = L->getLoopLatch();
if (!Latch || Latch->hasAddressTaken())
return;
BranchInst *Jmp = dyn_cast<BranchInst>(Latch->getTerminator());
if (!Jmp || !Jmp->isUnconditional())
return;
BasicBlock *LastExit = Latch->getSinglePredecessor();
if (!LastExit || !L->isLoopExiting(LastExit))
return;
BranchInst *BI = dyn_cast<BranchInst>(LastExit->getTerminator());
if (!BI)
return;
if (!shouldSpeculateInstrs(Latch->begin(), Jmp))
return;
DEBUG(dbgs() << "Folding loop latch " << Latch->getName() << " into "
<< LastExit->getName() << "\n");
// Hoist the instructions from Latch into LastExit.
LastExit->getInstList().splice(BI, Latch->getInstList(), Latch->begin(), Jmp);
unsigned FallThruPath = BI->getSuccessor(0) == Latch ? 0 : 1;
BasicBlock *Header = Jmp->getSuccessor(0);
assert(Header == L->getHeader() && "expected a backward branch");
// Remove Latch from the CFG so that LastExit becomes the new Latch.
BI->setSuccessor(FallThruPath, Header);
Latch->replaceSuccessorsPhiUsesWith(LastExit);
Jmp->eraseFromParent();
// Nuke the Latch block.
assert(Latch->empty() && "unable to evacuate Latch");
LI->removeBlock(Latch);
if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>())
DT->eraseNode(Latch);
Latch->eraseFromParent();
}
/// Rotate loop LP. Return true if the loop is rotated.
bool LoopRotate::rotateLoop(Loop *L) {
// If the loop has only one block then there is not much to rotate.

View File

@ -0,0 +1,39 @@
; RUN: opt -S < %s -loop-rotate -verify-dom-info -verify-loop-info | FileCheck %s
; PR2624 unroll multiple exits
@mode_table = global [4 x i32] zeroinitializer ; <[4 x i32]*> [#uses=1]
; CHECK: @f
; CHECK-NOT: bb4
define i8 @f() {
entry:
tail call i32 @fegetround( ) ; <i32>:0 [#uses=1]
br label %bb
bb: ; preds = %bb4, %entry
%mode.0 = phi i8 [ 0, %entry ], [ %indvar.next, %bb4 ] ; <i8> [#uses=4]
zext i8 %mode.0 to i32 ; <i32>:1 [#uses=1]
getelementptr [4 x i32]* @mode_table, i32 0, i32 %1 ; <i32*>:2 [#uses=1]
load i32* %2, align 4 ; <i32>:3 [#uses=1]
icmp eq i32 %3, %0 ; <i1>:4 [#uses=1]
br i1 %4, label %bb1, label %bb2
bb1: ; preds = %bb
ret i8 %mode.0
bb2: ; preds = %bb
icmp eq i8 %mode.0, 1 ; <i1>:5 [#uses=1]
br i1 %5, label %bb5, label %bb4
bb4: ; preds = %bb2
%indvar.next = add i8 %mode.0, 1 ; <i8> [#uses=1]
br label %bb
bb5: ; preds = %bb2
tail call void @raise_exception( ) noreturn
unreachable
}
declare i32 @fegetround()
declare void @raise_exception() noreturn