OLD | NEW |
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 #include <limits> | 5 #include <limits> |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/access-builder.h" | 8 #include "src/compiler/access-builder.h" |
9 #include "src/compiler/change-lowering.h" | 9 #include "src/compiler/change-lowering.h" |
10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 }; | 99 }; |
100 | 100 |
101 | 101 |
102 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. | 102 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc. |
103 // TODO(titzer): test tagged representation for input to NumberToInt32. | 103 // TODO(titzer): test tagged representation for input to NumberToInt32. |
104 TEST(RunNumberToInt32_float64) { | 104 TEST(RunNumberToInt32_float64) { |
105 // TODO(titzer): explicit load/stores here are only because of representations | 105 // TODO(titzer): explicit load/stores here are only because of representations |
106 double input; | 106 double input; |
107 int32_t result; | 107 int32_t result; |
108 SimplifiedLoweringTester<Object*> t; | 108 SimplifiedLoweringTester<Object*> t; |
109 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 109 FieldAccess load = {kUntaggedBase, 0, |
110 MachineType::Float64()}; | 110 Handle<Name>(), Type::Number(), |
| 111 MachineType::Float64(), kNoWriteBarrier}; |
111 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); | 112 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
112 NodeProperties::SetType(loaded, Type::Number()); | 113 NodeProperties::SetType(loaded, Type::Number()); |
113 Node* convert = t.NumberToInt32(loaded); | 114 Node* convert = t.NumberToInt32(loaded); |
114 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(), | 115 FieldAccess store = {kUntaggedBase, 0, |
115 MachineType::Int32()}; | 116 Handle<Name>(), Type::Signed32(), |
| 117 MachineType::Int32(), kNoWriteBarrier}; |
116 t.StoreField(store, t.PointerConstant(&result), convert); | 118 t.StoreField(store, t.PointerConstant(&result), convert); |
117 t.Return(t.jsgraph.TrueConstant()); | 119 t.Return(t.jsgraph.TrueConstant()); |
118 t.LowerAllNodesAndLowerChanges(); | 120 t.LowerAllNodesAndLowerChanges(); |
119 t.GenerateCode(); | 121 t.GenerateCode(); |
120 | 122 |
121 FOR_FLOAT64_INPUTS(i) { | 123 FOR_FLOAT64_INPUTS(i) { |
122 input = *i; | 124 input = *i; |
123 int32_t expected = DoubleToInt32(*i); | 125 int32_t expected = DoubleToInt32(*i); |
124 t.Call(); | 126 t.Call(); |
125 CHECK_EQ(expected, result); | 127 CHECK_EQ(expected, result); |
126 } | 128 } |
127 } | 129 } |
128 | 130 |
129 | 131 |
130 // TODO(titzer): test tagged representation for input to NumberToUint32. | 132 // TODO(titzer): test tagged representation for input to NumberToUint32. |
131 TEST(RunNumberToUint32_float64) { | 133 TEST(RunNumberToUint32_float64) { |
132 // TODO(titzer): explicit load/stores here are only because of representations | 134 // TODO(titzer): explicit load/stores here are only because of representations |
133 double input; | 135 double input; |
134 uint32_t result; | 136 uint32_t result; |
135 SimplifiedLoweringTester<Object*> t; | 137 SimplifiedLoweringTester<Object*> t; |
136 FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(), | 138 FieldAccess load = {kUntaggedBase, 0, |
137 MachineType::Float64()}; | 139 Handle<Name>(), Type::Number(), |
| 140 MachineType::Float64(), kNoWriteBarrier}; |
138 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); | 141 Node* loaded = t.LoadField(load, t.PointerConstant(&input)); |
139 NodeProperties::SetType(loaded, Type::Number()); | 142 NodeProperties::SetType(loaded, Type::Number()); |
140 Node* convert = t.NumberToUint32(loaded); | 143 Node* convert = t.NumberToUint32(loaded); |
141 FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(), | 144 FieldAccess store = {kUntaggedBase, 0, |
142 MachineType::Uint32()}; | 145 Handle<Name>(), Type::Unsigned32(), |
| 146 MachineType::Uint32(), kNoWriteBarrier}; |
143 t.StoreField(store, t.PointerConstant(&result), convert); | 147 t.StoreField(store, t.PointerConstant(&result), convert); |
144 t.Return(t.jsgraph.TrueConstant()); | 148 t.Return(t.jsgraph.TrueConstant()); |
145 t.LowerAllNodesAndLowerChanges(); | 149 t.LowerAllNodesAndLowerChanges(); |
146 t.GenerateCode(); | 150 t.GenerateCode(); |
147 | 151 |
148 FOR_FLOAT64_INPUTS(i) { | 152 FOR_FLOAT64_INPUTS(i) { |
149 input = *i; | 153 input = *i; |
150 uint32_t expected = DoubleToUint32(*i); | 154 uint32_t expected = DoubleToUint32(*i); |
151 t.Call(); | 155 t.Call(); |
152 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); | 156 CHECK_EQ(static_cast<int32_t>(expected), static_cast<int32_t>(result)); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 CHECK_EQ(data[i], expected); | 295 CHECK_EQ(data[i], expected); |
292 } | 296 } |
293 } | 297 } |
294 | 298 |
295 | 299 |
296 TEST(RunLoadFieldFromUntaggedBase) { | 300 TEST(RunLoadFieldFromUntaggedBase) { |
297 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 301 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
298 | 302 |
299 for (size_t i = 0; i < arraysize(smis); i++) { | 303 for (size_t i = 0; i < arraysize(smis); i++) { |
300 int offset = static_cast<int>(i * sizeof(Smi*)); | 304 int offset = static_cast<int>(i * sizeof(Smi*)); |
301 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 305 FieldAccess access = {kUntaggedBase, |
302 Type::Integral32(), MachineType::AnyTagged()}; | 306 offset, |
| 307 Handle<Name>(), |
| 308 Type::Integral32(), |
| 309 MachineType::AnyTagged(), |
| 310 kNoWriteBarrier}; |
303 | 311 |
304 SimplifiedLoweringTester<Object*> t; | 312 SimplifiedLoweringTester<Object*> t; |
305 Node* load = t.LoadField(access, t.PointerConstant(smis)); | 313 Node* load = t.LoadField(access, t.PointerConstant(smis)); |
306 t.Return(load); | 314 t.Return(load); |
307 t.LowerAllNodesAndLowerChanges(); | 315 t.LowerAllNodesAndLowerChanges(); |
308 | 316 |
309 for (int j = -5; j <= 5; j++) { | 317 for (int j = -5; j <= 5; j++) { |
310 Smi* expected = Smi::FromInt(j); | 318 Smi* expected = Smi::FromInt(j); |
311 smis[i] = expected; | 319 smis[i] = expected; |
312 CHECK_EQ(expected, t.Call()); | 320 CHECK_EQ(expected, t.Call()); |
313 } | 321 } |
314 } | 322 } |
315 } | 323 } |
316 | 324 |
317 | 325 |
318 TEST(RunStoreFieldToUntaggedBase) { | 326 TEST(RunStoreFieldToUntaggedBase) { |
319 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; | 327 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3)}; |
320 | 328 |
321 for (size_t i = 0; i < arraysize(smis); i++) { | 329 for (size_t i = 0; i < arraysize(smis); i++) { |
322 int offset = static_cast<int>(i * sizeof(Smi*)); | 330 int offset = static_cast<int>(i * sizeof(Smi*)); |
323 FieldAccess access = {kUntaggedBase, offset, Handle<Name>(), | 331 FieldAccess access = {kUntaggedBase, |
324 Type::Integral32(), MachineType::AnyTagged()}; | 332 offset, |
| 333 Handle<Name>(), |
| 334 Type::Integral32(), |
| 335 MachineType::AnyTagged(), |
| 336 kNoWriteBarrier}; |
325 | 337 |
326 SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); | 338 SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); |
327 Node* p0 = t.Parameter(0); | 339 Node* p0 = t.Parameter(0); |
328 t.StoreField(access, t.PointerConstant(smis), p0); | 340 t.StoreField(access, t.PointerConstant(smis), p0); |
329 t.Return(p0); | 341 t.Return(p0); |
330 t.LowerAllNodesAndLowerChanges(); | 342 t.LowerAllNodesAndLowerChanges(); |
331 | 343 |
332 for (int j = -5; j <= 5; j++) { | 344 for (int j = -5; j <= 5; j++) { |
333 Smi* expected = Smi::FromInt(j); | 345 Smi* expected = Smi::FromInt(j); |
334 smis[i] = Smi::FromInt(-100); | 346 smis[i] = Smi::FromInt(-100); |
335 CHECK_EQ(expected, t.Call(expected)); | 347 CHECK_EQ(expected, t.Call(expected)); |
336 CHECK_EQ(expected, smis[i]); | 348 CHECK_EQ(expected, smis[i]); |
337 } | 349 } |
338 } | 350 } |
339 } | 351 } |
340 | 352 |
341 | 353 |
342 TEST(RunLoadElementFromUntaggedBase) { | 354 TEST(RunLoadElementFromUntaggedBase) { |
343 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 355 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
344 Smi::FromInt(4), Smi::FromInt(5)}; | 356 Smi::FromInt(4), Smi::FromInt(5)}; |
345 | 357 |
346 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 358 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
347 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 359 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
348 int offset = static_cast<int>(i * sizeof(Smi*)); | 360 int offset = static_cast<int>(i * sizeof(Smi*)); |
349 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), | 361 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
350 MachineType::AnyTagged()}; | 362 MachineType::AnyTagged(), kNoWriteBarrier}; |
351 | 363 |
352 SimplifiedLoweringTester<Object*> t; | 364 SimplifiedLoweringTester<Object*> t; |
353 Node* load = t.LoadElement(access, t.PointerConstant(smis), | 365 Node* load = t.LoadElement(access, t.PointerConstant(smis), |
354 t.Int32Constant(static_cast<int>(j))); | 366 t.Int32Constant(static_cast<int>(j))); |
355 t.Return(load); | 367 t.Return(load); |
356 t.LowerAllNodesAndLowerChanges(); | 368 t.LowerAllNodesAndLowerChanges(); |
357 | 369 |
358 for (int k = -5; k <= 5; k++) { | 370 for (int k = -5; k <= 5; k++) { |
359 Smi* expected = Smi::FromInt(k); | 371 Smi* expected = Smi::FromInt(k); |
360 smis[i + j] = expected; | 372 smis[i + j] = expected; |
361 CHECK_EQ(expected, t.Call()); | 373 CHECK_EQ(expected, t.Call()); |
362 } | 374 } |
363 } | 375 } |
364 } | 376 } |
365 } | 377 } |
366 | 378 |
367 | 379 |
368 TEST(RunStoreElementFromUntaggedBase) { | 380 TEST(RunStoreElementFromUntaggedBase) { |
369 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), | 381 Smi* smis[] = {Smi::FromInt(1), Smi::FromInt(2), Smi::FromInt(3), |
370 Smi::FromInt(4), Smi::FromInt(5)}; | 382 Smi::FromInt(4), Smi::FromInt(5)}; |
371 | 383 |
372 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes | 384 for (size_t i = 0; i < arraysize(smis); i++) { // for header sizes |
373 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index | 385 for (size_t j = 0; (i + j) < arraysize(smis); j++) { // for element index |
374 int offset = static_cast<int>(i * sizeof(Smi*)); | 386 int offset = static_cast<int>(i * sizeof(Smi*)); |
375 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), | 387 ElementAccess access = {kUntaggedBase, offset, Type::Integral32(), |
376 MachineType::AnyTagged()}; | 388 MachineType::AnyTagged(), kNoWriteBarrier}; |
377 | 389 |
378 SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); | 390 SimplifiedLoweringTester<Object*> t(MachineType::AnyTagged()); |
379 Node* p0 = t.Parameter(0); | 391 Node* p0 = t.Parameter(0); |
380 t.StoreElement(access, t.PointerConstant(smis), | 392 t.StoreElement(access, t.PointerConstant(smis), |
381 t.Int32Constant(static_cast<int>(j)), p0); | 393 t.Int32Constant(static_cast<int>(j)), p0); |
382 t.Return(p0); | 394 t.Return(p0); |
383 t.LowerAllNodesAndLowerChanges(); | 395 t.LowerAllNodesAndLowerChanges(); |
384 | 396 |
385 for (int k = -5; k <= 5; k++) { | 397 for (int k = -5; k <= 5; k++) { |
386 Smi* expected = Smi::FromInt(k); | 398 Smi* expected = Smi::FromInt(k); |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 return GetTaggedElement(index); | 530 return GetTaggedElement(index); |
519 } else { | 531 } else { |
520 return untagged_array[index]; | 532 return untagged_array[index]; |
521 } | 533 } |
522 } | 534 } |
523 | 535 |
524 private: | 536 private: |
525 ElementAccess GetElementAccess() { | 537 ElementAccess GetElementAccess() { |
526 ElementAccess access = {tagged ? kTaggedBase : kUntaggedBase, | 538 ElementAccess access = {tagged ? kTaggedBase : kUntaggedBase, |
527 tagged ? FixedArrayBase::kHeaderSize : 0, | 539 tagged ? FixedArrayBase::kHeaderSize : 0, |
528 Type::Any(), rep}; | 540 Type::Any(), rep, kFullWriteBarrier}; |
529 return access; | 541 return access; |
530 } | 542 } |
531 | 543 |
532 FieldAccess GetFieldAccess(int field) { | 544 FieldAccess GetFieldAccess(int field) { |
533 int offset = field * sizeof(E); | 545 int offset = field * sizeof(E); |
534 FieldAccess access = {tagged ? kTaggedBase : kUntaggedBase, | 546 FieldAccess access = {tagged ? kTaggedBase : kUntaggedBase, |
535 offset + (tagged ? FixedArrayBase::kHeaderSize : 0), | 547 offset + (tagged ? FixedArrayBase::kHeaderSize : 0), |
536 Handle<Name>(), Type::Any(), rep}; | 548 Handle<Name>(), |
| 549 Type::Any(), |
| 550 rep, |
| 551 kFullWriteBarrier}; |
537 return access; | 552 return access; |
538 } | 553 } |
539 | 554 |
540 template <typename T> | 555 template <typename T> |
541 Node* GetBaseNode(SimplifiedLoweringTester<T>* t) { | 556 Node* GetBaseNode(SimplifiedLoweringTester<T>* t) { |
542 return tagged ? t->HeapConstant(tagged_array) | 557 return tagged ? t->HeapConstant(tagged_array) |
543 : t->PointerConstant(untagged_array); | 558 : t->PointerConstant(untagged_array); |
544 } | 559 } |
545 | 560 |
546 void BoundsCheck(int index) { | 561 void BoundsCheck(int index) { |
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 MachineType::Int8(), MachineType::Int16(), MachineType::Int32(), | 1320 MachineType::Int8(), MachineType::Int16(), MachineType::Int32(), |
1306 MachineType::Uint32(), MachineType::Int64(), MachineType::Float64(), | 1321 MachineType::Uint32(), MachineType::Int64(), MachineType::Float64(), |
1307 MachineType::AnyTagged()}; | 1322 MachineType::AnyTagged()}; |
1308 | 1323 |
1309 } // namespace | 1324 } // namespace |
1310 | 1325 |
1311 | 1326 |
1312 TEST(LowerLoadField_to_load) { | 1327 TEST(LowerLoadField_to_load) { |
1313 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1328 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1314 TestingGraph t(Type::Any(), Type::Signed32()); | 1329 TestingGraph t(Type::Any(), Type::Signed32()); |
1315 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1330 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1316 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; | 1331 Handle<Name>::null(), Type::Any(), |
| 1332 kMachineReps[i], kNoWriteBarrier}; |
1317 | 1333 |
1318 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, | 1334 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, |
1319 t.start, t.start); | 1335 t.start, t.start); |
1320 Node* use = t.Use(load, kMachineReps[i]); | 1336 Node* use = t.Use(load, kMachineReps[i]); |
1321 t.Return(use); | 1337 t.Return(use); |
1322 t.LowerAllNodesAndLowerChanges(); | 1338 t.LowerAllNodesAndLowerChanges(); |
1323 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1339 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1324 CHECK_EQ(t.p0, load->InputAt(0)); | 1340 CHECK_EQ(t.p0, load->InputAt(0)); |
1325 CheckFieldAccessArithmetic(access, load); | 1341 CheckFieldAccessArithmetic(access, load); |
1326 | 1342 |
1327 MachineType rep = LoadRepresentationOf(load->op()); | 1343 MachineType rep = LoadRepresentationOf(load->op()); |
1328 CHECK_EQ(kMachineReps[i], rep); | 1344 CHECK_EQ(kMachineReps[i], rep); |
1329 } | 1345 } |
1330 } | 1346 } |
1331 | 1347 |
1332 | 1348 |
1333 TEST(LowerStoreField_to_store) { | 1349 TEST(LowerStoreField_to_store) { |
1334 { | 1350 { |
1335 TestingGraph t(Type::Any(), Type::Signed32()); | 1351 TestingGraph t(Type::Any(), Type::Signed32()); |
1336 | 1352 |
1337 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1353 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1338 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1354 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1339 Handle<Name>::null(), Type::Any(), kMachineReps[i]}; | 1355 Handle<Name>::null(), Type::Any(), |
1340 | 1356 kMachineReps[i], kNoWriteBarrier}; |
1341 | 1357 |
1342 Node* val = t.ExampleWithOutput(kMachineReps[i]); | 1358 Node* val = t.ExampleWithOutput(kMachineReps[i]); |
1343 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1359 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1344 val, t.start, t.start); | 1360 val, t.start, t.start); |
1345 t.Effect(store); | 1361 t.Effect(store); |
1346 t.LowerAllNodesAndLowerChanges(); | 1362 t.LowerAllNodesAndLowerChanges(); |
1347 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1363 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1348 CHECK_EQ(val, store->InputAt(2)); | 1364 CHECK_EQ(val, store->InputAt(2)); |
1349 CheckFieldAccessArithmetic(access, store); | 1365 CheckFieldAccessArithmetic(access, store); |
1350 | 1366 |
1351 StoreRepresentation rep = StoreRepresentationOf(store->op()); | 1367 StoreRepresentation rep = StoreRepresentationOf(store->op()); |
1352 if (kMachineReps[i].representation() == MachineRepresentation::kTagged) { | 1368 if (kMachineReps[i].representation() == MachineRepresentation::kTagged) { |
1353 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); | 1369 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); |
1354 } | 1370 } |
1355 CHECK_EQ(kMachineReps[i].representation(), rep.representation()); | 1371 CHECK_EQ(kMachineReps[i].representation(), rep.representation()); |
1356 } | 1372 } |
1357 } | 1373 } |
1358 { | 1374 { |
1359 HandleAndZoneScope scope; | 1375 HandleAndZoneScope scope; |
1360 Zone* z = scope.main_zone(); | 1376 Zone* z = scope.main_zone(); |
1361 TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(), | 1377 TestingGraph t(Type::Any(), Type::Intersect(Type::SignedSmall(), |
1362 Type::TaggedSigned(), z)); | 1378 Type::TaggedSigned(), z)); |
1363 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1379 FieldAccess access = { |
1364 Handle<Name>::null(), Type::Any(), | 1380 kTaggedBase, FixedArrayBase::kHeaderSize, Handle<Name>::null(), |
1365 MachineType::AnyTagged()}; | 1381 Type::Any(), MachineType::AnyTagged(), kNoWriteBarrier}; |
1366 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1382 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1367 t.p1, t.start, t.start); | 1383 t.p1, t.start, t.start); |
1368 t.Effect(store); | 1384 t.Effect(store); |
1369 t.LowerAllNodesAndLowerChanges(); | 1385 t.LowerAllNodesAndLowerChanges(); |
1370 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1386 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1371 CHECK_EQ(t.p1, store->InputAt(2)); | 1387 CHECK_EQ(t.p1, store->InputAt(2)); |
1372 StoreRepresentation rep = StoreRepresentationOf(store->op()); | 1388 StoreRepresentation rep = StoreRepresentationOf(store->op()); |
1373 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); | 1389 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); |
1374 } | 1390 } |
1375 } | 1391 } |
1376 | 1392 |
1377 | 1393 |
1378 TEST(LowerLoadElement_to_load) { | 1394 TEST(LowerLoadElement_to_load) { |
1379 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1395 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1380 TestingGraph t(Type::Any(), Type::Signed32()); | 1396 TestingGraph t(Type::Any(), Type::Signed32()); |
1381 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1397 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1382 Type::Any(), kMachineReps[i]}; | 1398 Type::Any(), kMachineReps[i], kNoWriteBarrier}; |
1383 | 1399 |
1384 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1400 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1385 t.p1, t.start, t.start); | 1401 t.p1, t.start, t.start); |
1386 Node* use = t.Use(load, kMachineReps[i]); | 1402 Node* use = t.Use(load, kMachineReps[i]); |
1387 t.Return(use); | 1403 t.Return(use); |
1388 t.LowerAllNodesAndLowerChanges(); | 1404 t.LowerAllNodesAndLowerChanges(); |
1389 CHECK_EQ(IrOpcode::kLoad, load->opcode()); | 1405 CHECK_EQ(IrOpcode::kLoad, load->opcode()); |
1390 CHECK_EQ(t.p0, load->InputAt(0)); | 1406 CHECK_EQ(t.p0, load->InputAt(0)); |
1391 CheckElementAccessArithmetic(access, load); | 1407 CheckElementAccessArithmetic(access, load); |
1392 | 1408 |
1393 MachineType rep = LoadRepresentationOf(load->op()); | 1409 MachineType rep = LoadRepresentationOf(load->op()); |
1394 CHECK_EQ(kMachineReps[i], rep); | 1410 CHECK_EQ(kMachineReps[i], rep); |
1395 } | 1411 } |
1396 } | 1412 } |
1397 | 1413 |
1398 | 1414 |
1399 TEST(LowerStoreElement_to_store) { | 1415 TEST(LowerStoreElement_to_store) { |
1400 { | 1416 { |
1401 for (size_t i = 0; i < arraysize(kMachineReps); i++) { | 1417 for (size_t i = 0; i < arraysize(kMachineReps); i++) { |
1402 TestingGraph t(Type::Any(), Type::Signed32()); | 1418 TestingGraph t(Type::Any(), Type::Signed32()); |
1403 | 1419 |
1404 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1420 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1405 Type::Any(), kMachineReps[i]}; | 1421 Type::Any(), kMachineReps[i], kNoWriteBarrier}; |
1406 | 1422 |
1407 Node* val = t.ExampleWithOutput(kMachineReps[i]); | 1423 Node* val = t.ExampleWithOutput(kMachineReps[i]); |
1408 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), | 1424 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), |
1409 t.p0, t.p1, val, t.start, t.start); | 1425 t.p0, t.p1, val, t.start, t.start); |
1410 t.Effect(store); | 1426 t.Effect(store); |
1411 t.LowerAllNodesAndLowerChanges(); | 1427 t.LowerAllNodesAndLowerChanges(); |
1412 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1428 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1413 CHECK_EQ(val, store->InputAt(2)); | 1429 CHECK_EQ(val, store->InputAt(2)); |
1414 CheckElementAccessArithmetic(access, store); | 1430 CheckElementAccessArithmetic(access, store); |
1415 | 1431 |
1416 StoreRepresentation rep = StoreRepresentationOf(store->op()); | 1432 StoreRepresentation rep = StoreRepresentationOf(store->op()); |
1417 if (kMachineReps[i].representation() == MachineRepresentation::kTagged) { | 1433 if (kMachineReps[i].representation() == MachineRepresentation::kTagged) { |
1418 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); | 1434 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); |
1419 } | 1435 } |
1420 CHECK_EQ(kMachineReps[i].representation(), rep.representation()); | 1436 CHECK_EQ(kMachineReps[i].representation(), rep.representation()); |
1421 } | 1437 } |
1422 } | 1438 } |
1423 { | 1439 { |
1424 HandleAndZoneScope scope; | 1440 HandleAndZoneScope scope; |
1425 Zone* z = scope.main_zone(); | 1441 Zone* z = scope.main_zone(); |
1426 TestingGraph t( | 1442 TestingGraph t( |
1427 Type::Any(), Type::Signed32(), | 1443 Type::Any(), Type::Signed32(), |
1428 Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); | 1444 Type::Intersect(Type::SignedSmall(), Type::TaggedSigned(), z)); |
1429 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1445 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1430 Type::Any(), MachineType::AnyTagged()}; | 1446 Type::Any(), MachineType::AnyTagged(), |
| 1447 kNoWriteBarrier}; |
1431 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, | 1448 Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, |
1432 t.p1, t.p2, t.start, t.start); | 1449 t.p1, t.p2, t.start, t.start); |
1433 t.Effect(store); | 1450 t.Effect(store); |
1434 t.LowerAllNodesAndLowerChanges(); | 1451 t.LowerAllNodesAndLowerChanges(); |
1435 CHECK_EQ(IrOpcode::kStore, store->opcode()); | 1452 CHECK_EQ(IrOpcode::kStore, store->opcode()); |
1436 CHECK_EQ(t.p2, store->InputAt(2)); | 1453 CHECK_EQ(t.p2, store->InputAt(2)); |
1437 StoreRepresentation rep = StoreRepresentationOf(store->op()); | 1454 StoreRepresentation rep = StoreRepresentationOf(store->op()); |
1438 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); | 1455 CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); |
1439 } | 1456 } |
1440 } | 1457 } |
1441 | 1458 |
1442 | 1459 |
1443 TEST(InsertChangeForLoadElementIndex) { | 1460 TEST(InsertChangeForLoadElementIndex) { |
1444 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => | 1461 // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) => |
1445 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) | 1462 // Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k)) |
1446 TestingGraph t(Type::Any(), Type::Signed32()); | 1463 TestingGraph t(Type::Any(), Type::Signed32()); |
1447 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1464 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1448 MachineType::AnyTagged()}; | 1465 MachineType::AnyTagged(), kNoWriteBarrier}; |
1449 | 1466 |
1450 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1467 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1451 t.p1, t.start, t.start); | 1468 t.p1, t.start, t.start); |
1452 t.Return(load); | 1469 t.Return(load); |
1453 t.Lower(); | 1470 t.Lower(); |
1454 CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); | 1471 CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); |
1455 CHECK_EQ(t.p0, load->InputAt(0)); | 1472 CHECK_EQ(t.p0, load->InputAt(0)); |
1456 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, load->InputAt(1)); | 1473 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, load->InputAt(1)); |
1457 } | 1474 } |
1458 | 1475 |
1459 | 1476 |
1460 TEST(InsertChangeForStoreElementIndex) { | 1477 TEST(InsertChangeForStoreElementIndex) { |
1461 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => | 1478 // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) => |
1462 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) | 1479 // Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val) |
1463 TestingGraph t(Type::Any(), Type::Signed32()); | 1480 TestingGraph t(Type::Any(), Type::Signed32()); |
1464 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1481 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1465 MachineType::AnyTagged()}; | 1482 MachineType::AnyTagged(), kFullWriteBarrier}; |
1466 | 1483 |
1467 Node* store = | 1484 Node* store = |
1468 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, | 1485 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, |
1469 t.jsgraph.TrueConstant(), t.start, t.start); | 1486 t.jsgraph.TrueConstant(), t.start, t.start); |
1470 t.Effect(store); | 1487 t.Effect(store); |
1471 t.Lower(); | 1488 t.Lower(); |
1472 CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); | 1489 CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); |
1473 CHECK_EQ(t.p0, store->InputAt(0)); | 1490 CHECK_EQ(t.p0, store->InputAt(0)); |
1474 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, store->InputAt(1)); | 1491 CheckChangeOf(IrOpcode::kChangeTaggedToInt32, t.p1, store->InputAt(1)); |
1475 } | 1492 } |
1476 | 1493 |
1477 | 1494 |
1478 TEST(InsertChangeForLoadElement) { | 1495 TEST(InsertChangeForLoadElement) { |
1479 // TODO(titzer): test all load/store representation change insertions. | 1496 // TODO(titzer): test all load/store representation change insertions. |
1480 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); | 1497 TestingGraph t(Type::Any(), Type::Signed32(), Type::Any()); |
1481 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1498 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1482 MachineType::Float64()}; | 1499 MachineType::Float64(), kNoWriteBarrier}; |
1483 | 1500 |
1484 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, | 1501 Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, |
1485 t.p1, t.start, t.start); | 1502 t.p1, t.start, t.start); |
1486 t.Return(load); | 1503 t.Return(load); |
1487 t.Lower(); | 1504 t.Lower(); |
1488 CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); | 1505 CHECK_EQ(IrOpcode::kLoadElement, load->opcode()); |
1489 CHECK_EQ(t.p0, load->InputAt(0)); | 1506 CHECK_EQ(t.p0, load->InputAt(0)); |
1490 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); | 1507 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); |
1491 } | 1508 } |
1492 | 1509 |
1493 | 1510 |
1494 TEST(InsertChangeForLoadField) { | 1511 TEST(InsertChangeForLoadField) { |
1495 // TODO(titzer): test all load/store representation change insertions. | 1512 // TODO(titzer): test all load/store representation change insertions. |
1496 TestingGraph t(Type::Any(), Type::Signed32()); | 1513 TestingGraph t(Type::Any(), Type::Signed32()); |
1497 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1514 FieldAccess access = { |
1498 Handle<Name>::null(), Type::Any(), | 1515 kTaggedBase, FixedArrayBase::kHeaderSize, Handle<Name>::null(), |
1499 MachineType::Float64()}; | 1516 Type::Any(), MachineType::Float64(), kNoWriteBarrier}; |
1500 | 1517 |
1501 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, | 1518 Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, |
1502 t.start, t.start); | 1519 t.start, t.start); |
1503 t.Return(load); | 1520 t.Return(load); |
1504 t.Lower(); | 1521 t.Lower(); |
1505 CHECK_EQ(IrOpcode::kLoadField, load->opcode()); | 1522 CHECK_EQ(IrOpcode::kLoadField, load->opcode()); |
1506 CHECK_EQ(t.p0, load->InputAt(0)); | 1523 CHECK_EQ(t.p0, load->InputAt(0)); |
1507 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); | 1524 CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0)); |
1508 } | 1525 } |
1509 | 1526 |
1510 | 1527 |
1511 TEST(InsertChangeForStoreElement) { | 1528 TEST(InsertChangeForStoreElement) { |
1512 // TODO(titzer): test all load/store representation change insertions. | 1529 // TODO(titzer): test all load/store representation change insertions. |
1513 TestingGraph t(Type::Any(), Type::Signed32()); | 1530 TestingGraph t(Type::Any(), Type::Signed32()); |
1514 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), | 1531 ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(), |
1515 MachineType::Float64()}; | 1532 MachineType::Float64(), kFullWriteBarrier}; |
1516 | 1533 |
1517 Node* store = | 1534 Node* store = |
1518 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, | 1535 t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, |
1519 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); | 1536 t.jsgraph.Int32Constant(0), t.p1, t.start, t.start); |
1520 t.Effect(store); | 1537 t.Effect(store); |
1521 t.Lower(); | 1538 t.Lower(); |
1522 | 1539 |
1523 CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); | 1540 CHECK_EQ(IrOpcode::kStoreElement, store->opcode()); |
1524 CHECK_EQ(t.p0, store->InputAt(0)); | 1541 CHECK_EQ(t.p0, store->InputAt(0)); |
1525 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); | 1542 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2)); |
1526 } | 1543 } |
1527 | 1544 |
1528 | 1545 |
1529 TEST(InsertChangeForStoreField) { | 1546 TEST(InsertChangeForStoreField) { |
1530 // TODO(titzer): test all load/store representation change insertions. | 1547 // TODO(titzer): test all load/store representation change insertions. |
1531 TestingGraph t(Type::Any(), Type::Signed32()); | 1548 TestingGraph t(Type::Any(), Type::Signed32()); |
1532 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1549 FieldAccess access = { |
1533 Handle<Name>::null(), Type::Any(), | 1550 kTaggedBase, FixedArrayBase::kHeaderSize, Handle<Name>::null(), |
1534 MachineType::Float64()}; | 1551 Type::Any(), MachineType::Float64(), kNoWriteBarrier}; |
1535 | 1552 |
1536 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, | 1553 Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, |
1537 t.p1, t.start, t.start); | 1554 t.p1, t.start, t.start); |
1538 t.Effect(store); | 1555 t.Effect(store); |
1539 t.Lower(); | 1556 t.Lower(); |
1540 | 1557 |
1541 CHECK_EQ(IrOpcode::kStoreField, store->opcode()); | 1558 CHECK_EQ(IrOpcode::kStoreField, store->opcode()); |
1542 CHECK_EQ(t.p0, store->InputAt(0)); | 1559 CHECK_EQ(t.p0, store->InputAt(0)); |
1543 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(1)); | 1560 CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(1)); |
1544 } | 1561 } |
1545 | 1562 |
1546 | 1563 |
1547 TEST(UpdatePhi) { | 1564 TEST(UpdatePhi) { |
1548 TestingGraph t(Type::Any(), Type::Signed32()); | 1565 TestingGraph t(Type::Any(), Type::Signed32()); |
1549 static const MachineType kMachineTypes[] = { | 1566 static const MachineType kMachineTypes[] = { |
1550 MachineType::Int32(), MachineType::Uint32(), MachineType::Float64()}; | 1567 MachineType::Int32(), MachineType::Uint32(), MachineType::Float64()}; |
1551 Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()}; | 1568 Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()}; |
1552 | 1569 |
1553 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { | 1570 for (size_t i = 0; i < arraysize(kMachineTypes); i++) { |
1554 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, | 1571 FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, |
1555 Handle<Name>::null(), kTypes[i], kMachineTypes[i]}; | 1572 Handle<Name>::null(), kTypes[i], |
| 1573 kMachineTypes[i], kFullWriteBarrier}; |
1556 | 1574 |
1557 Node* load0 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, | 1575 Node* load0 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, |
1558 t.start, t.start); | 1576 t.start, t.start); |
1559 Node* load1 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p1, | 1577 Node* load1 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p1, |
1560 t.start, t.start); | 1578 t.start, t.start); |
1561 Node* phi = | 1579 Node* phi = |
1562 t.graph()->NewNode(t.common()->Phi(MachineRepresentation::kTagged, 2), | 1580 t.graph()->NewNode(t.common()->Phi(MachineRepresentation::kTagged, 2), |
1563 load0, load1, t.start); | 1581 load0, load1, t.start); |
1564 t.Return(t.Use(phi, kMachineTypes[i])); | 1582 t.Return(t.Use(phi, kMachineTypes[i])); |
1565 t.Lower(); | 1583 t.Lower(); |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1939 t.Return(use); | 1957 t.Return(use); |
1940 t.Lower(); | 1958 t.Lower(); |
1941 | 1959 |
1942 CHECK_EQ(d.expected, PhiRepresentationOf(phi->op())); | 1960 CHECK_EQ(d.expected, PhiRepresentationOf(phi->op())); |
1943 } | 1961 } |
1944 } | 1962 } |
1945 | 1963 |
1946 } // namespace compiler | 1964 } // namespace compiler |
1947 } // namespace internal | 1965 } // namespace internal |
1948 } // namespace v8 | 1966 } // namespace v8 |
OLD | NEW |