OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/v8.h" | |
6 #include "test/cctest/cctest.h" | |
7 | |
8 #include "src/compiler/common-operator.h" | |
9 #include "src/compiler/graph-inl.h" | |
10 #include "src/compiler/phi-reducer.h" | |
11 | |
12 using namespace v8::internal; | |
13 using namespace v8::internal::compiler; | |
14 | |
15 class PhiReducerTester : HandleAndZoneScope { | |
16 public: | |
17 explicit PhiReducerTester(int num_parameters = 0) | |
18 : isolate(main_isolate()), | |
19 common(main_zone()), | |
20 graph(main_zone()), | |
21 self(graph.NewNode(common.Start(num_parameters))), | |
22 dead(graph.NewNode(common.Dead())) { | |
23 graph.SetStart(self); | |
24 } | |
25 | |
26 Isolate* isolate; | |
27 CommonOperatorBuilder common; | |
28 Graph graph; | |
29 Node* self; | |
30 Node* dead; | |
31 | |
32 void CheckReduce(Node* expect, Node* phi) { | |
33 PhiReducer reducer; | |
34 Reduction reduction = reducer.Reduce(phi); | |
35 if (expect == phi) { | |
36 CHECK(!reduction.Changed()); | |
37 } else { | |
38 CHECK(reduction.Changed()); | |
39 CHECK_EQ(expect, reduction.replacement()); | |
40 } | |
41 } | |
42 | |
43 Node* Int32Constant(int32_t val) { | |
44 return graph.NewNode(common.Int32Constant(val)); | |
45 } | |
46 | |
47 Node* Float64Constant(double val) { | |
48 return graph.NewNode(common.Float64Constant(val)); | |
49 } | |
50 | |
51 Node* Parameter(int32_t index = 0) { | |
52 return graph.NewNode(common.Parameter(index), graph.start()); | |
53 } | |
54 | |
55 Node* Phi(Node* a) { | |
56 return SetSelfReferences(graph.NewNode(common.Phi(kMachAnyTagged, 1), a)); | |
57 } | |
58 | |
59 Node* Phi(Node* a, Node* b) { | |
60 return SetSelfReferences( | |
61 graph.NewNode(common.Phi(kMachAnyTagged, 2), a, b)); | |
62 } | |
63 | |
64 Node* Phi(Node* a, Node* b, Node* c) { | |
65 return SetSelfReferences( | |
66 graph.NewNode(common.Phi(kMachAnyTagged, 3), a, b, c)); | |
67 } | |
68 | |
69 Node* Phi(Node* a, Node* b, Node* c, Node* d) { | |
70 return SetSelfReferences( | |
71 graph.NewNode(common.Phi(kMachAnyTagged, 4), a, b, c, d)); | |
72 } | |
73 | |
74 Node* PhiWithControl(Node* a, Node* control) { | |
75 return SetSelfReferences( | |
76 graph.NewNode(common.Phi(kMachAnyTagged, 1), a, control)); | |
77 } | |
78 | |
79 Node* PhiWithControl(Node* a, Node* b, Node* control) { | |
80 return SetSelfReferences( | |
81 graph.NewNode(common.Phi(kMachAnyTagged, 2), a, b, control)); | |
82 } | |
83 | |
84 Node* SetSelfReferences(Node* node) { | |
85 Node::Inputs inputs = node->inputs(); | |
86 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | |
87 ++iter) { | |
88 Node* input = *iter; | |
89 if (input == self) node->ReplaceInput(iter.index(), node); | |
90 } | |
91 return node; | |
92 } | |
93 }; | |
94 | |
95 | |
96 TEST(PhiReduce1) { | |
97 PhiReducerTester R; | |
98 Node* zero = R.Int32Constant(0); | |
99 Node* one = R.Int32Constant(1); | |
100 Node* oneish = R.Float64Constant(1.1); | |
101 Node* param = R.Parameter(); | |
102 | |
103 Node* singles[] = {zero, one, oneish, param}; | |
104 for (size_t i = 0; i < arraysize(singles); i++) { | |
105 R.CheckReduce(singles[i], R.Phi(singles[i])); | |
106 } | |
107 } | |
108 | |
109 | |
110 TEST(PhiReduce2) { | |
111 PhiReducerTester R; | |
112 Node* zero = R.Int32Constant(0); | |
113 Node* one = R.Int32Constant(1); | |
114 Node* oneish = R.Float64Constant(1.1); | |
115 Node* param = R.Parameter(); | |
116 | |
117 Node* singles[] = {zero, one, oneish, param}; | |
118 for (size_t i = 0; i < arraysize(singles); i++) { | |
119 Node* a = singles[i]; | |
120 R.CheckReduce(a, R.Phi(a, a)); | |
121 } | |
122 | |
123 for (size_t i = 0; i < arraysize(singles); i++) { | |
124 Node* a = singles[i]; | |
125 R.CheckReduce(a, R.Phi(R.self, a)); | |
126 R.CheckReduce(a, R.Phi(a, R.self)); | |
127 } | |
128 | |
129 for (size_t i = 1; i < arraysize(singles); i++) { | |
130 Node* a = singles[i], *b = singles[0]; | |
131 Node* phi1 = R.Phi(b, a); | |
132 R.CheckReduce(phi1, phi1); | |
133 | |
134 Node* phi2 = R.Phi(a, b); | |
135 R.CheckReduce(phi2, phi2); | |
136 } | |
137 } | |
138 | |
139 | |
140 TEST(PhiReduce3) { | |
141 PhiReducerTester R; | |
142 Node* zero = R.Int32Constant(0); | |
143 Node* one = R.Int32Constant(1); | |
144 Node* oneish = R.Float64Constant(1.1); | |
145 Node* param = R.Parameter(); | |
146 | |
147 Node* singles[] = {zero, one, oneish, param}; | |
148 for (size_t i = 0; i < arraysize(singles); i++) { | |
149 Node* a = singles[i]; | |
150 R.CheckReduce(a, R.Phi(a, a, a)); | |
151 } | |
152 | |
153 for (size_t i = 0; i < arraysize(singles); i++) { | |
154 Node* a = singles[i]; | |
155 R.CheckReduce(a, R.Phi(R.self, a, a)); | |
156 R.CheckReduce(a, R.Phi(a, R.self, a)); | |
157 R.CheckReduce(a, R.Phi(a, a, R.self)); | |
158 } | |
159 | |
160 for (size_t i = 1; i < arraysize(singles); i++) { | |
161 Node* a = singles[i], *b = singles[0]; | |
162 Node* phi1 = R.Phi(b, a, a); | |
163 R.CheckReduce(phi1, phi1); | |
164 | |
165 Node* phi2 = R.Phi(a, b, a); | |
166 R.CheckReduce(phi2, phi2); | |
167 | |
168 Node* phi3 = R.Phi(a, a, b); | |
169 R.CheckReduce(phi3, phi3); | |
170 } | |
171 } | |
172 | |
173 | |
174 TEST(PhiReduce4) { | |
175 PhiReducerTester R; | |
176 Node* zero = R.Int32Constant(0); | |
177 Node* one = R.Int32Constant(1); | |
178 Node* oneish = R.Float64Constant(1.1); | |
179 Node* param = R.Parameter(); | |
180 | |
181 Node* singles[] = {zero, one, oneish, param}; | |
182 for (size_t i = 0; i < arraysize(singles); i++) { | |
183 Node* a = singles[i]; | |
184 R.CheckReduce(a, R.Phi(a, a, a, a)); | |
185 } | |
186 | |
187 for (size_t i = 0; i < arraysize(singles); i++) { | |
188 Node* a = singles[i]; | |
189 R.CheckReduce(a, R.Phi(R.self, a, a, a)); | |
190 R.CheckReduce(a, R.Phi(a, R.self, a, a)); | |
191 R.CheckReduce(a, R.Phi(a, a, R.self, a)); | |
192 R.CheckReduce(a, R.Phi(a, a, a, R.self)); | |
193 | |
194 R.CheckReduce(a, R.Phi(R.self, R.self, a, a)); | |
195 R.CheckReduce(a, R.Phi(a, R.self, R.self, a)); | |
196 R.CheckReduce(a, R.Phi(a, a, R.self, R.self)); | |
197 R.CheckReduce(a, R.Phi(R.self, a, a, R.self)); | |
198 } | |
199 | |
200 for (size_t i = 1; i < arraysize(singles); i++) { | |
201 Node* a = singles[i], *b = singles[0]; | |
202 Node* phi1 = R.Phi(b, a, a, a); | |
203 R.CheckReduce(phi1, phi1); | |
204 | |
205 Node* phi2 = R.Phi(a, b, a, a); | |
206 R.CheckReduce(phi2, phi2); | |
207 | |
208 Node* phi3 = R.Phi(a, a, b, a); | |
209 R.CheckReduce(phi3, phi3); | |
210 | |
211 Node* phi4 = R.Phi(a, a, a, b); | |
212 R.CheckReduce(phi4, phi4); | |
213 } | |
214 } | |
215 | |
216 | |
217 TEST(PhiReduceShouldIgnoreControlNodes) { | |
218 PhiReducerTester R; | |
219 Node* zero = R.Int32Constant(0); | |
220 Node* one = R.Int32Constant(1); | |
221 Node* oneish = R.Float64Constant(1.1); | |
222 Node* param = R.Parameter(); | |
223 | |
224 Node* singles[] = {zero, one, oneish, param}; | |
225 for (size_t i = 0; i < arraysize(singles); ++i) { | |
226 R.CheckReduce(singles[i], R.PhiWithControl(singles[i], R.dead)); | |
227 R.CheckReduce(singles[i], R.PhiWithControl(R.self, singles[i], R.dead)); | |
228 R.CheckReduce(singles[i], R.PhiWithControl(singles[i], R.self, R.dead)); | |
229 } | |
230 } | |
OLD | NEW |