Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: test/cctest/compiler/test-simplified-lowering.cc

Issue 1439473003: [turbofan] Move simplified alloc, load and store lowering to change lowering. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: A bit of cement. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // TODO(jochen): Remove this after the setting is turned on globally. 5 // TODO(jochen): Remove this after the setting is turned on globally.
6 #define V8_IMMINENT_DEPRECATION_WARNINGS 6 #define V8_IMMINENT_DEPRECATION_WARNINGS
7 7
8 #include <limits> 8 #include <limits>
9 9
10 #include "src/compiler/access-builder.h" 10 #include "src/compiler/access-builder.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 SimplifiedLoweringTester<Object*> t; 104 SimplifiedLoweringTester<Object*> t;
105 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), 105 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
106 kMachFloat64}; 106 kMachFloat64};
107 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); 107 Node* loaded = t.LoadField(load, t.PointerConstant(&input));
108 NodeProperties::SetType(loaded, Type::Number()); 108 NodeProperties::SetType(loaded, Type::Number());
109 Node* convert = t.NumberToInt32(loaded); 109 Node* convert = t.NumberToInt32(loaded);
110 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), 110 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(),
111 kMachInt32}; 111 kMachInt32};
112 t.StoreField(store, t.PointerConstant(&result), convert); 112 t.StoreField(store, t.PointerConstant(&result), convert);
113 t.Return(t.jsgraph.TrueConstant()); 113 t.Return(t.jsgraph.TrueConstant());
114 t.LowerAllNodes(); 114 t.LowerAllNodesAndLowerChanges();
115 t.GenerateCode(); 115 t.GenerateCode();
116 116
117 FOR_FLOAT64_INPUTS(i) { 117 FOR_FLOAT64_INPUTS(i) {
118 input = *i; 118 input = *i;
119 int32_t expected = DoubleToInt32(*i); 119 int32_t expected = DoubleToInt32(*i);
120 t.Call(); 120 t.Call();
121 CHECK_EQ(expected, result); 121 CHECK_EQ(expected, result);
122 } 122 }
123 } 123 }
124 124
125 125
126 // TODO(titzer): test tagged representation for input to NumberToUint32. 126 // TODO(titzer): test tagged representation for input to NumberToUint32.
127 TEST(RunNumberToUint32_float64) { 127 TEST(RunNumberToUint32_float64) {
128 // TODO(titzer): explicit load/stores here are only because of representations 128 // TODO(titzer): explicit load/stores here are only because of representations
129 double input; 129 double input;
130 uint32_t result; 130 uint32_t result;
131 SimplifiedLoweringTester<Object*> t; 131 SimplifiedLoweringTester<Object*> t;
132 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), 132 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
133 kMachFloat64}; 133 kMachFloat64};
134 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); 134 Node* loaded = t.LoadField(load, t.PointerConstant(&input));
135 NodeProperties::SetType(loaded, Type::Number()); 135 NodeProperties::SetType(loaded, Type::Number());
136 Node* convert = t.NumberToUint32(loaded); 136 Node* convert = t.NumberToUint32(loaded);
137 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), 137 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(),
138 kMachUint32}; 138 kMachUint32};
139 t.StoreField(store, t.PointerConstant(&result), convert); 139 t.StoreField(store, t.PointerConstant(&result), convert);
140 t.Return(t.jsgraph.TrueConstant()); 140 t.Return(t.jsgraph.TrueConstant());
141 t.LowerAllNodes(); 141 t.LowerAllNodesAndLowerChanges();
142 t.GenerateCode(); 142 t.GenerateCode();
143 143
144 FOR_FLOAT64_INPUTS(i) { 144 FOR_FLOAT64_INPUTS(i) {
145 input = *i; 145 input = *i;
146 uint32_t expected = DoubleToUint32(*i); 146 uint32_t expected = DoubleToUint32(*i);
147 t.Call(); 147 t.Call();
148 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); 148 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result));
149 } 149 }
150 } 150 }
151 151
152 152
153 // Create a simple JSObject with a unique map. 153 // Create a simple JSObject with a unique map.
154 static Handle<JSObject> TestObject() { 154 static Handle<JSObject> TestObject() {
155 static int index = 0; 155 static int index = 0;
156 char buffer[50]; 156 char buffer[50];
157 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++); 157 v8::base::OS::SNPrintF(buffer, 50, "({'a_%d':1})", index++);
158 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer))); 158 return Handle<JSObject>::cast(v8::Utils::OpenHandle(*CompileRun(buffer)));
159 } 159 }
160 160
161 161
162 TEST(RunLoadMap) { 162 TEST(RunLoadMap) {
163 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 163 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
164 FieldAccess access = AccessBuilder::ForMap(); 164 FieldAccess access = AccessBuilder::ForMap();
165 Node* load = t.LoadField(access, t.Parameter(0)); 165 Node* load = t.LoadField(access, t.Parameter(0));
166 t.Return(load); 166 t.Return(load);
167 167
168 t.LowerAllNodes(); 168 t.LowerAllNodesAndLowerChanges();
169 t.GenerateCode(); 169 t.GenerateCode();
170 170
171 Handle<JSObject> src = TestObject(); 171 Handle<JSObject> src = TestObject();
172 Handle<Map> src_map(src->map()); 172 Handle<Map> src_map(src->map());
173 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call 173 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call
174 CHECK_EQ(*src_map, result); 174 CHECK_EQ(*src_map, result);
175 } 175 }
176 176
177 177
178 TEST(RunStoreMap) { 178 TEST(RunStoreMap) {
179 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged); 179 SimplifiedLoweringTester<int32_t> t(kMachAnyTagged, kMachAnyTagged);
180 FieldAccess access = AccessBuilder::ForMap(); 180 FieldAccess access = AccessBuilder::ForMap();
181 t.StoreField(access, t.Parameter(1), t.Parameter(0)); 181 t.StoreField(access, t.Parameter(1), t.Parameter(0));
182 t.Return(t.jsgraph.TrueConstant()); 182 t.Return(t.jsgraph.TrueConstant());
183 183
184 t.LowerAllNodes(); 184 t.LowerAllNodesAndLowerChanges();
185 t.GenerateCode(); 185 t.GenerateCode();
186 186
187 Handle<JSObject> src = TestObject(); 187 Handle<JSObject> src = TestObject();
188 Handle<Map> src_map(src->map()); 188 Handle<Map> src_map(src->map());
189 Handle<JSObject> dst = TestObject(); 189 Handle<JSObject> dst = TestObject();
190 CHECK(src->map() != dst->map()); 190 CHECK(src->map() != dst->map());
191 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call 191 t.Call(*src_map, *dst); // TODO(titzer): raw pointers in call
192 CHECK(*src_map == dst->map()); 192 CHECK(*src_map == dst->map());
193 } 193 }
194 194
195 195
196 TEST(RunLoadProperties) { 196 TEST(RunLoadProperties) {
197 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 197 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
198 FieldAccess access = AccessBuilder::ForJSObjectProperties(); 198 FieldAccess access = AccessBuilder::ForJSObjectProperties();
199 Node* load = t.LoadField(access, t.Parameter(0)); 199 Node* load = t.LoadField(access, t.Parameter(0));
200 t.Return(load); 200 t.Return(load);
201 201
202 t.LowerAllNodes(); 202 t.LowerAllNodesAndLowerChanges();
203 t.GenerateCode(); 203 t.GenerateCode();
204 204
205 Handle<JSObject> src = TestObject(); 205 Handle<JSObject> src = TestObject();
206 Handle<FixedArray> src_props(src->properties()); 206 Handle<FixedArray> src_props(src->properties());
207 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call 207 Object* result = t.Call(*src); // TODO(titzer): raw pointers in call
208 CHECK_EQ(*src_props, result); 208 CHECK_EQ(*src_props, result);
209 } 209 }
210 210
211 211
212 TEST(RunLoadStoreMap) { 212 TEST(RunLoadStoreMap) {
213 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged); 213 SimplifiedLoweringTester<Object*> t(kMachAnyTagged, kMachAnyTagged);
214 FieldAccess access = AccessBuilder::ForMap(); 214 FieldAccess access = AccessBuilder::ForMap();
215 Node* load = t.LoadField(access, t.Parameter(0)); 215 Node* load = t.LoadField(access, t.Parameter(0));
216 t.StoreField(access, t.Parameter(1), load); 216 t.StoreField(access, t.Parameter(1), load);
217 t.Return(load); 217 t.Return(load);
218 218
219 t.LowerAllNodes(); 219 t.LowerAllNodesAndLowerChanges();
220 t.GenerateCode(); 220 t.GenerateCode();
221 221
222 Handle<JSObject> src = TestObject(); 222 Handle<JSObject> src = TestObject();
223 Handle<Map> src_map(src->map()); 223 Handle<Map> src_map(src->map());
224 Handle<JSObject> dst = TestObject(); 224 Handle<JSObject> dst = TestObject();
225 CHECK(src->map() != dst->map()); 225 CHECK(src->map() != dst->map());
226 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call 226 Object* result = t.Call(*src, *dst); // TODO(titzer): raw pointers in call
227 CHECK(result->IsMap()); 227 CHECK(result->IsMap());
228 CHECK_EQ(*src_map, result); 228 CHECK_EQ(*src_map, result);
229 CHECK(*src_map == dst->map()); 229 CHECK(*src_map == dst->map());
230 } 230 }
231 231
232 232
233 TEST(RunLoadStoreFixedArrayIndex) { 233 TEST(RunLoadStoreFixedArrayIndex) {
234 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 234 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
235 ElementAccess access = AccessBuilder::ForFixedArrayElement(); 235 ElementAccess access = AccessBuilder::ForFixedArrayElement();
236 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0)); 236 Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0));
237 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load); 237 t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load);
238 t.Return(load); 238 t.Return(load);
239 239
240 t.LowerAllNodes(); 240 t.LowerAllNodesAndLowerChanges();
241 t.GenerateCode(); 241 t.GenerateCode();
242 242
243 Handle<FixedArray> array = t.factory()->NewFixedArray(2); 243 Handle<FixedArray> array = t.factory()->NewFixedArray(2);
244 Handle<JSObject> src = TestObject(); 244 Handle<JSObject> src = TestObject();
245 Handle<JSObject> dst = TestObject(); 245 Handle<JSObject> dst = TestObject();
246 array->set(0, *src); 246 array->set(0, *src);
247 array->set(1, *dst); 247 array->set(1, *dst);
248 Object* result = t.Call(*array); 248 Object* result = t.Call(*array);
249 CHECK_EQ(*src, result); 249 CHECK_EQ(*src, result);
250 CHECK_EQ(*src, array->get(0)); 250 CHECK_EQ(*src, array->get(0));
251 CHECK_EQ(*src, array->get(1)); 251 CHECK_EQ(*src, array->get(1));
252 } 252 }
253 253
254 254
255 TEST(RunLoadStoreArrayBuffer) { 255 TEST(RunLoadStoreArrayBuffer) {
256 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 256 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
257 const int index = 12; 257 const int index = 12;
258 const int array_length = 2 * index; 258 const int array_length = 2 * index;
259 ElementAccess buffer_access = 259 ElementAccess buffer_access =
260 AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true); 260 AccessBuilder::ForTypedArrayElement(kExternalInt8Array, true);
261 Node* backing_store = t.LoadField( 261 Node* backing_store = t.LoadField(
262 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0)); 262 AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0));
263 Node* load = 263 Node* load =
264 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index)); 264 t.LoadElement(buffer_access, backing_store, t.Int32Constant(index));
265 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1), 265 t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1),
266 load); 266 load);
267 t.Return(t.jsgraph.TrueConstant()); 267 t.Return(t.jsgraph.TrueConstant());
268 268
269 t.LowerAllNodes(); 269 t.LowerAllNodesAndLowerChanges();
270 t.GenerateCode(); 270 t.GenerateCode();
271 271
272 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer(); 272 Handle<JSArrayBuffer> array = t.factory()->NewJSArrayBuffer();
273 JSArrayBuffer::SetupAllocatingData(array, t.isolate(), array_length); 273 JSArrayBuffer::SetupAllocatingData(array, t.isolate(), array_length);
274 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store()); 274 uint8_t* data = reinterpret_cast<uint8_t*>(array->backing_store());
275 for (int i = 0; i < array_length; i++) { 275 for (int i = 0; i < array_length; i++) {
276 data[i] = i; 276 data[i] = i;
277 } 277 }
278 278
279 // TODO(titzer): raw pointers in call 279 // TODO(titzer): raw pointers in call
(...skipping 11 matching lines...) Expand all
291 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; 291 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)};
292 292
293 for (size_t i = 0; i < arraysize(smis); i++) { 293 for (size_t i = 0; i < arraysize(smis); i++) {
294 int offset = static_cast<int>(i * sizeof(Smi*)); 294 int offset = static_cast<int>(i * sizeof(Smi*));
295 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), 295 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(),
296 Type::Integral32(), kMachAnyTagged}; 296 Type::Integral32(), kMachAnyTagged};
297 297
298 SimplifiedLoweringTester<Object*> t; 298 SimplifiedLoweringTester<Object*> t;
299 Node* load = t.LoadField(access, t.PointerConstant(smis)); 299 Node* load = t.LoadField(access, t.PointerConstant(smis));
300 t.Return(load); 300 t.Return(load);
301 t.LowerAllNodes(); 301 t.LowerAllNodesAndLowerChanges();
302 302
303 for (int j = -5; j <= 5; j++) { 303 for (int j = -5; j <= 5; j++) {
304 Smi* expected = Smi::FromInt(j); 304 Smi* expected = Smi::FromInt(j);
305 smis[i] = expected; 305 smis[i] = expected;
306 CHECK_EQ(expected, t.Call()); 306 CHECK_EQ(expected, t.Call());
307 } 307 }
308 } 308 }
309 } 309 }
310 310
311 311
312 TEST(RunStoreFieldToUntaggedBase) { 312 TEST(RunStoreFieldToUntaggedBase) {
313 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; 313 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)};
314 314
315 for (size_t i = 0; i < arraysize(smis); i++) { 315 for (size_t i = 0; i < arraysize(smis); i++) {
316 int offset = static_cast<int>(i * sizeof(Smi*)); 316 int offset = static_cast<int>(i * sizeof(Smi*));
317 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), 317 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(),
318 Type::Integral32(), kMachAnyTagged}; 318 Type::Integral32(), kMachAnyTagged};
319 319
320 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 320 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
321 Node* p0 = t.Parameter(0); 321 Node* p0 = t.Parameter(0);
322 t.StoreField(access, t.PointerConstant(smis), p0); 322 t.StoreField(access, t.PointerConstant(smis), p0);
323 t.Return(p0); 323 t.Return(p0);
324 t.LowerAllNodes(); 324 t.LowerAllNodesAndLowerChanges();
325 325
326 for (int j = -5; j <= 5; j++) { 326 for (int j = -5; j <= 5; j++) {
327 Smi* expected = Smi::FromInt(j); 327 Smi* expected = Smi::FromInt(j);
328 smis[i] = Smi::FromInt(-100); 328 smis[i] = Smi::FromInt(-100);
329 CHECK_EQ(expected, t.Call(expected)); 329 CHECK_EQ(expected, t.Call(expected));
330 CHECK_EQ(expected, smis[i]); 330 CHECK_EQ(expected, smis[i]);
331 } 331 }
332 } 332 }
333 } 333 }
334 334
335 335
336 TEST(RunLoadElementFromUntaggedBase) { 336 TEST(RunLoadElementFromUntaggedBase) {
337 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), 337 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3),
338 Smi::FromInt(4), Smi::FromInt(5)}; 338 Smi::FromInt(4), Smi::FromInt(5)};
339 339
340 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes 340 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes
341 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index 341 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index
342 int offset = static_cast<int>(i * sizeof(Smi*)); 342 int offset = static_cast<int>(i * sizeof(Smi*));
343 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), 343 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(),
344 kMachAnyTagged}; 344 kMachAnyTagged};
345 345
346 SimplifiedLoweringTester<Object*> t; 346 SimplifiedLoweringTester<Object*> t;
347 Node* load = t.LoadElement(access, t.PointerConstant(smis), 347 Node* load = t.LoadElement(access, t.PointerConstant(smis),
348 t.Int32Constant(static_cast<int>(j))); 348 t.Int32Constant(static_cast<int>(j)));
349 t.Return(load); 349 t.Return(load);
350 t.LowerAllNodes(); 350 t.LowerAllNodesAndLowerChanges();
351 351
352 for (int k = -5; k <= 5; k++) { 352 for (int k = -5; k <= 5; k++) {
353 Smi* expected = Smi::FromInt(k); 353 Smi* expected = Smi::FromInt(k);
354 smis[i + j] = expected; 354 smis[i + j] = expected;
355 CHECK_EQ(expected, t.Call()); 355 CHECK_EQ(expected, t.Call());
356 } 356 }
357 } 357 }
358 } 358 }
359 } 359 }
360 360
361 361
362 TEST(RunStoreElementFromUntaggedBase) { 362 TEST(RunStoreElementFromUntaggedBase) {
363 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), 363 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3),
364 Smi::FromInt(4), Smi::FromInt(5)}; 364 Smi::FromInt(4), Smi::FromInt(5)};
365 365
366 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes 366 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes
367 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index 367 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index
368 int offset = static_cast<int>(i * sizeof(Smi*)); 368 int offset = static_cast<int>(i * sizeof(Smi*));
369 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), 369 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(),
370 kMachAnyTagged}; 370 kMachAnyTagged};
371 371
372 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 372 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
373 Node* p0 = t.Parameter(0); 373 Node* p0 = t.Parameter(0);
374 t.StoreElement(access, t.PointerConstant(smis), 374 t.StoreElement(access, t.PointerConstant(smis),
375 t.Int32Constant(static_cast<int>(j)), p0); 375 t.Int32Constant(static_cast<int>(j)), p0);
376 t.Return(p0); 376 t.Return(p0);
377 t.LowerAllNodes(); 377 t.LowerAllNodesAndLowerChanges();
378 378
379 for (int k = -5; k <= 5; k++) { 379 for (int k = -5; k <= 5; k++) {
380 Smi* expected = Smi::FromInt(k); 380 Smi* expected = Smi::FromInt(k);
381 smis[i + j] = Smi::FromInt(-100); 381 smis[i + j] = Smi::FromInt(-100);
382 CHECK_EQ(expected, t.Call(expected)); 382 CHECK_EQ(expected, t.Call(expected));
383 CHECK_EQ(expected, smis[i + j]); 383 CHECK_EQ(expected, smis[i + j]);
384 } 384 }
385 385
386 // TODO(titzer): assert the contents of the array. 386 // TODO(titzer): assert the contents of the array.
387 } 387 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 // a constant in the code. 432 // a constant in the code.
433 BoundsCheck(from_index); 433 BoundsCheck(from_index);
434 BoundsCheck(to_index); 434 BoundsCheck(to_index);
435 ElementAccess access = GetElementAccess(); 435 ElementAccess access = GetElementAccess();
436 436
437 SimplifiedLoweringTester<Object*> t; 437 SimplifiedLoweringTester<Object*> t;
438 Node* ptr = GetBaseNode(&t); 438 Node* ptr = GetBaseNode(&t);
439 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index)); 439 Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index));
440 t.StoreElement(access, ptr, t.Int32Constant(to_index), load); 440 t.StoreElement(access, ptr, t.Int32Constant(to_index), load);
441 t.Return(t.jsgraph.TrueConstant()); 441 t.Return(t.jsgraph.TrueConstant());
442 t.LowerAllNodes(); 442 t.LowerAllNodesAndLowerChanges();
443 t.GenerateCode(); 443 t.GenerateCode();
444 444
445 Object* result = t.Call(); 445 Object* result = t.Call();
446 CHECK_EQ(t.isolate()->heap()->true_value(), result); 446 CHECK_EQ(t.isolate()->heap()->true_value(), result);
447 } 447 }
448 448
449 // Create and run code that copies the field in either {untagged_array} 449 // Create and run code that copies the field in either {untagged_array}
450 // or {tagged_array} at index {from_index} to index {to_index}. 450 // or {tagged_array} at index {from_index} to index {to_index}.
451 void RunCopyField(int from_index, int to_index) { 451 void RunCopyField(int from_index, int to_index) {
452 BoundsCheck(from_index); 452 BoundsCheck(from_index);
453 BoundsCheck(to_index); 453 BoundsCheck(to_index);
454 FieldAccess from_access = GetFieldAccess(from_index); 454 FieldAccess from_access = GetFieldAccess(from_index);
455 FieldAccess to_access = GetFieldAccess(to_index); 455 FieldAccess to_access = GetFieldAccess(to_index);
456 456
457 SimplifiedLoweringTester<Object*> t; 457 SimplifiedLoweringTester<Object*> t;
458 Node* ptr = GetBaseNode(&t); 458 Node* ptr = GetBaseNode(&t);
459 Node* load = t.LoadField(from_access, ptr); 459 Node* load = t.LoadField(from_access, ptr);
460 t.StoreField(to_access, ptr, load); 460 t.StoreField(to_access, ptr, load);
461 t.Return(t.jsgraph.TrueConstant()); 461 t.Return(t.jsgraph.TrueConstant());
462 t.LowerAllNodes(); 462 t.LowerAllNodesAndLowerChanges();
463 t.GenerateCode(); 463 t.GenerateCode();
464 464
465 Object* result = t.Call(); 465 Object* result = t.Call();
466 CHECK_EQ(t.isolate()->heap()->true_value(), result); 466 CHECK_EQ(t.isolate()->heap()->true_value(), result);
467 } 467 }
468 468
469 // Create and run code that copies the elements from {this} to {that}. 469 // Create and run code that copies the elements from {this} to {that}.
470 void RunCopyElements(AccessTester<E>* that) { 470 void RunCopyElements(AccessTester<E>* that) {
471 // TODO(titzer): Rewrite this test without StructuredGraphBuilder support. 471 // TODO(titzer): Rewrite this test without StructuredGraphBuilder support.
472 #if 0 472 #if 0
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 644
645 for (size_t i = 0; i < arraysize(flag); i++) { 645 for (size_t i = 0; i < arraysize(flag); i++) {
646 SimplifiedLoweringTester<HeapObject*> t; 646 SimplifiedLoweringTester<HeapObject*> t;
647 FieldAccess access = AccessBuilder::ForMap(); 647 FieldAccess access = AccessBuilder::ForMap();
648 Node* size = t.jsgraph.Constant(HeapNumber::kSize); 648 Node* size = t.jsgraph.Constant(HeapNumber::kSize);
649 Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size); 649 Node* alloc = t.NewNode(t.simplified()->Allocate(flag[i]), size);
650 Node* map = t.jsgraph.Constant(t.factory()->heap_number_map()); 650 Node* map = t.jsgraph.Constant(t.factory()->heap_number_map());
651 t.StoreField(access, alloc, map); 651 t.StoreField(access, alloc, map);
652 t.Return(alloc); 652 t.Return(alloc);
653 653
654 t.LowerAllNodes(); 654 t.LowerAllNodesAndLowerChanges();
655 t.GenerateCode(); 655 t.GenerateCode();
656 656
657 HeapObject* result = t.CallWithPotentialGC<HeapObject>(); 657 HeapObject* result = t.CallWithPotentialGC<HeapObject>();
658 CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED); 658 CHECK(t.heap()->new_space()->Contains(result) || flag[i] == TENURED);
659 CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED); 659 CHECK(t.heap()->old_space()->Contains(result) || flag[i] == NOT_TENURED);
660 CHECK(result->IsHeapNumber()); 660 CHECK(result->IsHeapNumber());
661 } 661 }
662 } 662 }
663 663
664 664
(...skipping 10 matching lines...) Expand all
675 Node* end; 675 Node* end;
676 Node* ret; 676 Node* ret;
677 677
678 explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(), 678 explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
679 Type* p2_type = Type::None()) 679 Type* p2_type = Type::None())
680 : GraphAndBuilders(main_zone()), 680 : GraphAndBuilders(main_zone()),
681 typer(main_isolate(), graph()), 681 typer(main_isolate(), graph()),
682 javascript(main_zone()), 682 javascript(main_zone()),
683 jsgraph(main_isolate(), graph(), common(), &javascript, simplified(), 683 jsgraph(main_isolate(), graph(), common(), &javascript, simplified(),
684 machine()) { 684 machine()) {
685 start = graph()->NewNode(common()->Start(2)); 685 start = graph()->NewNode(common()->Start(4));
686 graph()->SetStart(start); 686 graph()->SetStart(start);
687 ret = 687 ret =
688 graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start); 688 graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start);
689 end = graph()->NewNode(common()->End(1), ret); 689 end = graph()->NewNode(common()->End(1), ret);
690 graph()->SetEnd(end); 690 graph()->SetEnd(end);
691 p0 = graph()->NewNode(common()->Parameter(0), start); 691 p0 = graph()->NewNode(common()->Parameter(0), start);
692 p1 = graph()->NewNode(common()->Parameter(1), start); 692 p1 = graph()->NewNode(common()->Parameter(1), start);
693 p2 = graph()->NewNode(common()->Parameter(2), start); 693 p2 = graph()->NewNode(common()->Parameter(2), start);
694 typer.Run(); 694 typer.Run();
695 NodeProperties::SetType(p0, p0_type); 695 NodeProperties::SetType(p0, p0_type);
(...skipping 20 matching lines...) Expand all
716 Return(graph()->NewNode(trunc, node)); 716 Return(graph()->NewNode(trunc, node));
717 Lower(); 717 Lower();
718 CHECK_EQ(expected, node->opcode()); 718 CHECK_EQ(expected, node->opcode());
719 } 719 }
720 720
721 void Lower() { 721 void Lower() {
722 SourcePositionTable table(jsgraph.graph()); 722 SourcePositionTable table(jsgraph.graph());
723 SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes(); 723 SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes();
724 } 724 }
725 725
726 void LowerAllNodesAndLowerChanges() {
727 SourcePositionTable table(jsgraph.graph());
728 SimplifiedLowering(&jsgraph, jsgraph.zone(), &table).LowerAllNodes();
729
730 ChangeLowering lowering(&jsgraph);
731 GraphReducer reducer(this->zone(), this->graph());
732 reducer.AddReducer(&lowering);
733 reducer.ReduceGraph();
734 Verifier::Run(this->graph());
735 }
736
726 // Inserts the node as the return value of the graph. 737 // Inserts the node as the return value of the graph.
727 Node* Return(Node* node) { 738 Node* Return(Node* node) {
728 ret->ReplaceInput(0, node); 739 ret->ReplaceInput(0, node);
729 return node; 740 return node;
730 } 741 }
731 742
732 // Inserts the node as the effect input to the return of the graph. 743 // Inserts the node as the effect input to the return of the graph.
733 void Effect(Node* node) { ret->ReplaceInput(1, node); } 744 void Effect(Node* node) { ret->ReplaceInput(1, node); }
734 745
735 Node* ExampleWithOutput(MachineType type) { 746 Node* ExampleWithOutput(MachineType type) {
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 TestingGraph t(Type::Any(), Type::Signed32()); 1372 TestingGraph t(Type::Any(), Type::Signed32());
1362 1373
1363 for (size_t i = 0; i < arraysize(kMachineReps); i++) { 1374 for (size_t i = 0; i < arraysize(kMachineReps); i++) {
1364 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1375 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1365 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; 1376 Handle<Name>::null(), Type::Any(), kMachineReps[i]};
1366 1377
1367 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, 1378 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
1368 t.start, t.start); 1379 t.start, t.start);
1369 Node* use = t.Use(load, kMachineReps[i]); 1380 Node* use = t.Use(load, kMachineReps[i]);
1370 t.Return(use); 1381 t.Return(use);
1371 t.Lower(); 1382 t.LowerAllNodesAndLowerChanges();
1372 CHECK_EQ(IrOpcode::kLoad, load->opcode()); 1383 CHECK_EQ(IrOpcode::kLoad, load->opcode());
1373 CHECK_EQ(t.p0, load->InputAt(0)); 1384 CHECK_EQ(t.p0, load->InputAt(0));
1374 CheckFieldAccessArithmetic(access, load); 1385 CheckFieldAccessArithmetic(access, load);
1375 1386
1376 MachineType rep = OpParameter<MachineType>(load); 1387 MachineType rep = OpParameter<MachineType>(load);
1377 CHECK_EQ(kMachineReps[i], rep); 1388 CHECK_EQ(kMachineReps[i], rep);
1378 } 1389 }
1379 } 1390 }
1380 1391
1381 1392
1382 TEST(LowerStoreField_to_store) { 1393 TEST(LowerStoreField_to_store) {
1383 { 1394 {
1384 TestingGraph t(Type::Any(), Type::Signed32()); 1395 TestingGraph t(Type::Any(), Type::Signed32());
1385 1396
1386 for (size_t i = 0; i < arraysize(kMachineReps); i++) { 1397 for (size_t i = 0; i < arraysize(kMachineReps); i++) {
1387 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1398 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1388 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; 1399 Handle<Name>::null(), Type::Any(), kMachineReps[i]};
1389 1400
1390 1401
1391 Node* val = t.ExampleWithOutput(kMachineReps[i]); 1402 Node* val = t.ExampleWithOutput(kMachineReps[i]);
1392 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, 1403 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
1393 val, t.start, t.start); 1404 val, t.start, t.start);
1394 t.Effect(store); 1405 t.Effect(store);
1395 t.Lower(); 1406 t.LowerAllNodesAndLowerChanges();
1396 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1407 CHECK_EQ(IrOpcode::kStore, store->opcode());
1397 CHECK_EQ(val, store->InputAt(2)); 1408 CHECK_EQ(val, store->InputAt(2));
1398 CheckFieldAccessArithmetic(access, store); 1409 CheckFieldAccessArithmetic(access, store);
1399 1410
1400 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); 1411 StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
1401 if (kMachineReps[i] & kRepTagged) { 1412 if (kMachineReps[i] & kRepTagged) {
1402 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); 1413 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
1403 } 1414 }
1404 CHECK_EQ(kMachineReps[i], rep.machine_type()); 1415 CHECK_EQ(kMachineReps[i], rep.machine_type());
1405 } 1416 }
1406 } 1417 }
1407 { 1418 {
1408 HandleAndZoneScope scope; 1419 HandleAndZoneScope scope;
1409 Zone* z = scope.main_zone(); 1420 Zone* z = scope.main_zone();
1410 TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(), 1421 TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(),
1411 Type::TaggedSigned(), z)); 1422 Type::TaggedSigned(), z));
1412 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1423 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1413 Handle<Name>::null(), Type::Any(), kMachAnyTagged}; 1424 Handle<Name>::null(), Type::Any(), kMachAnyTagged};
1414 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, 1425 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
1415 t.p1, t.start, t.start); 1426 t.p1, t.start, t.start);
1416 t.Effect(store); 1427 t.Effect(store);
1417 t.Lower(); 1428 t.LowerAllNodesAndLowerChanges();
1418 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1429 CHECK_EQ(IrOpcode::kStore, store->opcode());
1419 CHECK_EQ(t.p1, store->InputAt(2)); 1430 CHECK_EQ(t.p1, store->InputAt(2));
1420 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); 1431 StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
1421 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); 1432 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind());
1422 } 1433 }
1423 } 1434 }
1424 1435
1425 1436
1426 TEST(LowerLoadElement_to_load) { 1437 TEST(LowerLoadElement_to_load) {
1427 TestingGraph t(Type::Any(), Type::Signed32()); 1438 TestingGraph t(Type::Any(), Type::Signed32());
1428 1439
1429 for (size_t i = 0; i < arraysize(kMachineReps); i++) { 1440 for (size_t i = 0; i < arraysize(kMachineReps); i++) {
1430 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1441 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1431 Type::Any(), kMachineReps[i]}; 1442 Type::Any(), kMachineReps[i]};
1432 1443
1433 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, 1444 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
1434 t.p1, t.start, t.start); 1445 t.p1, t.start, t.start);
1435 Node* use = t.Use(load, kMachineReps[i]); 1446 Node* use = t.Use(load, kMachineReps[i]);
1436 t.Return(use); 1447 t.Return(use);
1437 t.Lower(); 1448 t.LowerAllNodesAndLowerChanges();
1438 CHECK_EQ(IrOpcode::kLoad, load->opcode()); 1449 CHECK_EQ(IrOpcode::kLoad, load->opcode());
1439 CHECK_EQ(t.p0, load->InputAt(0)); 1450 CHECK_EQ(t.p0, load->InputAt(0));
1440 CheckElementAccessArithmetic(access, load); 1451 CheckElementAccessArithmetic(access, load);
1441 1452
1442 MachineType rep = OpParameter<MachineType>(load); 1453 MachineType rep = OpParameter<MachineType>(load);
1443 CHECK_EQ(kMachineReps[i], rep); 1454 CHECK_EQ(kMachineReps[i], rep);
1444 } 1455 }
1445 } 1456 }
1446 1457
1447 1458
1448 TEST(LowerStoreElement_to_store) { 1459 TEST(LowerStoreElement_to_store) {
1449 { 1460 {
1450 TestingGraph t(Type::Any(), Type::Signed32()); 1461 TestingGraph t(Type::Any(), Type::Signed32());
1451 1462
1452 for (size_t i = 0; i < arraysize(kMachineReps); i++) { 1463 for (size_t i = 0; i < arraysize(kMachineReps); i++) {
1453 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1464 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1454 Type::Any(), kMachineReps[i]}; 1465 Type::Any(), kMachineReps[i]};
1455 1466
1456 Node* val = t.ExampleWithOutput(kMachineReps[i]); 1467 Node* val = t.ExampleWithOutput(kMachineReps[i]);
1457 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), 1468 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access),
1458 t.p0, t.p1, val, t.start, t.start); 1469 t.p0, t.p1, val, t.start, t.start);
1459 t.Effect(store); 1470 t.Effect(store);
1460 t.Lower(); 1471 t.LowerAllNodesAndLowerChanges();
1461 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1472 CHECK_EQ(IrOpcode::kStore, store->opcode());
1462 CHECK_EQ(val, store->InputAt(2)); 1473 CHECK_EQ(val, store->InputAt(2));
1463 CheckElementAccessArithmetic(access, store); 1474 CheckElementAccessArithmetic(access, store);
1464 1475
1465 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); 1476 StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
1466 if (kMachineReps[i] & kRepTagged) { 1477 if (kMachineReps[i] & kRepTagged) {
1467 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); 1478 CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
1468 } 1479 }
1469 CHECK_EQ(kMachineReps[i], rep.machine_type()); 1480 CHECK_EQ(kMachineReps[i], rep.machine_type());
1470 } 1481 }
1471 } 1482 }
1472 { 1483 {
1473 HandleAndZoneScope scope; 1484 HandleAndZoneScope scope;
1474 Zone* z = scope.main_zone(); 1485 Zone* z = scope.main_zone();
1475 TestingGraph t( 1486 TestingGraph t(
1476 Type::Any(), Type::Signed32(), 1487 Type::Any(), Type::Signed32(),
1477 Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); 1488 Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z));
1478 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1489 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1479 Type::Any(), kMachAnyTagged}; 1490 Type::Any(), kMachAnyTagged};
1480 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, 1491 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
1481 t.p1, t.p2, t.start, t.start); 1492 t.p1, t.p2, t.start, t.start);
1482 t.Effect(store); 1493 t.Effect(store);
1483 t.Lower(); 1494 t.LowerAllNodesAndLowerChanges();
1484 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1495 CHECK_EQ(IrOpcode::kStore, store->opcode());
1485 CHECK_EQ(t.p2, store->InputAt(2)); 1496 CHECK_EQ(t.p2, store->InputAt(2));
1486 StoreRepresentation rep = OpParameter<StoreRepresentation>(store); 1497 StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
1487 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); 1498 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind());
1488 } 1499 }
1489 } 1500 }
1490 1501
1491 1502
1492 TEST(InsertChangeForLoadElementIndex) { 1503 TEST(InsertChangeForLoadElementIndex) {
1493 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => 1504 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) =>
1494 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) 1505 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k))
1495 TestingGraph t(Type::Any(), Type::Signed32()); 1506 TestingGraph t(Type::Any(), Type::Signed32());
1496 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), 1507 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
1497 kMachAnyTagged}; 1508 kMachAnyTagged};
1498 1509
1499 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, 1510 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
1500 t.p1, t.start, t.start); 1511 t.p1, t.start, t.start);
1501 t.Return(load); 1512 t.Return(load);
1502 t.Lower(); 1513 t.Lower();
1503 CHECK_EQ(IrOpcode::kLoad, load->opcode()); 1514 CHECK_EQ(IrOpcode::kLoadElement, load->opcode());
1504 CHECK_EQ(t.p0, load->InputAt(0)); 1515 CHECK_EQ(t.p0, load->InputAt(0));
1505 1516 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, load->InputAt(1));
1506 Node* index = CheckElementAccessArithmetic(access, load);
1507 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index);
1508 } 1517 }
1509 1518
1510 1519
1511 TEST(InsertChangeForStoreElementIndex) { 1520 TEST(InsertChangeForStoreElementIndex) {
1512 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => 1521 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) =>
1513 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) 1522 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val)
1514 TestingGraph t(Type::Any(), Type::Signed32()); 1523 TestingGraph t(Type::Any(), Type::Signed32());
1515 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), 1524 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
1516 kMachAnyTagged}; 1525 kMachAnyTagged};
1517 1526
1518 Node* store = 1527 Node* store =
1519 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, 1528 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1,
1520 t.jsgraph.TrueConstant(), t.start, t.start); 1529 t.jsgraph.TrueConstant(), t.start, t.start);
1521 t.Effect(store); 1530 t.Effect(store);
1522 t.Lower(); 1531 t.Lower();
1523 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1532 CHECK_EQ(IrOpcode::kStoreElement, store->opcode());
1524 CHECK_EQ(t.p0, store->InputAt(0)); 1533 CHECK_EQ(t.p0, store->InputAt(0));
1525 1534 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, store->InputAt(1));
1526 Node* index = CheckElementAccessArithmetic(access, store);
1527 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, index);
1528 } 1535 }
1529 1536
1530 1537
1531 TEST(InsertChangeForLoadElement) { 1538 TEST(InsertChangeForLoadElement) {
1532 // TODO(titzer): test all load/store representation change insertions. 1539 // TODO(titzer): test all load/store representation change insertions.
1533 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); 1540 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
1534 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), 1541 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
1535 kMachFloat64}; 1542 kMachFloat64};
1536 1543
1537 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, 1544 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
1538 t.p1, t.start, t.start); 1545 t.p1, t.start, t.start);
1539 t.Return(load); 1546 t.Return(load);
1540 t.Lower(); 1547 t.Lower();
1541 CHECK_EQ(IrOpcode::kLoad, load->opcode()); 1548 CHECK_EQ(IrOpcode::kLoadElement, load->opcode());
1542 CHECK_EQ(t.p0, load->InputAt(0)); 1549 CHECK_EQ(t.p0, load->InputAt(0));
1543 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); 1550 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
1544 } 1551 }
1545 1552
1546 1553
1547 TEST(InsertChangeForLoadField) { 1554 TEST(InsertChangeForLoadField) {
1548 // TODO(titzer): test all load/store representation change insertions. 1555 // TODO(titzer): test all load/store representation change insertions.
1549 TestingGraph t(Type::Any(), Type::Signed32()); 1556 TestingGraph t(Type::Any(), Type::Signed32());
1550 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1557 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1551 Handle<Name>::null(), Type::Any(), kMachFloat64}; 1558 Handle<Name>::null(), Type::Any(), kMachFloat64};
1552 1559
1553 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, 1560 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
1554 t.start, t.start); 1561 t.start, t.start);
1555 t.Return(load); 1562 t.Return(load);
1556 t.Lower(); 1563 t.Lower();
1557 CHECK_EQ(IrOpcode::kLoad, load->opcode()); 1564 CHECK_EQ(IrOpcode::kLoadField, load->opcode());
1558 CHECK_EQ(t.p0, load->InputAt(0)); 1565 CHECK_EQ(t.p0, load->InputAt(0));
1559 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); 1566 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
1560 } 1567 }
1561 1568
1562 1569
1563 TEST(InsertChangeForStoreElement) { 1570 TEST(InsertChangeForStoreElement) {
1564 // TODO(titzer): test all load/store representation change insertions. 1571 // TODO(titzer): test all load/store representation change insertions.
1565 TestingGraph t(Type::Any(), Type::Signed32()); 1572 TestingGraph t(Type::Any(), Type::Signed32());
1566 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), 1573 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
1567 kMachFloat64}; 1574 kMachFloat64};
1568 1575
1569 Node* store = 1576 Node* store =
1570 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, 1577 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
1571 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); 1578 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start);
1572 t.Effect(store); 1579 t.Effect(store);
1573 t.Lower(); 1580 t.Lower();
1574 1581
1575 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1582 CHECK_EQ(IrOpcode::kStoreElement, store->opcode());
1576 CHECK_EQ(t.p0, store->InputAt(0)); 1583 CHECK_EQ(t.p0, store->InputAt(0));
1577 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); 1584 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2));
1578 } 1585 }
1579 1586
1580 1587
1581 TEST(InsertChangeForStoreField) { 1588 TEST(InsertChangeForStoreField) {
1582 // TODO(titzer): test all load/store representation change insertions. 1589 // TODO(titzer): test all load/store representation change insertions.
1583 TestingGraph t(Type::Any(), Type::Signed32()); 1590 TestingGraph t(Type::Any(), Type::Signed32());
1584 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, 1591 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
1585 Handle<Name>::null(), Type::Any(), kMachFloat64}; 1592 Handle<Name>::null(), Type::Any(), kMachFloat64};
1586 1593
1587 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, 1594 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
1588 t.p1, t.start, t.start); 1595 t.p1, t.start, t.start);
1589 t.Effect(store); 1596 t.Effect(store);
1590 t.Lower(); 1597 t.Lower();
1591 1598
1592 CHECK_EQ(IrOpcode::kStore, store->opcode()); 1599 CHECK_EQ(IrOpcode::kStoreField, store->opcode());
1593 CHECK_EQ(t.p0, store->InputAt(0)); 1600 CHECK_EQ(t.p0, store->InputAt(0));
1594 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); 1601 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(1));
1595 } 1602 }
1596 1603
1597 1604
1598 TEST(UpdatePhi) { 1605 TEST(UpdatePhi) {
1599 TestingGraph t(Type::Any(), Type::Signed32()); 1606 TestingGraph t(Type::Any(), Type::Signed32());
1600 static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32, 1607 static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32,
1601 kMachFloat64}; 1608 kMachFloat64};
1602 Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()}; 1609 Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()};
1603 1610
1604 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { 1611 for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
(...skipping 16 matching lines...) Expand all
1621 } 1628 }
1622 1629
1623 1630
1624 TEST(RunNumberDivide_minus_1_TruncatingToInt32) { 1631 TEST(RunNumberDivide_minus_1_TruncatingToInt32) {
1625 SimplifiedLoweringTester<Object*> t(kMachAnyTagged); 1632 SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
1626 Node* num = t.NumberToInt32(t.Parameter(0)); 1633 Node* num = t.NumberToInt32(t.Parameter(0));
1627 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1)); 1634 Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1));
1628 Node* trunc = t.NumberToInt32(div); 1635 Node* trunc = t.NumberToInt32(div);
1629 t.Return(trunc); 1636 t.Return(trunc);
1630 1637
1631 t.LowerAllNodesAndLowerChanges(); 1638 t.LowerAllNodesAndLowerChanges();
1632 t.GenerateCode(); 1639 t.GenerateCode();
1633 1640
1634 FOR_INT32_INPUTS(i) { 1641 FOR_INT32_INPUTS(i) {
1635 int32_t x = 0 - *i; 1642 int32_t x = 0 - *i;
1636 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i)); 1643 t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
1637 } 1644 }
1638 } 1645 }
1639 1646
1640 1647
1641 TEST(NumberMultiply_TruncatingToInt32) { 1648 TEST(NumberMultiply_TruncatingToInt32) {
1642 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000}; 1649 int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000};
1643 1650
1644 for (size_t i = 0; i < arraysize(constants); i++) { 1651 for (size_t i = 0; i < arraysize(constants); i++) {
1645 TestingGraph t(Type::Signed32()); 1652 TestingGraph t(Type::Signed32());
1646 Node* k = t.jsgraph.Constant(constants[i]); 1653 Node* k = t.jsgraph.Constant(constants[i]);
1647 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k); 1654 Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 t.Return(use); 2011 t.Return(use);
2005 t.Lower(); 2012 t.Lower();
2006 2013
2007 CHECK_EQ(d.expected, OpParameter<MachineType>(phi)); 2014 CHECK_EQ(d.expected, OpParameter<MachineType>(phi));
2008 } 2015 }
2009 } 2016 }
2010 2017
2011 } // namespace compiler 2018 } // namespace compiler
2012 } // namespace internal 2019 } // namespace internal
2013 } // namespace v8 2020 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.cc ('k') | test/unittests/compiler/change-lowering-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698