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

Side by Side Diff: test/cctest/compiler/test-control-reducer.cc

Issue 661923002: Implement graph trimming in ControlReducer. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use Deque. Created 6 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « test/cctest/cctest.status ('k') | test/cctest/compiler/test-run-jsbranches.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/control-reducer.h"
10 #include "src/compiler/graph-inl.h"
11 #include "src/compiler/js-graph.h"
12
13 using namespace v8::internal;
14 using namespace v8::internal::compiler;
15
16 class CTrimTester : HandleAndZoneScope {
17 public:
18 CTrimTester()
19 : isolate(main_isolate()),
20 common(main_zone()),
21 graph(main_zone()),
22 jsgraph(&graph, &common, NULL, NULL),
23 start(graph.NewNode(common.Start(1))),
24 p0(graph.NewNode(common.Parameter(0), start)),
25 one(jsgraph.OneConstant()),
26 half(jsgraph.Constant(0.5)) {
27 graph.SetEnd(start);
28 graph.SetStart(start);
29 }
30
31 Isolate* isolate;
32 CommonOperatorBuilder common;
33 Graph graph;
34 JSGraph jsgraph;
35 Node* start;
36 Node* p0;
37 Node* one;
38 Node* half;
39
40 void Trim() { ControlReducer::TrimGraph(&jsgraph); }
41 };
42
43
44 bool IsUsedBy(Node* a, Node* b) {
45 for (UseIter i = a->uses().begin(); i != a->uses().end(); ++i) {
46 if (b == *i) return true;
47 }
48 return false;
49 }
50
51
52 TEST(Trim1_live) {
53 CTrimTester T;
54 CHECK(IsUsedBy(T.start, T.p0));
55 T.graph.SetEnd(T.p0);
56 T.Trim();
57 CHECK(IsUsedBy(T.start, T.p0));
58 CHECK_EQ(T.start, T.p0->InputAt(0));
59 }
60
61
62 TEST(Trim1_dead) {
63 CTrimTester T;
64 CHECK(IsUsedBy(T.start, T.p0));
65 T.Trim();
66 CHECK(!IsUsedBy(T.start, T.p0));
67 CHECK_EQ(NULL, T.p0->InputAt(0));
68 }
69
70
71 TEST(Trim2_live) {
72 CTrimTester T;
73 Node* phi =
74 T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
75 CHECK(IsUsedBy(T.one, phi));
76 CHECK(IsUsedBy(T.half, phi));
77 CHECK(IsUsedBy(T.start, phi));
78 T.graph.SetEnd(phi);
79 T.Trim();
80 CHECK(IsUsedBy(T.one, phi));
81 CHECK(IsUsedBy(T.half, phi));
82 CHECK(IsUsedBy(T.start, phi));
83 CHECK_EQ(T.one, phi->InputAt(0));
84 CHECK_EQ(T.half, phi->InputAt(1));
85 CHECK_EQ(T.start, phi->InputAt(2));
86 }
87
88
89 TEST(Trim2_dead) {
90 CTrimTester T;
91 Node* phi =
92 T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
93 CHECK(IsUsedBy(T.one, phi));
94 CHECK(IsUsedBy(T.half, phi));
95 CHECK(IsUsedBy(T.start, phi));
96 T.Trim();
97 CHECK(!IsUsedBy(T.one, phi));
98 CHECK(!IsUsedBy(T.half, phi));
99 CHECK(!IsUsedBy(T.start, phi));
100 CHECK_EQ(NULL, phi->InputAt(0));
101 CHECK_EQ(NULL, phi->InputAt(1));
102 CHECK_EQ(NULL, phi->InputAt(2));
103 }
104
105
106 TEST(Trim_chain1) {
107 CTrimTester T;
108 const int kDepth = 15;
109 Node* live[kDepth];
110 Node* dead[kDepth];
111 Node* end = T.start;
112 for (int i = 0; i < kDepth; i++) {
113 live[i] = end = T.graph.NewNode(T.common.Merge(1), end);
114 dead[i] = T.graph.NewNode(T.common.Merge(1), end);
115 }
116 // end -> live[last] -> live[last-1] -> ... -> start
117 // dead[last] ^ dead[last-1] ^ ... ^
118 T.graph.SetEnd(end);
119 T.Trim();
120 for (int i = 0; i < kDepth; i++) {
121 CHECK(!IsUsedBy(live[i], dead[i]));
122 CHECK_EQ(NULL, dead[i]->InputAt(0));
123 CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
124 }
125 }
126
127
128 TEST(Trim_chain2) {
129 CTrimTester T;
130 const int kDepth = 15;
131 Node* live[kDepth];
132 Node* dead[kDepth];
133 Node* l = T.start;
134 Node* d = T.start;
135 for (int i = 0; i < kDepth; i++) {
136 live[i] = l = T.graph.NewNode(T.common.Merge(1), l);
137 dead[i] = d = T.graph.NewNode(T.common.Merge(1), d);
138 }
139 // end -> live[last] -> live[last-1] -> ... -> start
140 // dead[last] -> dead[last-1] -> ... -> start
141 T.graph.SetEnd(l);
142 T.Trim();
143 CHECK(!IsUsedBy(T.start, dead[0]));
144 for (int i = 0; i < kDepth; i++) {
145 CHECK_EQ(i == 0 ? NULL : dead[i - 1], dead[i]->InputAt(0));
146 CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
147 }
148 }
149
150
151 TEST(Trim_cycle1) {
152 CTrimTester T;
153 Node* loop = T.graph.NewNode(T.common.Loop(1), T.start, T.start);
154 loop->ReplaceInput(1, loop);
155 Node* end = T.graph.NewNode(T.common.End(), loop);
156 T.graph.SetEnd(end);
157
158 CHECK(IsUsedBy(T.start, loop));
159 CHECK(IsUsedBy(loop, end));
160 CHECK(IsUsedBy(loop, loop));
161
162 T.Trim();
163
164 // nothing should have happened to the loop itself.
165 CHECK(IsUsedBy(T.start, loop));
166 CHECK(IsUsedBy(loop, end));
167 CHECK(IsUsedBy(loop, loop));
168 CHECK_EQ(T.start, loop->InputAt(0));
169 CHECK_EQ(loop, loop->InputAt(1));
170 CHECK_EQ(loop, end->InputAt(0));
171 }
172
173
174 TEST(Trim_cycle2) {
175 CTrimTester T;
176 Node* loop = T.graph.NewNode(T.common.Loop(2), T.start, T.start);
177 loop->ReplaceInput(1, loop);
178 Node* end = T.graph.NewNode(T.common.End(), loop);
179 Node* phi =
180 T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, loop);
181 T.graph.SetEnd(end);
182
183 CHECK(IsUsedBy(T.start, loop));
184 CHECK(IsUsedBy(loop, end));
185 CHECK(IsUsedBy(loop, loop));
186 CHECK(IsUsedBy(loop, phi));
187 CHECK(IsUsedBy(T.one, phi));
188 CHECK(IsUsedBy(T.half, phi));
189
190 T.Trim();
191
192 // nothing should have happened to the loop itself.
193 CHECK(IsUsedBy(T.start, loop));
194 CHECK(IsUsedBy(loop, end));
195 CHECK(IsUsedBy(loop, loop));
196 CHECK_EQ(T.start, loop->InputAt(0));
197 CHECK_EQ(loop, loop->InputAt(1));
198 CHECK_EQ(loop, end->InputAt(0));
199
200 // phi should have been trimmed away.
201 CHECK(!IsUsedBy(loop, phi));
202 CHECK(!IsUsedBy(T.one, phi));
203 CHECK(!IsUsedBy(T.half, phi));
204 CHECK_EQ(NULL, phi->InputAt(0));
205 CHECK_EQ(NULL, phi->InputAt(1));
206 CHECK_EQ(NULL, phi->InputAt(2));
207 }
208
209
210 void CheckTrimConstant(CTrimTester* T, Node* k) {
211 Node* phi = T->graph.NewNode(T->common.Phi(kMachInt32, 1), k, T->start);
212 CHECK(IsUsedBy(k, phi));
213 T->Trim();
214 CHECK(!IsUsedBy(k, phi));
215 CHECK_EQ(NULL, phi->InputAt(0));
216 CHECK_EQ(NULL, phi->InputAt(1));
217 }
218
219
220 TEST(Trim_constants) {
221 CTrimTester T;
222 int32_t int32_constants[] = {
223 0, -1, -2, 2, 2, 3, 3, 4, 4, 5, 5, 4, 5, 6, 6, 7, 8, 7, 8, 9,
224 0, -11, -12, 12, 12, 13, 13, 14, 14, 15, 15, 14, 15, 6, 6, 7, 8, 7, 8, 9};
225
226 for (size_t i = 0; i < arraysize(int32_constants); i++) {
227 CheckTrimConstant(&T, T.jsgraph.Int32Constant(int32_constants[i]));
228 CheckTrimConstant(&T, T.jsgraph.Float64Constant(int32_constants[i]));
229 CheckTrimConstant(&T, T.jsgraph.Constant(int32_constants[i]));
230 }
231
232 Node* other_constants[] = {
233 T.jsgraph.UndefinedConstant(), T.jsgraph.TheHoleConstant(),
234 T.jsgraph.TrueConstant(), T.jsgraph.FalseConstant(),
235 T.jsgraph.NullConstant(), T.jsgraph.ZeroConstant(),
236 T.jsgraph.OneConstant(), T.jsgraph.NaNConstant(),
237 T.jsgraph.Constant(21), T.jsgraph.Constant(22.2)};
238
239 for (size_t i = 0; i < arraysize(other_constants); i++) {
240 CheckTrimConstant(&T, other_constants[i]);
241 }
242 }
OLDNEW
« no previous file with comments | « test/cctest/cctest.status ('k') | test/cctest/compiler/test-run-jsbranches.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698