Skip to content

Commit 9bfa6f8

Browse files
committed
Implement a simple optimization for the termination condition of the loop.
The termination condition actually wants to use the post-incremented value of the loop, not a new indvar with an unusual base. On PPC, for example, this allows us to compile LoopStrengthReduce/exit_compare_live_range.ll to: _foo: li r2, 0 .LBB_foo_1: ; no_exit li r5, 0 stw r5, 0(r3) addi r2, r2, 1 cmpw cr0, r2, r4 bne .LBB_foo_1 ; no_exit blr instead of: _foo: li r2, 1 ;; IV starts at 1, not 0 .LBB_foo_1: ; no_exit li r5, 0 stw r5, 0(r3) addi r5, r2, 1 cmpw cr0, r2, r4 or r2, r5, r5 ;; Reg-reg copy, extra live range bne .LBB_foo_1 ; no_exit blr This implements LoopStrengthReduce/exit_compare_live_range.ll llvm-svn: 22699
1 parent 24a0a43 commit 9bfa6f8

File tree

1 file changed

+107
-6
lines changed

1 file changed

+107
-6
lines changed

llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Lines changed: 107 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,16 @@ namespace {
4646
SCEVHandle Offset;
4747
Instruction *User;
4848
Value *OperandValToReplace;
49+
50+
// isUseOfPostIncrementedValue - True if this should use the
51+
// post-incremented version of this IV, not the preincremented version.
52+
// This can only be set in special cases, such as the terminating setcc
53+
// instruction for a loop.
54+
bool isUseOfPostIncrementedValue;
4955

5056
IVStrideUse(const SCEVHandle &Offs, Instruction *U, Value *O)
51-
: Offset(Offs), User(U), OperandValToReplace(O) {}
57+
: Offset(Offs), User(U), OperandValToReplace(O),
58+
isUseOfPostIncrementedValue(false) {}
5259
};
5360

5461
/// IVUsersOfOneStride - This structure keeps track of all instructions that
@@ -127,6 +134,7 @@ namespace {
127134
std::set<Instruction*> &Processed);
128135
SCEVHandle GetExpressionSCEV(Instruction *E, Loop *L);
129136

137+
void OptimizeIndvars(Loop *L);
130138

131139
void StrengthReduceStridedIVUsers(Value *Stride, IVUsersOfOneStride &Uses,
132140
Loop *L, bool isOnlyStride);
@@ -353,8 +361,15 @@ namespace {
353361
/// operation. This is null if we should just use zero so far.
354362
Value *EmittedBase;
355363

356-
BasedUser(Instruction *I, Value *Op, const SCEVHandle &IMM)
357-
: Inst(I), OperandValToReplace(Op), Imm(IMM), EmittedBase(0) {}
364+
// isUseOfPostIncrementedValue - True if this should use the
365+
// post-incremented version of this IV, not the preincremented version.
366+
// This can only be set in special cases, such as the terminating setcc
367+
// instruction for a loop.
368+
bool isUseOfPostIncrementedValue;
369+
370+
BasedUser(Instruction *I, Value *Op, const SCEVHandle &IMM, bool iUOPIV)
371+
: Inst(I), OperandValToReplace(Op), Imm(IMM), EmittedBase(0),
372+
isUseOfPostIncrementedValue(iUOPIV) {}
358373

359374
// Once we rewrite the code to insert the new IVs we want, update the
360375
// operands of Inst to use the new expression 'NewBase', with 'Imm' added
@@ -505,7 +520,8 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride,
505520
UsersToProcess.push_back(std::make_pair(Uses.Users[i].Offset,
506521
BasedUser(Uses.Users[i].User,
507522
Uses.Users[i].OperandValToReplace,
508-
ZeroBase)));
523+
ZeroBase,
524+
Uses.Users[i].isUseOfPostIncrementedValue)));
509525

510526
// First pass, figure out what we can represent in the immediate fields of
511527
// instructions. If we can represent anything there, move it to the imm
@@ -586,7 +602,15 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride,
586602

587603
// Now that we know what we need to do, insert code before User for the
588604
// immediate and any loop-variant expressions.
589-
User.RewriteInstructionToUseNewBase(NewPHI, Rewriter);
605+
Value *NewBase = NewPHI;
606+
607+
// If this instruction wants to use the post-incremented value, move it
608+
// after the post-inc and use its value instead of the PHI.
609+
if (User.isUseOfPostIncrementedValue) {
610+
NewBase = IncV;
611+
User.Inst->moveBefore(LatchBlock->getTerminator());
612+
}
613+
User.RewriteInstructionToUseNewBase(NewBase, Rewriter);
590614

