mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 18:31:04 +00:00
indvars: Added canExpandBackEdgeTakenCount.
Only create a canonical IV for backedge taken count if it will actually be used by LinearFunctionTestReplace. And some related cleanup, preparing to reduce dependence on canonical IVs. No significant effect on x86 or arm in the test-suite. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130799 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ee4a3abede
commit
4dfdf242c1
@ -105,11 +105,12 @@ namespace {
|
|||||||
void EliminateIVRemainders();
|
void EliminateIVRemainders();
|
||||||
void RewriteNonIntegerIVs(Loop *L);
|
void RewriteNonIntegerIVs(Loop *L);
|
||||||
|
|
||||||
|
bool canExpandBackedgeTakenCount(Loop *L,
|
||||||
|
const SCEV *BackedgeTakenCount);
|
||||||
|
|
||||||
ICmpInst *LinearFunctionTestReplace(Loop *L, const SCEV *BackedgeTakenCount,
|
ICmpInst *LinearFunctionTestReplace(Loop *L, const SCEV *BackedgeTakenCount,
|
||||||
PHINode *IndVar,
|
PHINode *IndVar,
|
||||||
BasicBlock *ExitingBlock,
|
SCEVExpander &Rewriter);
|
||||||
BranchInst *BI,
|
|
||||||
SCEVExpander &Rewriter);
|
|
||||||
void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
|
void RewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
|
||||||
|
|
||||||
void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter);
|
void RewriteIVExpressions(Loop *L, SCEVExpander &Rewriter);
|
||||||
@ -183,17 +184,24 @@ bool IndVarSimplify::isValidRewrite(Value *FromVal, Value *ToVal) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// LinearFunctionTestReplace - This method rewrites the exit condition of the
|
/// canExpandBackedgeTakenCount - Return true if this loop's backedge taken
|
||||||
/// loop to be a canonical != comparison against the incremented loop induction
|
/// count expression can be safely and cheaply expanded into an instruction
|
||||||
/// variable. This pass is able to rewrite the exit tests of any loop where the
|
/// sequence that can be used by LinearFunctionTestReplace.
|
||||||
/// SCEV analysis can determine a loop-invariant trip count of the loop, which
|
bool IndVarSimplify::
|
||||||
/// is actually a much broader range than just linear tests.
|
canExpandBackedgeTakenCount(Loop *L,
|
||||||
ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
const SCEV *BackedgeTakenCount) {
|
||||||
const SCEV *BackedgeTakenCount,
|
if (isa<SCEVCouldNotCompute>(BackedgeTakenCount) ||
|
||||||
PHINode *IndVar,
|
BackedgeTakenCount->isZero())
|
||||||
BasicBlock *ExitingBlock,
|
return false;
|
||||||
BranchInst *BI,
|
|
||||||
SCEVExpander &Rewriter) {
|
if (!L->getExitingBlock())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Can't rewrite non-branch yet.
|
||||||
|
BranchInst *BI = dyn_cast<BranchInst>(L->getExitingBlock()->getTerminator());
|
||||||
|
if (!BI)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Special case: If the backedge-taken count is a UDiv, it's very likely a
|
// Special case: If the backedge-taken count is a UDiv, it's very likely a
|
||||||
// UDiv that ScalarEvolution produced in order to compute a precise
|
// UDiv that ScalarEvolution produced in order to compute a precise
|
||||||
// expression, rather than a UDiv from the user's code. If we can't find a
|
// expression, rather than a UDiv from the user's code. If we can't find a
|
||||||
@ -208,16 +216,31 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
|||||||
const SCEV *L = SE->getSCEV(OrigCond->getOperand(0));
|
const SCEV *L = SE->getSCEV(OrigCond->getOperand(0));
|
||||||
L = SE->getMinusSCEV(L, SE->getConstant(L->getType(), 1));
|
L = SE->getMinusSCEV(L, SE->getConstant(L->getType(), 1));
|
||||||
if (L != BackedgeTakenCount)
|
if (L != BackedgeTakenCount)
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// LinearFunctionTestReplace - This method rewrites the exit condition of the
|
||||||
|
/// loop to be a canonical != comparison against the incremented loop induction
|
||||||
|
/// variable. This pass is able to rewrite the exit tests of any loop where the
|
||||||
|
/// SCEV analysis can determine a loop-invariant trip count of the loop, which
|
||||||
|
/// is actually a much broader range than just linear tests.
|
||||||
|
ICmpInst *IndVarSimplify::
|
||||||
|
LinearFunctionTestReplace(Loop *L,
|
||||||
|
const SCEV *BackedgeTakenCount,
|
||||||
|
PHINode *IndVar,
|
||||||
|
SCEVExpander &Rewriter) {
|
||||||
|
assert(canExpandBackedgeTakenCount(L, BackedgeTakenCount) && "precondition");
|
||||||
|
BranchInst *BI = cast<BranchInst>(L->getExitingBlock()->getTerminator());
|
||||||
|
|
||||||
// If the exiting block is not the same as the backedge block, we must compare
|
// If the exiting block is not the same as the backedge block, we must compare
|
||||||
// against the preincremented value, otherwise we prefer to compare against
|
// against the preincremented value, otherwise we prefer to compare against
|
||||||
// the post-incremented value.
|
// the post-incremented value.
|
||||||
Value *CmpIndVar;
|
Value *CmpIndVar;
|
||||||
const SCEV *RHS = BackedgeTakenCount;
|
const SCEV *RHS = BackedgeTakenCount;
|
||||||
if (ExitingBlock == L->getLoopLatch()) {
|
if (L->getExitingBlock() == L->getLoopLatch()) {
|
||||||
// Add one to the "backedge-taken" count to get the trip count.
|
// Add one to the "backedge-taken" count to get the trip count.
|
||||||
// If this addition may overflow, we have to be more pessimistic and
|
// If this addition may overflow, we have to be more pessimistic and
|
||||||
// cast the induction variable before doing the add.
|
// cast the induction variable before doing the add.
|
||||||
@ -240,7 +263,7 @@ ICmpInst *IndVarSimplify::LinearFunctionTestReplace(Loop *L,
|
|||||||
// The BackedgeTaken expression contains the number of times that the
|
// The BackedgeTaken expression contains the number of times that the
|
||||||
// backedge branches to the loop header. This is one less than the
|
// backedge branches to the loop header. This is one less than the
|
||||||
// number of times the loop executes, so use the incremented indvar.
|
// number of times the loop executes, so use the incremented indvar.
|
||||||
CmpIndVar = IndVar->getIncomingValueForBlock(ExitingBlock);
|
CmpIndVar = IndVar->getIncomingValueForBlock(L->getExitingBlock());
|
||||||
} else {
|
} else {
|
||||||
// We have to use the preincremented value...
|
// We have to use the preincremented value...
|
||||||
RHS = SE->getTruncateOrZeroExtend(BackedgeTakenCount,
|
RHS = SE->getTruncateOrZeroExtend(BackedgeTakenCount,
|
||||||
@ -533,7 +556,6 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
// transform them to use integer recurrences.
|
// transform them to use integer recurrences.
|
||||||
RewriteNonIntegerIVs(L);
|
RewriteNonIntegerIVs(L);
|
||||||
|
|
||||||
BasicBlock *ExitingBlock = L->getExitingBlock(); // may be null
|
|
||||||
const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
const SCEV *BackedgeTakenCount = SE->getBackedgeTakenCount(L);
|
||||||
|
|
||||||
// Create a rewriter object which we'll use to transform the code with.
|
// Create a rewriter object which we'll use to transform the code with.
|
||||||
@ -558,23 +580,26 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
// a canonical induction variable should be inserted.
|
// a canonical induction variable should be inserted.
|
||||||
const Type *LargestType = 0;
|
const Type *LargestType = 0;
|
||||||
bool NeedCannIV = false;
|
bool NeedCannIV = false;
|
||||||
if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount)) {
|
bool ExpandBECount = canExpandBackedgeTakenCount(L, BackedgeTakenCount);
|
||||||
LargestType = BackedgeTakenCount->getType();
|
if (ExpandBECount) {
|
||||||
LargestType = SE->getEffectiveSCEVType(LargestType);
|
|
||||||
// If we have a known trip count and a single exit block, we'll be
|
// If we have a known trip count and a single exit block, we'll be
|
||||||
// rewriting the loop exit test condition below, which requires a
|
// rewriting the loop exit test condition below, which requires a
|
||||||
// canonical induction variable.
|
// canonical induction variable.
|
||||||
if (ExitingBlock)
|
NeedCannIV = true;
|
||||||
NeedCannIV = true;
|
const Type *Ty = BackedgeTakenCount->getType();
|
||||||
|
if (!LargestType ||
|
||||||
|
SE->getTypeSizeInBits(Ty) >
|
||||||
|
SE->getTypeSizeInBits(LargestType))
|
||||||
|
LargestType = SE->getEffectiveSCEVType(Ty);
|
||||||
}
|
}
|
||||||
for (IVUsers::const_iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
|
for (IVUsers::const_iterator I = IU->begin(), E = IU->end(); I != E; ++I) {
|
||||||
|
NeedCannIV = true;
|
||||||
const Type *Ty =
|
const Type *Ty =
|
||||||
SE->getEffectiveSCEVType(I->getOperandValToReplace()->getType());
|
SE->getEffectiveSCEVType(I->getOperandValToReplace()->getType());
|
||||||
if (!LargestType ||
|
if (!LargestType ||
|
||||||
SE->getTypeSizeInBits(Ty) >
|
SE->getTypeSizeInBits(Ty) >
|
||||||
SE->getTypeSizeInBits(LargestType))
|
SE->getTypeSizeInBits(LargestType))
|
||||||
LargestType = Ty;
|
LargestType = Ty;
|
||||||
NeedCannIV = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we know the largest of the induction variable expressions
|
// Now that we know the largest of the induction variable expressions
|
||||||
@ -614,15 +639,13 @@ bool IndVarSimplify::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
// If we have a trip count expression, rewrite the loop's exit condition
|
// If we have a trip count expression, rewrite the loop's exit condition
|
||||||
// using it. We can currently only handle loops with a single exit.
|
// using it. We can currently only handle loops with a single exit.
|
||||||
ICmpInst *NewICmp = 0;
|
ICmpInst *NewICmp = 0;
|
||||||
if (!isa<SCEVCouldNotCompute>(BackedgeTakenCount) &&
|
if (ExpandBECount) {
|
||||||
!BackedgeTakenCount->isZero() &&
|
assert(canExpandBackedgeTakenCount(L, BackedgeTakenCount) &&
|
||||||
ExitingBlock) {
|
"canonical IV disrupted BackedgeTaken expansion");
|
||||||
assert(NeedCannIV &&
|
assert(NeedCannIV &&
|
||||||
"LinearFunctionTestReplace requires a canonical induction variable");
|
"LinearFunctionTestReplace requires a canonical induction variable");
|
||||||
// Can't rewrite non-branch yet.
|
NewICmp = LinearFunctionTestReplace(L, BackedgeTakenCount, IndVar,
|
||||||
if (BranchInst *BI = dyn_cast<BranchInst>(ExitingBlock->getTerminator()))
|
Rewriter);
|
||||||
NewICmp = LinearFunctionTestReplace(L, BackedgeTakenCount, IndVar,
|
|
||||||
ExitingBlock, BI, Rewriter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite IV-derived expressions.
|
// Rewrite IV-derived expressions.
|
||||||
|
Loading…
Reference in New Issue
Block a user