1 class MergeEscaped { 2 int a; 3 int b; 4 int c = 100; 5 6 public MergeEscaped() {} 7 public MergeEscaped(boolean cond) { 8 if (cond) { 9 this.a = 1; 10 this.b = 20; 11 this.c = 300; 12 blackhole(); // kill locals, so LV0 = this is dead here. 13 } else { 14 this.a = 100; 15 this.b = 50; 16 this.c = 7; 17 blackhole(); // kill locals. 18 } 19 // merge 2 predecessors, but LV0 is not live here. 20 // we need to merge allocation states, or wrong current allocation state is wrong. 21 } 22 23 public int sum() { 24 return a + b + c; 25 } 26 27 public static MergeEscaped cached; 28 29 void blackhole() {} // not inline this. 30 static void blackhole(Object obj) {} // not inline this. 31 32 public static MergeEscaped escaped(boolean cond1) { 33 MergeEscaped obj = new MergeEscaped(); 34 35 if (cond1) { 36 blackhole(obj); 37 obj.a = 20; 38 } else { 39 obj.b = 30; 40 blackhole(obj); 41 } 42 obj.c = 100; 43 return obj; 44 } 45 46 static void check_result(boolean cond1, int sum) { 47 boolean okay = true; 48 49 if (cond1) { 50 okay = sum == 120; 51 } else { 52 okay = sum == 130; 53 } 54 55 if (!okay) { 56 throw new RuntimeException("wrong answer: " + cond1 + " " + sum); 57 } 58 } 59 public static MergeEscaped escaped2(boolean cond1) { 60 MergeEscaped obj = new MergeEscaped(); 61 62 for (int i = 0; i < 100; ++i) { 63 if (cond1) { 64 blackhole(obj); 65 obj.a = 20; 66 } else { 67 obj.b = 30; 68 } 69 } 70 return obj; 71 } 72 73 public static MergeEscaped escaped3(boolean cond1, boolean cond2) { 74 MergeEscaped obj = new MergeEscaped(); 75 if (cond1) { 76 obj.a = 10; // V 77 } else { 78 if (cond2) { 79 blackhole(obj); // E1 80 obj.a = 20; 81 } else { 82 blackhole(obj); // E2 83 obj.b = 30; 84 } 85 obj.c = 300; // PHI(E1, E2), 86 } // PHI'(V, PHI) 87 return obj; 88 } 89 90 static void check_result3(boolean cond1, boolean cond2, int sum) { 91 boolean okay = true; 92 93 if (cond1) { 94 okay = sum == 110; 95 } else { 96 if (cond2) { 97 okay = sum == 320; 98 } else { 99 okay = sum == 330; 100 } 101 } 102 103 if (!okay) { 104 throw new RuntimeException("wrong answer: " + cond1 + " " + cond2 + " " + sum); 105 } 106 } 107 108 private static void test4(MergeEscaped obj, int cond) { 109 if (cond == 0) { 110 obj.a = 1; 111 } else if (cond == 1) { 112 obj.a = 2; 113 } else { 114 blackhole(obj); 115 } 116 } 117 118 public static MergeEscaped escaped4(boolean cond1, boolean cond2) { 119 MergeEscaped obj = new MergeEscaped(); 120 121 int cond = 0; 122 if (cond1) { 123 cond = 2; // cond1 << 1 124 } 125 if (cond2) { 126 cond = cond + 1; 127 } 128 129 test4(obj, cond); 130 blackhole(obj); 131 return obj; 132 } 133 134 public static void main(String[] args) { 135 long iterations = 0; 136 137 try { 138 while (true) { 139 boolean cond = 0 == (iterations & 0xf); 140 boolean cond2 = 7 == (iterations& 0xf); 141 142 int sum = MergeEscaped.escaped(cond).sum(); 143 check_result(cond, sum); 144 145 sum = MergeEscaped.escaped2(cond).sum(); 146 check_result(cond, sum); 147 148 sum = MergeEscaped.escaped3(cond, cond2).sum(); 149 check_result3(cond, cond2, sum); 150 151 escaped4(cond, cond2); 152 iterations++; 153 } 154 } finally { 155 System.err.println("Epsilon Test: " + iterations); 156 } 157 } 158 }