Restructure the {A,+,B}<L> * {C,+,D}<L> folding so that it folds

all applicable addrecs before recursing on getMulExpr, instead of
recursing on getMulExpr for each one.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112433 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2010-08-29 15:16:58 +00:00
parent b8fc62bc58
commit d578a40853

View File

@ -1886,27 +1886,30 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops,
// there are multiple AddRec's with the same loop induction variable being // there are multiple AddRec's with the same loop induction variable being
// multiplied together. If so, we can fold them. // multiplied together. If so, we can fold them.
for (unsigned OtherIdx = Idx+1; for (unsigned OtherIdx = Idx+1;
OtherIdx < Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);++OtherIdx) OtherIdx < Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
if (OtherIdx != Idx) { ++OtherIdx)
const SCEVAddRecExpr *OtherAddRec = cast<SCEVAddRecExpr>(Ops[OtherIdx]); if (AddRecLoop == cast<SCEVAddRecExpr>(Ops[OtherIdx])->getLoop()) {
if (AddRecLoop == OtherAddRec->getLoop()) { // F * G, where F = {A,+,B}<L> and G = {C,+,D}<L> -->
// F * G --> {A,+,B} * {C,+,D} --> {A*C,+,F*D + G*B + B*D} // {A*C,+,F*D + G*B + B*D}<L>
const SCEVAddRecExpr *F = AddRec, *G = OtherAddRec; for (; OtherIdx != Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);
const SCEV *NewStart = getMulExpr(F->getStart(), G->getStart()); ++OtherIdx)
const SCEV *B = F->getStepRecurrence(*this); if (const SCEVAddRecExpr *OtherAddRec =
const SCEV *D = G->getStepRecurrence(*this); dyn_cast<SCEVAddRecExpr>(Ops[OtherIdx]))
const SCEV *NewStep = getAddExpr(getMulExpr(F, D), if (OtherAddRec->getLoop() == AddRecLoop) {
getMulExpr(G, B), const SCEVAddRecExpr *F = AddRec, *G = OtherAddRec;
getMulExpr(B, D)); const SCEV *NewStart = getMulExpr(F->getStart(), G->getStart());
const SCEV *NewAddRec = getAddRecExpr(NewStart, NewStep, const SCEV *B = F->getStepRecurrence(*this);
F->getLoop()); const SCEV *D = G->getStepRecurrence(*this);
if (Ops.size() == 2) return NewAddRec; const SCEV *NewStep = getAddExpr(getMulExpr(F, D),
getMulExpr(G, B),
Ops.erase(Ops.begin()+Idx); getMulExpr(B, D));
Ops.erase(Ops.begin()+OtherIdx-1); const SCEV *NewAddRec = getAddRecExpr(NewStart, NewStep,
Ops.push_back(NewAddRec); F->getLoop());
return getMulExpr(Ops); if (Ops.size() == 2) return NewAddRec;
} Ops[Idx] = AddRec = cast<SCEVAddRecExpr>(NewAddRec);
Ops.erase(Ops.begin() + OtherIdx); --OtherIdx;
}
return getMulExpr(Ops);
} }
// Otherwise couldn't fold anything into this recurrence. Move onto the // Otherwise couldn't fold anything into this recurrence. Move onto the