OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 "src/compiler/load-elimination.h" |
5 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/load-elimination.h" | 7 #include "src/compiler/node.h" |
7 #include "src/compiler/simplified-operator.h" | 8 #include "src/compiler/simplified-operator.h" |
8 #include "test/unittests/compiler/graph-unittest.h" | 9 #include "test/unittests/compiler/graph-unittest.h" |
9 #include "test/unittests/compiler/node-test-utils.h" | 10 #include "test/unittests/compiler/node-test-utils.h" |
10 | 11 |
11 namespace v8 { | 12 namespace v8 { |
12 namespace internal { | 13 namespace internal { |
13 namespace compiler { | 14 namespace compiler { |
14 | 15 |
15 class LoadEliminationTest : public TypedGraphTest { | 16 class LoadEliminationTest : public TypedGraphTest { |
16 public: | 17 public: |
17 LoadEliminationTest() : TypedGraphTest(3), simplified_(zone()) {} | 18 LoadEliminationTest() : TypedGraphTest(3), simplified_(zone()) {} |
18 ~LoadEliminationTest() override {} | 19 ~LoadEliminationTest() override {} |
19 | 20 |
20 protected: | 21 protected: |
21 Reduction Reduce(Node* node) { | 22 void Run() { |
22 // TODO(titzer): mock the GraphReducer here for better unit testing. | 23 LoadElimination load_elimination(graph(), zone()); |
23 GraphReducer graph_reducer(zone(), graph()); | 24 load_elimination.Run(); |
24 LoadElimination reducer(&graph_reducer, graph(), simplified()); | |
25 return reducer.Reduce(node); | |
26 } | 25 } |
27 | 26 |
28 SimplifiedOperatorBuilder* simplified() { return &simplified_; } | 27 SimplifiedOperatorBuilder* simplified() { return &simplified_; } |
29 | 28 |
30 private: | 29 private: |
31 SimplifiedOperatorBuilder simplified_; | 30 SimplifiedOperatorBuilder simplified_; |
32 }; | 31 }; |
33 | 32 |
34 | 33 TEST_F(LoadEliminationTest, LoadFieldAndLoadField) { |
35 TEST_F(LoadEliminationTest, LoadFieldWithStoreField) { | 34 Node* object = Parameter(Type::Any(), 0); |
36 Node* object1 = Parameter(Type::Any(), 0); | |
37 Node* object2 = Parameter(Type::Any(), 1); | |
38 Node* value = Parameter(Type::Any(), 2); | |
39 Node* effect = graph()->start(); | 35 Node* effect = graph()->start(); |
40 Node* control = graph()->start(); | 36 Node* control = graph()->start(); |
| 37 FieldAccess access = {kTaggedBase, |
| 38 kPointerSize, |
| 39 MaybeHandle<Name>(), |
| 40 Type::Any(), |
| 41 MachineType::AnyTagged(), |
| 42 kNoWriteBarrier}; |
| 43 Node* load1 = effect = graph()->NewNode(simplified()->LoadField(access), |
| 44 object, effect, control); |
| 45 Node* load2 = effect = graph()->NewNode(simplified()->LoadField(access), |
| 46 object, effect, control); |
| 47 control = graph()->NewNode(common()->Return(), load2, effect, control); |
| 48 graph()->end()->ReplaceInput(0, control); |
41 | 49 |
42 FieldAccess access1 = AccessBuilder::ForContextSlot(42); | 50 Run(); |
43 Node* store1 = graph()->NewNode(simplified()->StoreField(access1), object1, | |
44 value, effect, control); | |
45 Reduction r1 = Reduce(graph()->NewNode(simplified()->LoadField(access1), | |
46 object1, store1, control)); | |
47 ASSERT_TRUE(r1.Changed()); | |
48 EXPECT_EQ(value, r1.replacement()); | |
49 | 51 |
50 FieldAccess access2 = AccessBuilder::ForMap(); | 52 EXPECT_THAT(graph()->end(), IsEnd(IsReturn(load1, load1, graph()->start()))); |
51 Node* store2 = graph()->NewNode(simplified()->StoreField(access2), object1, | 53 } |
52 object2, store1, control); | |
53 Reduction r2 = Reduce(graph()->NewNode(simplified()->LoadField(access2), | |
54 object1, store2, control)); | |
55 ASSERT_TRUE(r2.Changed()); | |
56 EXPECT_EQ(object2, r2.replacement()); | |
57 | 54 |
58 Node* store3 = graph()->NewNode( | 55 TEST_F(LoadEliminationTest, StoreFieldAndLoadField) { |
59 simplified()->StoreBuffer(BufferAccess(kExternalInt8Array)), object2, | 56 Node* object = Parameter(Type::Any(), 0); |
60 value, Int32Constant(10), object1, store2, control); | 57 Node* value = Parameter(Type::Any(), 1); |
| 58 Node* effect = graph()->start(); |
| 59 Node* control = graph()->start(); |
| 60 FieldAccess access = {kTaggedBase, |
| 61 kPointerSize, |
| 62 MaybeHandle<Name>(), |
| 63 Type::Any(), |
| 64 MachineType::AnyTagged(), |
| 65 kNoWriteBarrier}; |
| 66 Node* store = effect = graph()->NewNode(simplified()->StoreField(access), |
| 67 object, value, effect, control); |
| 68 Node* load = effect = graph()->NewNode(simplified()->LoadField(access), |
| 69 object, effect, control); |
| 70 control = graph()->NewNode(common()->Return(), load, effect, control); |
| 71 graph()->end()->ReplaceInput(0, control); |
61 | 72 |
62 Reduction r3 = Reduce(graph()->NewNode(simplified()->LoadField(access1), | 73 Run(); |
63 object2, store3, control)); | |
64 ASSERT_FALSE(r3.Changed()); | |
65 | 74 |
66 Reduction r4 = Reduce(graph()->NewNode(simplified()->LoadField(access1), | 75 EXPECT_THAT(graph()->end(), IsEnd(IsReturn(value, store, graph()->start()))); |
67 object1, store3, control)); | |
68 ASSERT_TRUE(r4.Changed()); | |
69 EXPECT_EQ(value, r4.replacement()); | |
70 } | 76 } |
71 | 77 |
72 } // namespace compiler | 78 } // namespace compiler |
73 } // namespace internal | 79 } // namespace internal |
74 } // namespace v8 | 80 } // namespace v8 |
OLD | NEW |