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:
Chris Lattner 2005-08-13 07:27:18 +00:00
parent dc3154ec66
commit 5949d49032
1 changed files with 61 additions and 28 deletions

View File

@ -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;
}