Skip to content

Commit

Permalink
Fix the iteration count for summation reduction
Browse files Browse the repository at this point in the history
Summation reduction in the expressions simplification optimization pass
transforms loops of the following form:

    for (int i = a; i < k; i++) {
        ...
        sum += loopInvariantExpression;
        ...
    }

into a form where the sum is computed via multiplication:

    sum += loopInvariantExpression * k;
    for (int i = 0; i < k; i++) { ... }

For illustration these are written as typical for-loops on the range
[0,k), but summation reduction works on a variety of loops. For example,
the IV (induction variable) may be either increasing or decreasing, and
the loop test may be inclusive or exclusive.

The initial value of the IV, the step amount, and the loop bound must
all be compile-time constants, so that the number of iterations can be
computed at compile time. This is the constant by which to multiply.

In calculating the number of iterations, it's important to know whether
the loop test is inclusive or exclusive, i.e. whether the loop test will
exit the loop when the IV is equal to the loop bound. Expressions
simplification remembers this in LoopInfo::_equals, the value of which
is determined in findLoopInfo(). This _equals is true when the loop
keeps running for an IV equal to the loop bound.

Expressions simplification has been determining _equals with an
assumption that the target of the loop test is outside the loop, e.g.

    ificmpge --> exit
      iload i
      iconst 10

    // loop body

But loop tests can (and often do) have the opposite sense, branching to
remain in the loop, and falling through to exit, e.g.

    ificmplt --> loop
      iload i
      iconst 10

    // exit

As a result, the iteration count could be off by 1 for loops whose tests
are in this form.

Expressions simplification will now inspect the loop test to determine
whether the branch targets the exit, and flip _equals when it does not.

Signed-off-by: Devin Papineau <devinmp@ca.ibm.com>
  • Loading branch information
jdmpapin committed May 16, 2019
1 parent afbd14f commit 6653288
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions compiler/optimizer/ExpressionsSimplification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,9 @@ TR_ExpressionsSimplification::findLoopInfo(TR_RegionStructure* region)
return 0;
}

TR_StructureSubGraphNode* exitNode = toStructureSubGraphNode(exitEdges.getFirst()->getFrom());
TR::CFGEdge *exitEdge = exitEdges.getFirst();
TR_StructureSubGraphNode* exitNode = toStructureSubGraphNode(exitEdge->getFrom());
int32_t exitTarget = exitEdge->getTo()->getNumber();

if (!exitNode->getStructure()->asBlock())
{
Expand Down Expand Up @@ -812,6 +814,12 @@ TR_ExpressionsSimplification::findLoopInfo(TR_RegionStructure* region)
equals = true;
case TR::ificmple:
case TR::ificmpge:
{
TR::TreeTop *branchDestTT = lastTreeInExitBlock->getBranchDestination();
TR::Block *branchDest = branchDestTT->getNode()->getBlock();
if (branchDest->getNumber() != exitTarget)
equals = !equals;

if (!(indVar->getEntry() && indVar->getEntry()->asIntConst()))
{
if (trace())
Expand All @@ -835,7 +843,7 @@ TR_ExpressionsSimplification::findLoopInfo(TR_RegionStructure* region)
return 0;
}
return new (trStackMemory()) LoopInfo(bound, lowerBound, upperBound, increment, equals);

}

default:
if (trace())
Expand Down

0 comments on commit 6653288

Please sign in to comment.