forked from OSchip/llvm-project
Canonicalize multiplies by looking at whether the operands have any constants themselves. Patch by Tim Murray!
llvm-svn: 223554
This commit is contained in:
parent
2163b05d8e
commit
05044c248e
|
@ -2207,6 +2207,25 @@ static uint64_t Choose(uint64_t n, uint64_t k, bool &Overflow) {
|
|||
return r;
|
||||
}
|
||||
|
||||
/// Determine if any of the operands in this SCEV are a constant or if
|
||||
/// any of the add or multiply expressions in this SCEV contain a constant.
|
||||
static bool containsConstantSomewhere(const SCEV *StartExpr) {
|
||||
SmallVector<const SCEV *, 4> Ops;
|
||||
Ops.push_back(StartExpr);
|
||||
while (!Ops.empty()) {
|
||||
const SCEV *CurrentExpr = Ops.pop_back_val();
|
||||
if (isa<SCEVConstant>(*CurrentExpr))
|
||||
return true;
|
||||
|
||||
if (isa<SCEVAddExpr>(*CurrentExpr) || isa<SCEVMulExpr>(*CurrentExpr)) {
|
||||
const auto *CurrentNAry = cast<SCEVNAryExpr>(CurrentExpr);
|
||||
for (const SCEV *Operand : CurrentNAry->operands())
|
||||
Ops.push_back(Operand);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getMulExpr - Get a canonical multiply expression, or something simpler if
|
||||
/// possible.
|
||||
const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
|
||||
|
@ -2246,11 +2265,13 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
|
|||
|
||||
// C1*(C2+V) -> C1*C2 + C1*V
|
||||
if (Ops.size() == 2)
|
||||
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1]))
|
||||
if (Add->getNumOperands() == 2 &&
|
||||
isa<SCEVConstant>(Add->getOperand(0)))
|
||||
return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)),
|
||||
getMulExpr(LHSC, Add->getOperand(1)));
|
||||
if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1]))
|
||||
// If any of Add's ops are Adds or Muls with a constant,
|
||||
// apply this transformation as well.
|
||||
if (Add->getNumOperands() == 2)
|
||||
if (containsConstantSomewhere(Add))
|
||||
return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)),
|
||||
getMulExpr(LHSC, Add->getOperand(1)));
|
||||
|
||||
++Idx;
|
||||
while (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
|
||||
|
|
Loading…
Reference in New Issue