Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix the iteration count for summation reduction
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