// We optimize only the inner loop. It turns into `if (n < 0) then closed else closed + n`. // Potentially we can also update the outer loop turning into if (m < 0) then 0 else if (n < 0) // then 0 else m * n`. /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (before) /// CHECK: Phi /// CHECK: Phi /// CHECK: Phi /// CHECK: Phi /// CHECK-NOT: Phi // /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (after) /// CHECK: Phi /// CHECK: Phi /// CHECK-NOT: Phi // // Inner loop optimization /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (after) /// CHECK-DAG: <<M:i\d+>> ParameterValue /// CHECK-DAG: <<N:i\d+>> ParameterValue /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Phi:i\d+>> Phi /// CHECK-DAG: <<Add:i\d+>> Add [<<N>>,<<Phi>>] /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] /// CHECK-DAG: <<Sel:i\d+>> Select [<<Phi>>,<<Add>>,<<LT>>] staticint closedFormNestedMN(int m, int n) { int closed = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) {
closed++;
}
} return closed; // only needs last-value
}
// We optimize only the inner loop. It turns into `if (n < 0) then closed else closed + n * 7`. // Potentially we can also update the outer loop turning into if (m < 0) then 0 else if (n < 0) // then 1245 else 12345 + m * n * 7`. /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (before) /// CHECK: Phi /// CHECK: Phi /// CHECK: Phi /// CHECK: Phi /// CHECK-NOT: Phi // /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (after) /// CHECK: Phi /// CHECK: Phi /// CHECK-NOT: Phi // // Inner loop optimization /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (after) /// CHECK-DAG: <<M:i\d+>> ParameterValue /// CHECK-DAG: <<N:i\d+>> ParameterValue /// CHECK-DAG: <<Int7:i\d+>> IntConstant 7 /// CHECK-DAG: <<Int0:i\d+>> IntConstant 0 /// CHECK-DAG: <<Phi:i\d+>> Phi /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Int7>>,<<N>>] /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Phi>>] /// CHECK-DAG: <<LT:z\d+>> LessThan [<<Int0>>,<<N>>] /// CHECK-DAG: <<Sel:i\d+>> Select [<<Phi>>,<<Add>>,<<LT>>] staticint closedFormNestedMNAlt(int m, int n) { int closed = 12345; for (int i = 0; i < m; i++) { // if n < 0 then closed else closed + n * 7 for (int j = 0; j < n; j++) {
closed += 7;
}
} return closed; // only needs last-value
}
/// CHECK-START: int Main.mainIndexReturned() loop_optimization (before) /// CHECK-DAG: <<Phi:i\d+>> Phi loop:{{B\d+}} outer_loop:none /// CHECK-DAG: Return [<<Phi>>] loop:none // /// CHECK-START: int Main.mainIndexReturned() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexReturned() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none staticint mainIndexReturned() { int i; for (i = 0; i < 10; i++); return i;
}
/// CHECK-START: int Main.periodicReturned9() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.periodicReturned9() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.periodicReturned9() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 1 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none staticint periodicReturned9() { int k = 0; for (int i = 0; i < 9; i++) {
k = 1 - k;
} return k;
}
/// CHECK-START: int Main.periodicReturned10() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.periodicReturned10() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.periodicReturned10() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 0 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none staticint periodicReturned10() { int k = 0; for (int i = 0; i < 10; i++) {
k = 1 - k;
} return k;
}
/// CHECK-START: int Main.getSum21() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi2>>] loop:none // /// CHECK-START: int Main.getSum21() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.getSum21() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 21 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none privatestaticint getSum21() { int k = 0; int sum = 0; for (int i = 0; i < 6; i++) {
k++;
sum += k;
} return sum;
}
// Ensure double induction does not "overshoot" the subscript range. privatestaticint getIncr2(int[] arr) { for (int i = 0; i < 12; ) {
arr[i++] = 30;
arr[i++] = 29;
} int sum = 0; for (int i = 0; i < 12; i++) {
sum += arr[i];
} return sum;
}
// We can generate a select, which then DCE detects it is redundant. Therefore, we eliminate // these loops.
/// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (before) /// CHECK: Phi /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (after) /// CHECK: Select staticint mainIndexReturnedN(int n) { int i; for (i = 0; i < n; i++); return i;
}
/// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (before) /// CHECK: Phi /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (after) /// CHECK: Select staticint mainIndexShort1(short s) { int i = 0; for (i = 0; i < s; i++) { } return i;
}
/// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (before) /// CHECK: Phi /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (after) /// CHECK: Select staticint mainIndexShort2(short s) { int i = 0; for (i = 0; s > i; i++) { } return i;
}
/// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.periodicReturnedN(int) loop_optimization (after) /// CHECK-NOT: Phi staticint periodicReturnedN(int n) { int k = 0; for (int i = 0; i < n; i++) {
k = 1 - k;
} return k;
}
/// CHECK-START: int Main.periodicOverflowTripCountNotOptimized() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.periodicOverflowTripCountNotOptimized() loop_optimization (after) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none staticint periodicOverflowTripCountNotOptimized() { int k = 0; for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE - 81; i += 80) {
k = 1 - k;
} return k;
}
/// CHECK-START: int Main.periodicCouldOverflowTripCountNotOptimized(int) loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.periodicCouldOverflowTripCountNotOptimized(int) loop_optimization (after) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: {{i\d+}} Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none staticint periodicCouldOverflowTripCountNotOptimized(int start) { int k = 0; for (int i = start; i < Integer.MAX_VALUE - 81; i += 80) {
k = 1 - k;
} return k;
}
// If ever replaced by closed form, last value should be correct! privatestaticint getSumN(int n) { int k = 0; int sum = 0; for (int i = 0; i < n; i++) {
k++;
sum += k;
} return sum;
}
// If ever replaced by closed form, last value should be correct! privatestaticint closedTwice() { int closed = 0; for (int i = 0; i < 10; i++) {
closed++;
} // Closed form of first loop defines trip count of second loop. int other_closed = 0; for (int i = 0; i < closed; i++) {
other_closed++;
} return other_closed;
}
/// CHECK-START: int Main.closedFeed() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop2>> outer_loop:none /// CHECK-DAG: Return [<<Phi3>>] loop:none /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" // /// CHECK-START: int Main.closedFeed() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.closedFeed() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 20 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none privatestaticint closedFeed() { int closed = 0; for (int i = 0; i < 10; i++) {
closed++;
} // Closed form of first loop feeds into initial value of second loop, // used when generating closed form for the latter. for (int i = 0; i < 10; i++) {
closed++;
} return closed;
}
// Checks that we do not loop optimize if the calculation of the trip count would overflow. /// CHECK-START: int Main.closedLinearStepOverflow() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.closedLinearStepOverflow() loop_optimization (after) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none privatestaticint closedLinearStepOverflow() { int closed = 0; // Note that this isn't a "one-off" error. // We are using MIN and MAX to make sure we overflow. for (int i = Integer.MIN_VALUE; i < (Integer.MAX_VALUE - 80); i += 79) {
closed++;
} return closed;
}
// Since we cannot guarantee that the start/end wouldn't overflow we do not perform loop // optimization. /// CHECK-START: int Main.$inline$closedByParameters(int, int) loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.$inline$closedByParameters(int, int) loop_optimization (after) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none privatestaticint $inline$closedByParameters(int start, int end) { int closed = 0; for (int i = start; i < end; i++) {
closed++;
} return closed;
}
// Since we are inlining `closedByParameters` we know that the parameters are fixed and // therefore we can perform loop optimization. /// CHECK-START: int Main.closedByParametersWithInline() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none /// CHECK-DAG: Return [<<Phi1>>] loop:none // /// CHECK-START: int Main.closedByParametersWithInline() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.closedByParametersWithInline() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 10 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none privatestaticint closedByParametersWithInline() { return $inline$closedByParameters(0, 10);
}
/// CHECK-START: int Main.waterFall() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop2:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi3:i\d+>> Phi loop:<<Loop3:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi4:i\d+>> Phi loop:<<Loop4:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi5:i\d+>> Phi loop:<<Loop5:B\d+>> outer_loop:none /// CHECK-DAG: Return [<<Phi5>>] loop:none // /// CHECK-START: int Main.waterFall() loop_optimization (after) /// CHECK-NOT: Phi // /// CHECK-START: int Main.waterFall() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <<Int:i\d+>> IntConstant 50 loop:none /// CHECK-DAG: Return [<<Int>>] loop:none privatestaticint waterFall() { int i = 0; for (; i < 10; i++); for (; i < 20; i++); for (; i < 30; i++); for (; i < 40; i++); for (; i < 50; i++); return i; // this should become just 50
}
privatestaticint exceptionExitBeforeAdd() { int k = 0; try { for (int i = 0; i < 10; i++) {
a[i] = 0;
k += 10; // increment last
}
} catch (Exception e) { // Flag error by returning current // value of k negated. return -k - 1;
} return k;
}
privatestaticint exceptionExitAfterAdd() { int k = 0; try { for (int i = 0; i < 10; i++) {
k += 10; // increment first
a[i] = 0;
}
} catch (Exception e) { // Flag error by returning current // value of k negated. return -k - 1;
} return k;
}
/// CHECK-START: long Main.closedLinearInductionUnmatchedTypesNotOptimized() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:j\d+>> Phi loop:<<Loop>> outer_loop:none // /// CHECK-START: long Main.closedLinearInductionUnmatchedTypesNotOptimized() loop_optimization (after) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:j\d+>> Phi loop:<<Loop>> outer_loop:none privatestaticlong closedLinearInductionUnmatchedTypesNotOptimized() { long sum = 0; for (int i = 0; i < 10; ++i) {
++sum;
} return sum;
}
/// CHECK-START: short Main.closedLinearInductionNarrowingNotOptimized() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none // /// CHECK-START: short Main.closedLinearInductionNarrowingNotOptimized() loop_optimization (after) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none privatestaticshort closedLinearInductionNarrowingNotOptimized() { short i = 0; for (; i < 10; ++i); return i;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.