591615
// Mark old value we replaced as possibly dead, so that it is elminated
592616
// if we just replaced the last use of that value.
@@ -602,6 +626,76 @@ void LoopStrengthReduce::StrengthReduceStridedIVUsers(Value *Stride,
602626
// different starting values, into different PHIs.
603627
}
604628

629+
// OptimizeIndvars - Now that IVUsesByStride is set up with all of the indvar
630+
// uses in the loop, look to see if we can eliminate some, in favor of using
631+
// common indvars for the different uses.
632+
void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
633+
// TODO: implement optzns here.
634+
635+
636+
637+
638+
// Finally, get the terminating condition for the loop if possible. If we
639+
// can, we want to change it to use a post-incremented version of its
640+
// induction variable, to allow coallescing the live ranges for the IV into
641+
// one register value.
642+
PHINode *SomePHI = cast<PHINode>(L->getHeader()->begin());
643+
BasicBlock *Preheader = L->getLoopPreheader();
644+
BasicBlock *LatchBlock =
645+
SomePHI->getIncomingBlock(SomePHI->getIncomingBlock(0) == Preheader);
646+
BranchInst *TermBr = dyn_cast<BranchInst>(LatchBlock->getTerminator());
647+
if (!TermBr || TermBr->isUnconditional() ||
648+
!isa<SetCondInst>(TermBr->getCondition()))
649+
return;
650+
SetCondInst *Cond = cast<SetCondInst>(TermBr->getCondition());
651+
652+
// Search IVUsesByStride to find Cond's IVUse if there is one.
653+
IVStrideUse *CondUse = 0;
654+
Value *CondStride = 0;
655+
656+
for (std::map<Value*, IVUsersOfOneStride>::iterator I =IVUsesByStride.begin(),
657+
E = IVUsesByStride.end(); I != E && !CondUse; ++I)
658+
for (std::vector<IVStrideUse>::iterator UI = I->second.Users.begin(),
659+
E = I->second.Users.end(); UI != E; ++UI)
660+
if (UI->User == Cond) {
661+
CondUse = &*UI;
662+
CondStride = I->first;
663+
// NOTE: we could handle setcc instructions with multiple uses here, but
664+
// InstCombine does it as well for simple uses, it's not clear that it
665+
// occurs enough in real life to handle.
666+
break;
667+
}
668+
if (!CondUse) return; // setcc doesn't use the IV.
669+
670+
// setcc stride is complex, don't mess with users.
671+
if (!isa<ConstantInt>(CondStride)) return;
672+
673+
// It's possible for the setcc instruction to be anywhere in the loop, and
674+
// possible for it to have multiple users. If it is not immediately before
675+
// the latch block branch, move it.
676+
if (&*++BasicBlock::iterator(Cond) != (Instruction*)TermBr) {
677+
if (Cond->hasOneUse()) { // Condition has a single use, just move it.
678+
Cond->moveBefore(TermBr);
679+
} else {
680+
// Otherwise, clone the terminating condition and insert into the loopend.
681+
Cond = cast<SetCondInst>(Cond->clone());
682+
Cond->setName(L->getHeader()->getName() + ".termcond");
683+
LatchBlock->getInstList().insert(TermBr, Cond);
684+
685+
// Clone the IVUse, as the old use still exists!
686+
IVUsesByStride[CondStride].addUser(CondUse->Offset, Cond,
687+
CondUse->OperandValToReplace);
688+
CondUse = &IVUsesByStride[CondStride].Users.back();
689+
}
690+
}
691+
692+
// If we get to here, we know that we can transform the setcc instruction to
693+
// use the post-incremented version of the IV, allowing us to coallesce the
694+
// live ranges for the IV correctly.
695+
CondUse->Offset = SCEV::getMinusSCEV(CondUse->Offset,
696+
SCEVUnknown::get(CondStride));
697+
CondUse->isUseOfPostIncrementedValue = true;
698+
}
605699

606700
void LoopStrengthReduce::runOnLoop(Loop *L) {
607701
// First step, transform all loops nesting inside of this loop.
@@ -616,7 +710,14 @@ void LoopStrengthReduce::runOnLoop(Loop *L) {
616710
AddUsersIfInteresting(I, L, Processed);
617711

618712
// If we have nothing to do, return.
619-
//if (IVUsesByStride.empty()) return;
713+
if (IVUsesByStride.empty()) return;
714+
715+
// Optimize induction variables. Some indvar uses can be transformed to use
716+
// strides that will be needed for other purposes. A common example of this
717+
// is the exit test for the loop, which can often be rewritten to use the
718+
// computation of some other indvar to decide when to terminate the loop.
719+
OptimizeIndvars(L);
720+
620721

621722
// FIXME: We can widen subreg IV's here for RISC targets. e.g. instead of
622723
// doing computation in byte values, promote to 32-bit values if safe.

0 commit comments

Comments
 (0)