// // Test on loop optimizations, in particular around geometric induction. // publicclass Main {
/// CHECK-START: int Main.geo1(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Mul loop:<<Loop>> // /// CHECK-START: int Main.geo1(int) loop_optimization (after) /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none /// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none /// CHECK-DAG: Return [<<Add>>] loop:none // /// CHECK-START: int Main.geo1(int) loop_optimization (after) /// CHECK-NOT: Phi publicstaticint geo1(int a) { for (int i = 0; i < 10; i++) {
a *= 10;
} return a;
}
/// CHECK-START: int Main.geo2(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Shl loop:<<Loop>> // /// CHECK-START: int Main.geo2(int) loop_optimization (after) /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none /// CHECK-DAG: <<Int:i\d+>> IntConstant 1024 loop:none /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none /// CHECK-DAG: Return [<<Add>>] loop:none // /// CHECK-START: int Main.geo2(int) loop_optimization (after) /// CHECK-NOT: Phi publicstaticint geo2(int a) { for (int i = 0; i < 10; i++) {
a <<= 1;
} return a;
}
/// CHECK-START: int Main.geo3(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Div loop:<<Loop>> // /// CHECK-START: int Main.geo3(int) loop_optimization (after) /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none /// CHECK-DAG: <<Int:i\d+>> IntConstant 59049 loop:none /// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none /// CHECK-DAG: Return [<<Add>>] loop:none // /// CHECK-START: int Main.geo3(int) loop_optimization (after) /// CHECK-NOT: Phi publicstaticint geo3(int a) { for (int i = 0; i < 10; i++) {
a /= 3;
} return a;
}
/// CHECK-START: int Main.geo4(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Rem loop:<<Loop>> // /// CHECK-START: int Main.geo4(int) loop_optimization (after) /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none /// CHECK-DAG: <<Int:i\d+>> IntConstant 7 loop:none /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none /// CHECK-DAG: Return [<<Rem>>] loop:none // /// CHECK-START: int Main.geo4(int) loop_optimization (after) /// CHECK-NOT: Phi publicstaticint geo4(int a) { for (int i = 0; i < 10; i++) {
a %= 7; // a wrap-around induction
} return a;
}
/// CHECK-START: int Main.geo5() loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Shr loop:<<Loop>> // /// CHECK-START: int Main.geo5() loop_optimization (after) /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none /// CHECK-DAG: Return [<<Add>>] loop:none // /// CHECK-START: int Main.geo5() loop_optimization (after) /// CHECK-NOT: Phi publicstaticint geo5() { int a = 0x7fffffff; for (int i = 0; i < 10; i++) {
a >>= 1;
} return a;
}
// TODO: someday? // /// CHECK-START: int Main.geo1BCE() BCE (before) /// CHECK-DAG: BoundsCheck loop:none /// CHECK-DAG: BoundsCheck loop:{{B\d+}} // /// CHECK-START: int Main.geo1BCE() BCE (after) /// CHECK-DAG: BoundsCheck loop:{{B\d+}} // /// CHECK-START: int Main.geo1BCE() BCE (after) /// CHECK-NOT: BoundsCheck loop:none /// CHECK-NOT: Deoptimize publicstaticint geo1BCE() { int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 25, 26 }; int a = 1; int r = 0; for (int i = 0; i < 3; i++) {
r += x[a];
a *= 5;
} return r;
}
// TODO: someday? // /// CHECK-START: int Main.geo2BCE() BCE (before) /// CHECK-DAG: BoundsCheck loop:none /// CHECK-DAG: BoundsCheck loop:{{B\d+}} // /// CHECK-START: int Main.geo2BCE() BCE (after) /// CHECK-DAG: BoundsCheck loop:{{B\d+}} // /// CHECK-START: int Main.geo2BCE() BCE (after) /// CHECK-NOT: BoundsCheck loop:none /// CHECK-NOT: Deoptimize publicstaticint geo2BCE() { int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 25, 26 }; int a = 1; int r = 0; for (int i = 0; i < 5; i++) {
r += x[a];
a <<= 1;
} return r;
}
/// CHECK-START: int Main.geo3BCE() BCE (before) /// CHECK-DAG: BoundsCheck loop:none /// CHECK-DAG: BoundsCheck loop:{{B\d+}} // /// CHECK-START: int Main.geo3BCE() BCE (after) /// CHECK-NOT: BoundsCheck /// CHECK-NOT: Deoptimize publicstaticint geo3BCE() { int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 25, 26 }; int a = 25; int r = 0; for (int i = 0; i < 100; i++) { // a converges to 0
r += x[a];
a /= 5;
} return r;
}
/// CHECK-START: int Main.geo4BCE() BCE (before) /// CHECK-DAG: BoundsCheck loop:none /// CHECK-DAG: BoundsCheck loop:{{B\d+}} // /// CHECK-START: int Main.geo4BCE() BCE (after) /// CHECK-NOT: BoundsCheck /// CHECK-NOT: Deoptimize publicstaticint geo4BCE() { int[] x = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 19, 20, 21, 22, 23, 24, 25, 26 }; int a = 25; int r = 0; for (int i = 0; i < 100; i++) { // a converges to 0
r += x[a];
a %= 5; // a wrap-around induction
} return r;
}
/// CHECK-START: int Main.geoMulBlackHole(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Mul loop:<<Loop>> // /// CHECK-START: int Main.geoMulBlackHole(int) loop_optimization (after) /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 /// CHECK-DAG: Return [<<Zero>>] // /// CHECK-START: int Main.geoMulBlackHole(int) loop_optimization (after) /// CHECK-NOT: Phi /// CHECK-NOT: Mul publicstaticint geoMulBlackHole(int a) { for (int i = 0; i < 100; i++) {
a *= 10;
} return a;
}
/// CHECK-START: int Main.geoShlBlackHole(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Shl loop:<<Loop>> // /// CHECK-START: int Main.geoShlBlackHole(int) loop_optimization (after) /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 /// CHECK-DAG: Return [<<Zero>>] // /// CHECK-START: int Main.geoShlBlackHole(int) loop_optimization (after) /// CHECK-NOT: Phi /// CHECK-NOT: Shl publicstaticint geoShlBlackHole(int a) { for (int i = 0; i < 100; i++) {
a <<= 1;
} return a;
}
/// CHECK-START: int Main.geoDivBlackHole(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Div loop:<<Loop>> // /// CHECK-START: int Main.geoDivBlackHole(int) loop_optimization (after) /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 /// CHECK-DAG: Return [<<Zero>>] // /// CHECK-START: int Main.geoDivBlackHole(int) loop_optimization (after) /// CHECK-NOT: Phi /// CHECK-NOT: Div publicstaticint geoDivBlackHole(int a) { for (int i = 0; i < 100; i++) {
a /= 10;
} return a;
}
// Even though Rem is already optimized away by the time induction analysis // and the loop optimizer run, the loop is optimized with a trivial // wrap-around induction just as the wrap-around for REM would. // /// CHECK-START: int Main.geoRemBlackHole(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> /// CHECK-DAG: Phi loop:<<Loop>> // /// CHECK-START: int Main.geoRemBlackHole(int) loop_optimization (after) /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 /// CHECK-DAG: Return [<<Zero>>] // /// CHECK-START: int Main.geoRemBlackHole(int) loop_optimization (after) /// CHECK-NOT: Phi publicstaticint geoRemBlackHole(int a) { for (int i = 0; i < 100; i++) {
a %= 1;
} return a;
}
// // Verifier. //
publicstaticvoid main(String[] args) { int m = 1410065408; for (int i = -100; i <= 100; i++) {
expectEquals(m * i, geo1(i));
} for (int i = 1; i <= 1000000000; i *= 10) {
expectEquals( m * i, geo1( i));
expectEquals(-m * i, geo1(-i));
}
for (int i = -100; i <= 100; i++) {
expectEquals(i << 10, geo2(i));
} for (int i = 0; i < 22; i++) {
expectEquals(1 << (i + 10), geo2(1 << i));
}
expectEquals(0x80000400, geo2(0x00200001));
expectEquals(0x00000000, geo2(0x00400000));
expectEquals(0x00000400, geo2(0x00400001));
int d = 59049; for (int i = -100; i <= 100; i++) {
expectEquals(0, geo3(i));
} for (int i = 1; i <= 100; i++) {
expectEquals( i, geo3( i * d));
expectEquals( i, geo3( i * d + 1));
expectEquals(-i, geo3(-i * d));
expectEquals(-i, geo3(-i * d - 1));
}
for (int i = -100; i <= 100; i++) {
expectEquals(i % 7, geo4(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.