| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 // Test correctness of side effects tracking used by load to load forwarding. | |
| 5 | |
| 6 // VMOptions=--optimization-counter-threshold=10 | |
| 7 | |
| 8 import "package:expect/expect.dart"; | |
| 9 import "dart:typed_data"; | |
| 10 | |
| 11 class A { | |
| 12 var x, y; | |
| 13 A(this.x, this.y); | |
| 14 } | |
| 15 | |
| 16 foo(a) { | |
| 17 var value1 = a.x; | |
| 18 var value2 = a.y; | |
| 19 for (var j = 1; j < 4; j++) { | |
| 20 value1 |= a.x << (j * 8); | |
| 21 a.y += 1; | |
| 22 a.x += 1; | |
| 23 value2 |= a.y << (j * 8); | |
| 24 } | |
| 25 return [value1, value2]; | |
| 26 } | |
| 27 | |
| 28 bar(a, mode) { | |
| 29 var value1 = a.x; | |
| 30 var value2 = a.y; | |
| 31 for (var j = 1; j < 4; j++) { | |
| 32 value1 |= a.x << (j * 8); | |
| 33 a.y += 1; | |
| 34 if (mode) a.x += 1; | |
| 35 a.x += 1; | |
| 36 value2 |= a.y << (j * 8); | |
| 37 } | |
| 38 return [value1, value2]; | |
| 39 } | |
| 40 | |
| 41 // Verify that immutable and mutable VM fields (array length in this case) | |
| 42 // are not confused by load forwarding even if the access the same offset | |
| 43 // in the object. | |
| 44 testImmutableVMFields(arr, immutable) { | |
| 45 if (immutable) { | |
| 46 return arr.length; // Immutable length load. | |
| 47 } | |
| 48 | |
| 49 if (arr.length < 2) { // Mutable length load, should not be forwarded. | |
| 50 arr.add(null); | |
| 51 } | |
| 52 | |
| 53 return arr.length; | |
| 54 } | |
| 55 | |
| 56 testPhiRepresentation(f, arr) { | |
| 57 if (f) { | |
| 58 arr[0] = arr[0] + arr[1]; | |
| 59 } else { | |
| 60 arr[0] = arr[0] - arr[1]; | |
| 61 } | |
| 62 return arr[0]; | |
| 63 } | |
| 64 | |
| 65 testPhiConvertions(f, arr) { | |
| 66 if (f) { | |
| 67 arr[0] = arr[1]; | |
| 68 } else { | |
| 69 arr[0] = arr[2]; | |
| 70 } | |
| 71 return arr[0]; | |
| 72 } | |
| 73 | |
| 74 class M { | |
| 75 var x; | |
| 76 M(this.x); | |
| 77 } | |
| 78 | |
| 79 fakeAliasing(arr) { | |
| 80 var a = new M(10); | |
| 81 var b = new M(10); | |
| 82 var c = arr.length; | |
| 83 | |
| 84 if (c * c != c * c) { | |
| 85 arr[0] = a; // Escape. | |
| 86 arr[0] = b; | |
| 87 } | |
| 88 | |
| 89 return c * c; // Deopt point. | |
| 90 } | |
| 91 | |
| 92 class X { | |
| 93 var next; | |
| 94 X(this.next); | |
| 95 } | |
| 96 | |
| 97 testPhiForwarding(obj) { | |
| 98 if (obj.next == null) { | |
| 99 return 1; | |
| 100 } | |
| 101 | |
| 102 var len = 0; | |
| 103 while (obj != null) { | |
| 104 len++; | |
| 105 obj = obj.next; // This load should not be forwarded. | |
| 106 } | |
| 107 | |
| 108 return len; | |
| 109 } | |
| 110 | |
| 111 testPhiForwarding2(obj) { | |
| 112 if (obj.next == null) { | |
| 113 return 1; | |
| 114 } | |
| 115 | |
| 116 var len = 0, next = null; | |
| 117 while ((obj != null) && len < 2) { | |
| 118 len++; | |
| 119 obj = obj.next; // This load should be forwarded. | |
| 120 next = obj.next; | |
| 121 } | |
| 122 | |
| 123 return len; | |
| 124 } | |
| 125 | |
| 126 class V { | |
| 127 final f; | |
| 128 V(this.f); | |
| 129 } | |
| 130 | |
| 131 testPhiForwarding3() { | |
| 132 var a = new V(-0.1); | |
| 133 var c = new V(0.0); | |
| 134 var b = new V(0.1); | |
| 135 | |
| 136 for (var i = 0; i < 3; i++) { | |
| 137 var af = a.f; | |
| 138 var bf = b.f; | |
| 139 var cf = c.f; | |
| 140 a = new V(cf); | |
| 141 b = new V(af); | |
| 142 c = new V(bf); | |
| 143 } | |
| 144 | |
| 145 Expect.equals(-0.1, a.f); | |
| 146 Expect.equals(0.1, b.f); | |
| 147 Expect.equals(0.0, c.f); | |
| 148 } | |
| 149 | |
| 150 testPhiForwarding4() { | |
| 151 var a = new V(-0.1); | |
| 152 var b = new V(0.1); | |
| 153 var c = new V(0.0); | |
| 154 | |
| 155 var result = new List(9); | |
| 156 for (var i = 0, j = 0; i < 3; i++) { | |
| 157 result[j++] = a.f; | |
| 158 result[j++] = b.f; | |
| 159 result[j++] = c.f; | |
| 160 var xa = a; | |
| 161 var xb = b; | |
| 162 a = c; | |
| 163 b = xa; | |
| 164 c = xb; | |
| 165 } | |
| 166 | |
| 167 Expect.listEquals([-0.1, 0.1, 0.0, | |
| 168 0.0, -0.1, 0.1, | |
| 169 0.1, 0.0, -0.1], result); | |
| 170 } | |
| 171 | |
| 172 class U { | |
| 173 var x, y; | |
| 174 U() : x = 0, y = 0; | |
| 175 } | |
| 176 | |
| 177 testEqualPhisElimination() { | |
| 178 var u = new U(); | |
| 179 var v = new U(); | |
| 180 var sum = 0; | |
| 181 for (var i = 0; i < 3; i++) { | |
| 182 u.x = i; | |
| 183 u.y = i; | |
| 184 if ((i & 1) == 1) { | |
| 185 v.x = i + 1; | |
| 186 v.y = i + 1; | |
| 187 } else { | |
| 188 v.x = i - 1; | |
| 189 v.y = i - 1; | |
| 190 } | |
| 191 sum += v.x + v.y; | |
| 192 } | |
| 193 Expect.equals(4, sum); | |
| 194 Expect.equals(2, u.x); | |
| 195 Expect.equals(2, u.y); | |
| 196 } | |
| 197 | |
| 198 main() { | |
| 199 final fixed = new List(10); | |
| 200 final growable = []; | |
| 201 testImmutableVMFields(fixed, true); | |
| 202 testImmutableVMFields(growable, false); | |
| 203 testImmutableVMFields(growable, false); | |
| 204 | |
| 205 final f64List = new Float64List(2); | |
| 206 testPhiRepresentation(true, f64List); | |
| 207 testPhiRepresentation(false, f64List); | |
| 208 | |
| 209 final obj = new X(new X(new X(null))); | |
| 210 | |
| 211 for (var i = 0; i < 20; i++) { | |
| 212 Expect.listEquals([0x02010000, 0x03020100], foo(new A(0, 0))); | |
| 213 Expect.listEquals([0x02010000, 0x03020100], bar(new A(0, 0), false)); | |
| 214 Expect.listEquals([0x04020000, 0x03020100], bar(new A(0, 0), true)); | |
| 215 testImmutableVMFields(fixed, true); | |
| 216 testPhiRepresentation(true, f64List); | |
| 217 testPhiForwarding(obj); | |
| 218 testPhiForwarding2(obj); | |
| 219 testPhiForwarding3(); | |
| 220 testPhiForwarding4(); | |
| 221 testEqualPhisElimination(); | |
| 222 } | |
| 223 | |
| 224 Expect.equals(1, testImmutableVMFields([], false)); | |
| 225 Expect.equals(2, testImmutableVMFields([1], false)); | |
| 226 Expect.equals(2, testImmutableVMFields([1, 2], false)); | |
| 227 Expect.equals(3, testImmutableVMFields([1, 2, 3], false)); | |
| 228 | |
| 229 final u32List = new Uint32List(3); | |
| 230 u32List[0] = 0; | |
| 231 u32List[1] = 0x3FFFFFFF; | |
| 232 u32List[2] = 0x7FFFFFFF; | |
| 233 | |
| 234 for (var i = 0; i < 20; i++) { | |
| 235 testPhiConvertions(true, u32List); | |
| 236 testPhiConvertions(false, u32List); | |
| 237 } | |
| 238 | |
| 239 final escape = new List(1); | |
| 240 for (var i = 0; i < 20; i++) { | |
| 241 fakeAliasing(escape); | |
| 242 } | |
| 243 } | |
| OLD | NEW |