[NFC][SCEV] Prepare `createNodeForSelectOrPHI()` for gaining additional strategy

Currently `createNodeForSelectOrPHI()` takes an Instruction,
and only works on the Cond that is an ICmpInst,
but that can be relaxed somewhat.

For now, simply rename the existing function,
and add a thin wrapper ontop that still does
the same thing as it used to.
This commit is contained in:
Roman Lebedev 2022-02-10 14:58:55 +03:00
parent 73990ff8a7
commit 97930f85af
No known key found for this signature in database
GPG Key ID: 083C3EBB4A1689E0
2 changed files with 36 additions and 22 deletions

View File

@ -1622,8 +1622,17 @@ private:
/// is either a select instruction or a phi node). \p I is the instruction
/// being processed, and it is assumed equivalent to "Cond ? TrueVal :
/// FalseVal".
const SCEV *createNodeForSelectOrPHI(Instruction *I, Value *Cond,
Value *TrueVal, Value *FalseVal);
const SCEV *createNodeForSelectOrPHIInstWithICmpInstCond(Instruction *I,
ICmpInst *Cond,
Value *TrueVal,
Value *FalseVal);
/// Given a value \p V, which is a select-like instruction (currently this is
/// either a select instruction or a phi node), which is assumed equivalent to
/// Cond ? TrueVal : FalseVal
/// see if we can model it as a SCEV expression.
const SCEV *createNodeForSelectOrPHI(Value *V, Value *Cond, Value *TrueVal,
Value *FalseVal);
/// Provide the special handling we need to analyze GEP SCEVs.
const SCEV *createNodeForGEP(GEPOperator *GEP);

View File

@ -5887,19 +5887,10 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) {
return getUnknown(PN);
}
const SCEV *ScalarEvolution::createNodeForSelectOrPHI(Instruction *I,
Value *Cond,
Value *TrueVal,
Value *FalseVal) {
// Handle "constant" branch or select. This can occur for instance when a
// loop pass transforms an inner loop and moves on to process the outer loop.
if (auto *CI = dyn_cast<ConstantInt>(Cond))
return getSCEV(CI->isOne() ? TrueVal : FalseVal);
const SCEV *ScalarEvolution::createNodeForSelectOrPHIInstWithICmpInstCond(
Instruction *I, ICmpInst *Cond, Value *TrueVal, Value *FalseVal) {
// Try to match some simple smax or umax patterns.
auto *ICI = dyn_cast<ICmpInst>(Cond);
if (!ICI)
return getUnknown(I);
auto *ICI = Cond;
Value *LHS = ICI->getOperand(0);
Value *RHS = ICI->getOperand(1);
@ -5995,6 +5986,26 @@ const SCEV *ScalarEvolution::createNodeForSelectOrPHI(Instruction *I,
return getUnknown(I);
}
const SCEV *ScalarEvolution::createNodeForSelectOrPHI(Value *V, Value *Cond,
Value *TrueVal,
Value *FalseVal) {
auto *I = dyn_cast<Instruction>(V);
if (!I)
return getUnknown(V);
// Handle "constant" branch or select. This can occur for instance when a
// loop pass transforms an inner loop and moves on to process the outer loop.
if (auto *CI = dyn_cast<ConstantInt>(Cond))
return getSCEV(CI->isOne() ? TrueVal : FalseVal);
// Try to match some simple smax or umax patterns.
if (auto *ICI = dyn_cast<ICmpInst>(Cond))
return createNodeForSelectOrPHIInstWithICmpInstCond(I, ICI, TrueVal,
FalseVal);
return getUnknown(V);
}
/// Expand GEP instructions into add and multiply operations. This allows them
/// to be analyzed by regular SCEV code.
const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) {
@ -7403,14 +7414,8 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
return createNodeForPHI(cast<PHINode>(U));
case Instruction::Select:
// U can also be a select constant expr, which let fall through. Since
// createNodeForSelect only works for a condition that is an `ICmpInst`, and
// constant expressions cannot have instructions as operands, we'd have
// returned getUnknown for a select constant expressions anyway.
if (isa<Instruction>(U))
return createNodeForSelectOrPHI(cast<Instruction>(U), U->getOperand(0),
U->getOperand(1), U->getOperand(2));
break;
return createNodeForSelectOrPHI(U, U->getOperand(0), U->getOperand(1),
U->getOperand(2));
case Instruction::Call:
case Instruction::Invoke: