forked from OSchip/llvm-project
Recursively scan scev expressions for common subexpressions. This allows us
to handle nested loops much better, for example, by being able to tell that these two expressions: {( 8 + ( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp 12)}<loopentry.1> {(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1> Have the following common part that can be shared: {(( 16 * ( 1 + %Tmp11 + %Tmp12)) + %c_),+,( 16 * %Tmp12)}<loopentry.1> This allows us to codegen an important inner loop in 168.wupwise as: .LBB_foo_4: ; no_exit.1 lfd f2, 16(r9) fmul f3, f0, f2 fmul f2, f1, f2 fadd f4, f3, f2 stfd f4, 8(r9) fsub f2, f3, f2 stfd f2, 16(r9) addi r8, r8, 1 addi r9, r9, 16 cmpw cr0, r8, r4 ble .LBB_foo_4 ; no_exit.1 instead of: .LBB_foo_3: ; no_exit.1 lfdx f2, r6, r9 add r10, r6, r9 lfd f3, 8(r10) fmul f4, f1, f2 fmadd f4, f0, f3, f4 stfd f4, 8(r10) fmul f3, f1, f3 fmsub f2, f0, f2, f3 stfdx f2, r6, r9 addi r9, r9, 16 addi r8, r8, 1 cmpw cr0, r8, r4 ble .LBB_foo_3 ; no_exit.1 llvm-svn: 22781
This commit is contained in:
parent
dc3154ec66
commit
5949d49032
|
@ -593,6 +593,36 @@ static void MoveImmediateValues(SCEVHandle &Val, SCEVHandle &Imm,
|
|||
// Otherwise, no immediates to move.
|
||||
}
|
||||
|
||||
|
||||
/// IncrementAddExprUses - Decompose the specified expression into its added
|
||||
/// subexpressions, and increment SubExpressionUseCounts for each of these
|
||||
/// decomposed parts.
|
||||
static void SeparateSubExprs(std::vector<SCEVHandle> &SubExprs,
|
||||
SCEVHandle Expr) {
|
||||
if (SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Expr)) {
|
||||
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
|
||||
SeparateSubExprs(SubExprs, AE->getOperand(j));
|
||||
} else if (SCEVAddRecExpr *SARE = dyn_cast<SCEVAddRecExpr>(Expr)) {
|
||||
SCEVHandle Zero = SCEVUnknown::getIntegerSCEV(0, Expr->getType());
|
||||
if (SARE->getOperand(0) == Zero) {
|
||||
SubExprs.push_back(Expr);
|
||||
} else {
|
||||
// Compute the addrec with zero as its base.
|
||||
std::vector<SCEVHandle> Ops(SARE->op_begin(), SARE->op_end());
|
||||
Ops[0] = Zero; // Start with zero base.
|
||||
SubExprs.push_back(SCEVAddRecExpr::get(Ops, SARE->getLoop()));
|
||||
|
||||
|
||||
SeparateSubExprs(SubExprs, SARE->getOperand(0));
|
||||
}
|
||||
} else if (!isa<SCEVConstant>(Expr) ||
|
||||
!cast<SCEVConstant>(Expr)->getValue()->isNullValue()) {
|
||||
// Do not add zero.
|
||||
SubExprs.push_back(Expr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// RemoveCommonExpressionsFromUseBases - Look through all of the uses in Bases,
|
||||
/// removing any common subexpressions from it. Anything truly common is
|
||||
/// removed, accumulated, and returned. This looks for things like (a+b+c) and
|
||||
|
@ -613,17 +643,21 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses) {
|
|||
// If any subexpressions are used Uses.size() times, they are common.
|
||||
std::map<SCEVHandle, unsigned> SubExpressionUseCounts;
|
||||
|
||||
for (unsigned i = 0; i != NumUses; ++i)
|
||||
if (SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Uses[i].Base)) {
|
||||
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
|
||||
SubExpressionUseCounts[AE->getOperand(j)]++;
|
||||
} else {
|
||||
// If the base is zero (which is common), return zero now, there are no
|
||||
// CSEs we can find.
|
||||
if (Uses[i].Base == Zero) return Result;
|
||||
SubExpressionUseCounts[Uses[i].Base]++;
|
||||
}
|
||||
|
||||
std::vector<SCEVHandle> SubExprs;
|
||||
for (unsigned i = 0; i != NumUses; ++i) {
|
||||
// If the base is zero (which is common), return zero now, there are no
|
||||
// CSEs we can find.
|
||||
if (Uses[i].Base == Zero) return Zero;
|
||||
|
||||
// Split the expression into subexprs.
|
||||
SeparateSubExprs(SubExprs, Uses[i].Base);
|
||||
// Add one to SubExpressionUseCounts for each subexpr present.
|
||||
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
|
||||
SubExpressionUseCounts[SubExprs[j]]++;
|
||||
SubExprs.clear();
|
||||
}
|
||||
|
||||
|
||||
// Now that we know how many times each is used, build Result.
|
||||
for (std::map<SCEVHandle, unsigned>::iterator I =
|
||||
SubExpressionUseCounts.begin(), E = SubExpressionUseCounts.end();
|
||||
|
@ -640,24 +674,23 @@ RemoveCommonExpressionsFromUseBases(std::vector<BasedUser> &Uses) {
|
|||
if (Result == Zero) return Result;
|
||||
|
||||
// Otherwise, remove all of the CSE's we found from each of the base values.
|
||||
for (unsigned i = 0; i != NumUses; ++i)
|
||||
if (SCEVAddExpr *AE = dyn_cast<SCEVAddExpr>(Uses[i].Base)) {
|
||||
std::vector<SCEVHandle> NewOps;
|
||||
|
||||
// Remove all of the values that are now in SubExpressionUseCounts.
|
||||
for (unsigned j = 0, e = AE->getNumOperands(); j != e; ++j)
|
||||
if (!SubExpressionUseCounts.count(AE->getOperand(j)))
|
||||
NewOps.push_back(AE->getOperand(j));
|
||||
if (NewOps.empty())
|
||||
Uses[i].Base = Zero;
|
||||
else
|
||||
Uses[i].Base = SCEVAddExpr::get(NewOps);
|
||||
} else {
|
||||
// If the base is zero (which is common), return zero now, there are no
|
||||
// CSEs we can find.
|
||||
assert(Uses[i].Base == Result);
|
||||
for (unsigned i = 0; i != NumUses; ++i) {
|
||||
// Split the expression into subexprs.
|
||||
SeparateSubExprs(SubExprs, Uses[i].Base);
|
||||
|
||||
// Remove any common subexpressions.
|
||||
for (unsigned j = 0, e = SubExprs.size(); j != e; ++j)
|
||||
if (SubExpressionUseCounts.count(SubExprs[j])) {
|
||||
SubExprs.erase(SubExprs.begin()+j);
|
||||
--j; --e;
|
||||
}
|
||||
|
||||
// Finally, the non-shared expressions together.
|
||||
if (SubExprs.empty())
|
||||
Uses[i].Base = Zero;
|
||||
}
|
||||
else
|
||||
Uses[i].Base = SCEVAddExpr::get(SubExprs);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue