Skeleton for transformations to truncate loop's iteration space.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42054 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2007-09-17 20:39:48 +00:00
parent 8c33da5dc4
commit 5279d064bc

View File

@ -111,7 +111,14 @@ namespace {
/// instruction then loop body is executed only for one iteration. In
/// such case eliminate loop structure surrounding this loop body. For
bool processOneIterationLoop(SplitInfo &SD);
void updateLoopBounds(ICmpInst *CI);
/// updateLoopIterationSpace - Current loop body is covered by an AND
/// instruction whose operands compares induction variables with loop
/// invariants. If possible, hoist this check outside the loop by
/// updating appropriate start and end values for induction variable.
bool updateLoopIterationSpace(SplitInfo &SD);
/// If loop header includes loop variant instruction operands then
/// this loop may not be eliminated.
bool safeHeader(SplitInfo &SD, BasicBlock *BB);
@ -229,7 +236,19 @@ bool LoopIndexSplit::runOnLoop(Loop *IncomingLoop, LPPassManager &LPM_Ref) {
E = SplitData.end(); SI != E;) {
SplitInfo &SD = *SI;
ICmpInst *CI = dyn_cast<ICmpInst>(SD.SplitCondition);
if (CI && CI->getPredicate() == ICmpInst::ICMP_EQ) {
if (SD.SplitCondition->getOpcode() == Instruction::And) {
Changed = updateLoopIterationSpace(SD);
if (Changed) {
++NumIndexSplit;
// If is loop is eliminated then nothing else to do here.
return Changed;
} else {
SmallVector<SplitInfo, 4>::iterator Delete_SI = SI;
++SI;
SplitData.erase(Delete_SI);
}
}
else if (CI && CI->getPredicate() == ICmpInst::ICMP_EQ) {
Changed = processOneIterationLoop(SD);
if (Changed) {
++NumIndexSplit;
@ -391,6 +410,25 @@ void LoopIndexSplit::findSplitCondition() {
if (BR->isUnconditional())
continue;
if (Instruction *AndI = dyn_cast<Instruction>(BR->getCondition())) {
if (AndI->getOpcode() == Instruction::And) {
ICmpInst *Op0 = dyn_cast<ICmpInst>(AndI->getOperand(0));
ICmpInst *Op1 = dyn_cast<ICmpInst>(AndI->getOperand(1));
if (!Op0 || !Op1)
continue;
if (!safeICmpInst(Op0, SD))
continue;
SD.clear();
if (!safeICmpInst(Op1, SD))
continue;
SD.clear();
SD.SplitCondition = AndI;
SplitData.push_back(SD);
continue;
}
}
ICmpInst *CI = dyn_cast<ICmpInst>(BR->getCondition());
if (!CI || CI == ExitCondition)
continue;
@ -662,6 +700,164 @@ bool LoopIndexSplit::safeExitingBlock(SplitInfo &SD,
return true;
}
void LoopIndexSplit::updateLoopBounds(ICmpInst *CI) {
Value *V0 = CI->getOperand(0);
Value *V1 = CI->getOperand(1);
Value *NV = NULL;
SCEVHandle SH0 = SE->getSCEV(V0);
if (SH0->isLoopInvariant(L))
NV = V0;
else
NV = V1;
switch (CI->getPredicate()) {
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
// for (i = LB; i < UB; ++i)
// if (i <= NV && ...)
// LOOP_BODY
//
// is transformed into
// NUB = min (NV+1, UB)
// for (i = LB; i < NUB ; ++i)
// LOOP_BODY
//
// for (i = LB; i <= UB; ++i)
// if (i <= NV && ...)
// LOOP_BODY
//
// is transformed into
// NUB = min (NV, UB)
// for (i = LB; i <= NUB ; ++i)
// LOOP_BODY
//
break;
case ICmpInst::ICMP_ULT:
case ICmpInst::ICMP_SLT:
// for (i = LB; i < UB; ++i)
// if (i < NV && ...)
// LOOP_BODY
//
// is transformed into
// NUB = min (NV, UB)
// for (i = LB; i < NUB ; ++i)
// LOOP_BODY
//
// for (i = LB; i <= UB; ++i)
// if (i < NV && ...)
// LOOP_BODY
//
// is transformed into
// NUB = min (NV -1 , UB)
// for (i = LB; i <= NUB ; ++i)
// LOOP_BODY
//
break;
case ICmpInst::ICMP_UGE:
case ICmpInst::ICMP_SGE:
// for (i = LB; i (< or <=) UB; ++i)
// if (i >= NV && ...)
// LOOP_BODY
//
// is transformed into
// NLB = max (NV, LB)
// for (i = NLB; i (< or <=) UB ; ++i)
// LOOP_BODY
//
break;
case ICmpInst::ICMP_UGT:
case ICmpInst::ICMP_SGT:
// for (i = LB; i (< or <=) UB; ++i)
// if (i > NV && ...)
// LOOP_BODY
//
// is transformed into
// NLB = max (NV+1, LB)
// for (i = NLB; i (< or <=) UB ; ++i)
// LOOP_BODY
//
break;
default:
assert ( 0 && "Unexpected split condition predicate");
}
}
/// updateLoopIterationSpace - Current loop body is covered by an AND
/// instruction whose operands compares induction variables with loop
/// invariants. If possible, hoist this check outside the loop by
/// updating appropriate start and end values for induction variable.
bool LoopIndexSplit::updateLoopIterationSpace(SplitInfo &SD) {
BasicBlock *Header = L->getHeader();
ICmpInst *Op0 = cast<ICmpInst>(SD.SplitCondition->getOperand(0));
ICmpInst *Op1 = cast<ICmpInst>(SD.SplitCondition->getOperand(1));
if (Op0->getPredicate() == ICmpInst::ICMP_EQ
|| Op0->getPredicate() == ICmpInst::ICMP_NE
|| Op0->getPredicate() == ICmpInst::ICMP_EQ
|| Op0->getPredicate() == ICmpInst::ICMP_NE)
return false;
// Check if SplitCondition dominates entire loop body
// or not.
// If SplitCondition is not in loop header then this loop is not suitable
// for this transformation.
if (SD.SplitCondition->getParent() != Header)
return false;
// If loop header includes loop variant instruction operands then
// this loop may not be eliminated.
Instruction *Terminator = Header->getTerminator();
for(BasicBlock::iterator BI = Header->begin(), BE = Header->end();
BI != BE; ++BI) {
Instruction *I = BI;
// PHI Nodes are OK.
if (isa<PHINode>(I))
continue;
// SplitCondition itself is OK.
if (I == SD.SplitCondition)
continue;
if (I == Op0 || I == Op1)
continue;
// Induction variable is OK.
if (I == IndVar)
continue;
// Induction variable increment is OK.
if (I == IndVarIncrement)
continue;
// Terminator is also harmless.
if (I == Terminator)
continue;
// Otherwise we have a instruction that may not be safe.
return false;
}
// If Exiting block includes loop variant instructions then this
// loop may not be eliminated.
if (!safeExitingBlock(SD, ExitCondition->getParent()))
return false;
updateLoopBounds(Op0);
updateLoopBounds(Op1);
// Update CFG
return true;
}
/// removeBlocks - Remove basic block DeadBB and all blocks dominated by DeadBB.
/// This routine is used to remove split condition's dead branch, dominated by
/// DeadBB. LiveBB dominates split conidition's other branch.