mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-04 18:24:38 +00:00
indvars -disable-iv-rewrite: avoid multiple IVs in weird cases.
Putting back the helper that I removed on 7/1 to do this right. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134423 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -608,6 +608,8 @@ protected:
|
|||||||
Instruction *NarrowDef,
|
Instruction *NarrowDef,
|
||||||
Instruction *WideDef);
|
Instruction *WideDef);
|
||||||
|
|
||||||
|
const SCEVAddRecExpr *GetWideRecurrence(Instruction *NarrowUse);
|
||||||
|
|
||||||
Instruction *WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
Instruction *WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
||||||
Instruction *WideDef);
|
Instruction *WideDef);
|
||||||
|
|
||||||
@ -704,6 +706,33 @@ static bool HoistStep(Instruction *IncV, Instruction *InsertPos,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetWideRecurrence - Is this instruction potentially interesting from IVUsers'
|
||||||
|
// perspective after widening it's type? In other words, can the extend be
|
||||||
|
// safely hoisted out of the loop with SCEV reducing the value to a recurrence
|
||||||
|
// on the same loop. If so, return the sign or zero extended
|
||||||
|
// recurrence. Otherwise return NULL.
|
||||||
|
const SCEVAddRecExpr *WidenIV::GetWideRecurrence(Instruction *NarrowUse) {
|
||||||
|
if (!SE->isSCEVable(NarrowUse->getType()))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const SCEV *NarrowExpr = SE->getSCEV(NarrowUse);
|
||||||
|
if (SE->getTypeSizeInBits(NarrowExpr->getType())
|
||||||
|
>= SE->getTypeSizeInBits(WideType)) {
|
||||||
|
// NarrowUse implicitly widens its operand. e.g. a gep with a narrow
|
||||||
|
// index. So don't follow this use.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SCEV *WideExpr = IsSigned ?
|
||||||
|
SE->getSignExtendExpr(NarrowExpr, WideType) :
|
||||||
|
SE->getZeroExtendExpr(NarrowExpr, WideType);
|
||||||
|
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(WideExpr);
|
||||||
|
if (!AddRec || AddRec->getLoop() != L)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return AddRec;
|
||||||
|
}
|
||||||
|
|
||||||
/// WidenIVUse - Determine whether an individual user of the narrow IV can be
|
/// WidenIVUse - Determine whether an individual user of the narrow IV can be
|
||||||
/// widened. If so, return the wide clone of the user.
|
/// widened. If so, return the wide clone of the user.
|
||||||
Instruction *WidenIV::WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
Instruction *WidenIV::WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
||||||
@ -753,24 +782,7 @@ Instruction *WidenIV::WidenIVUse(Use &NarrowDefUse, Instruction *NarrowDef,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Does this user itself evaluate to a recurrence after widening?
|
// Does this user itself evaluate to a recurrence after widening?
|
||||||
const SCEVAddRecExpr *WideAddRec = 0;
|
const SCEVAddRecExpr *WideAddRec = GetWideRecurrence(NarrowUse);
|
||||||
if (SE->isSCEVable(NarrowUse->getType())) {
|
|
||||||
const SCEV *NarrowExpr = SE->getSCEV(NarrowUse);
|
|
||||||
if (SE->getTypeSizeInBits(NarrowExpr->getType())
|
|
||||||
>= SE->getTypeSizeInBits(WideType)) {
|
|
||||||
// NarrowUse implicitly widens its operand. e.g. a gep with a narrow
|
|
||||||
// index. We have already extended the operand, so we're done.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const SCEV *WideExpr = IsSigned ?
|
|
||||||
SE->getSignExtendExpr(NarrowExpr, WideType) :
|
|
||||||
SE->getZeroExtendExpr(NarrowExpr, WideType);
|
|
||||||
|
|
||||||
// Only widen past values that evaluate to a recurrence in the same loop.
|
|
||||||
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(WideExpr);
|
|
||||||
if (AddRec && AddRec->getLoop() == L)
|
|
||||||
WideAddRec = AddRec;
|
|
||||||
}
|
|
||||||
if (!WideAddRec) {
|
if (!WideAddRec) {
|
||||||
// This user does not evaluate to a recurence after widening, so don't
|
// This user does not evaluate to a recurence after widening, so don't
|
||||||
// follow it. Instead insert a Trunc to kill off the original use,
|
// follow it. Instead insert a Trunc to kill off the original use,
|
||||||
|
Reference in New Issue
Block a user