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

Side by Side Diff: test/unittests/compiler/linkage-tail-call-unittest.cc

Issue 1245523002: [turbofan]: Fix tail calls edge cases and add tests (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@1220823004
Patch Set: Cleanup tests Created 5 years, 5 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
« no previous file with comments | « src/compiler/linkage.cc ('k') | test/unittests/unittests.gyp » ('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/compiler/common-operator.h"
6 #include "src/compiler/graph.h"
7 #include "src/compiler/linkage.h"
8 #include "src/compiler/node.h"
9 #include "test/unittests/test-utils.h"
10
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14
15 class LinkageTailCall : public TestWithZone {
16 protected:
17 CallDescriptor* NewStandardCallDescriptor(
18 LocationSignature::Builder* locations, MachineSignature::Builder* types) {
19 return new (zone())
20 CallDescriptor(CallDescriptor::kCallCodeObject, kMachAnyTagged,
21 LinkageLocation::AnyRegister(),
22 types->Build(), // machine_sig
23 locations->Build(), // location_sig
24 0, // js_parameter_count
25 Operator::kNoProperties, // properties
26 0, // callee-saved
27 0, // callee-saved fp
28 CallDescriptor::kNoFlags, // flags,
29 "");
30 }
31
32 LinkageLocation StackLocation(int loc) { return LinkageLocation(-loc); }
33
34 LinkageLocation RegisterLocation(int loc) { return LinkageLocation(loc); }
35 };
36
37
38 TEST_F(LinkageTailCall, EmptyToEmpty) {
39 LocationSignature::Builder locations(zone(), 0, 0);
40 MachineSignature::Builder types(zone(), 0, 0);
41
42 CallDescriptor* desc = NewStandardCallDescriptor(&locations, &types);
43
44 CommonOperatorBuilder common(zone());
45 const Operator* op = common.Call(desc);
46 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
47 EXPECT_TRUE(desc->CanTailCall(node));
48 }
49
50
51 TEST_F(LinkageTailCall, SameReturn) {
52 // Caller
53 LocationSignature::Builder locations1(zone(), 1, 0);
titzer 2015/07/21 11:48:52 You don't have to use the Signature::Builder every
54 MachineSignature::Builder types1(zone(), 1, 0);
55 locations1.AddReturn(RegisterLocation(0));
56 types1.AddReturn(kMachAnyTagged);
57
58 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
59
60 // Callee
61 LocationSignature::Builder locations2(zone(), 1, 0);
62 MachineSignature::Builder types2(zone(), 1, 0);
63 locations2.AddReturn(RegisterLocation(0));
64 types2.AddReturn(kMachAnyTagged);
65 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
66
67 CommonOperatorBuilder common(zone());
68 const Operator* op = common.Call(desc2);
69 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
70 EXPECT_TRUE(desc1->CanTailCall(node));
71 }
72
73
74 TEST_F(LinkageTailCall, DifferingReturn) {
75 // Caller
76 LocationSignature::Builder locations1(zone(), 1, 0);
77 MachineSignature::Builder types1(zone(), 1, 0);
78 locations1.AddReturn(RegisterLocation(0));
79 types1.AddReturn(kMachAnyTagged);
80 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
81
82 // Callee
83 LocationSignature::Builder locations2(zone(), 1, 0);
84 MachineSignature::Builder types2(zone(), 1, 0);
85 locations2.AddReturn(StackLocation(1));
86 types2.AddReturn(kMachAnyTagged);
87 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
88
89 CommonOperatorBuilder common(zone());
90 const Operator* op = common.Call(desc2);
91 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
92 EXPECT_FALSE(desc1->CanTailCall(node));
93 }
94
95
96 TEST_F(LinkageTailCall, MoreRegisterParametersCallee) {
97 // Caller
98 LocationSignature::Builder locations1(zone(), 1, 0);
99 MachineSignature::Builder types1(zone(), 1, 0);
100 locations1.AddReturn(RegisterLocation(0));
101 types1.AddReturn(kMachAnyTagged);
102 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
103
104 // Callee
105 LocationSignature::Builder locations2(zone(), 1, 1);
106 MachineSignature::Builder types2(zone(), 1, 1);
107 locations2.AddReturn(RegisterLocation(0));
108 types2.AddReturn(kMachAnyTagged);
109 locations2.AddParam(RegisterLocation(1));
110 types2.AddParam(kMachAnyTagged);
111 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
112
113 CommonOperatorBuilder common(zone());
114 const Operator* op = common.Call(desc2);
115 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
116 EXPECT_TRUE(desc1->CanTailCall(node));
117 }
118
119
120 TEST_F(LinkageTailCall, MoreRegisterParametersCalleer) {
121 // Caller
122 LocationSignature::Builder locations1(zone(), 1, 1);
123 MachineSignature::Builder types1(zone(), 1, 1);
124 locations1.AddReturn(RegisterLocation(0));
125 types1.AddReturn(kMachAnyTagged);
126 locations1.AddParam(RegisterLocation(1));
127 types1.AddParam(kMachAnyTagged);
128 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
129
130 // Callee
131 LocationSignature::Builder locations2(zone(), 1, 0);
132 MachineSignature::Builder types2(zone(), 1, 0);
133 locations2.AddReturn(RegisterLocation(0));
134 types2.AddReturn(kMachAnyTagged);
135 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
136
137 CommonOperatorBuilder common(zone());
138 const Operator* op = common.Call(desc2);
139 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
140 EXPECT_TRUE(desc1->CanTailCall(node));
141 }
142
143
144 TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCallee) {
145 // Caller
146 LocationSignature::Builder locations1(zone(), 1, 0);
147 MachineSignature::Builder types1(zone(), 1, 0);
148 locations1.AddReturn(RegisterLocation(0));
149 types1.AddReturn(kMachAnyTagged);
150 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
151
152 // Callee
153 LocationSignature::Builder locations2(zone(), 1, 3);
154 MachineSignature::Builder types2(zone(), 1, 3);
155 locations2.AddReturn(RegisterLocation(0));
156 types2.AddReturn(kMachAnyTagged);
157 locations2.AddParam(StackLocation(1));
158 types2.AddParam(kMachAnyTagged);
159 locations2.AddParam(RegisterLocation(0));
160 types2.AddParam(kMachAnyTagged);
161 locations2.AddParam(RegisterLocation(1));
162 types2.AddParam(kMachAnyTagged);
163 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
164
165 CommonOperatorBuilder common(zone());
166 const Operator* op = common.Call(desc2);
167 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
168 EXPECT_FALSE(desc1->CanTailCall(node));
169 }
170
171
172 TEST_F(LinkageTailCall, MoreRegisterAndStackParametersCalleer) {
173 // Caller
174 LocationSignature::Builder locations1(zone(), 1, 3);
175 MachineSignature::Builder types1(zone(), 1, 3);
176 locations1.AddReturn(RegisterLocation(0));
177 types1.AddReturn(kMachAnyTagged);
178 locations1.AddParam(StackLocation(1));
179 types1.AddParam(kMachAnyTagged);
180 locations1.AddParam(RegisterLocation(0));
181 types1.AddParam(kMachAnyTagged);
182 locations1.AddParam(RegisterLocation(1));
183 types1.AddParam(kMachAnyTagged);
184 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
185
186 // Callee
187 LocationSignature::Builder locations2(zone(), 1, 0);
188 MachineSignature::Builder types2(zone(), 1, 0);
189 locations2.AddReturn(RegisterLocation(0));
190 types2.AddReturn(kMachAnyTagged);
191 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
192
193 CommonOperatorBuilder common(zone());
194 const Operator* op = common.Call(desc2);
195 Node* const node = Node::New(zone(), 1, op, 0, nullptr, false);
196 EXPECT_FALSE(desc1->CanTailCall(node));
197 }
198
199
200 TEST_F(LinkageTailCall, MatchingStackParameters) {
201 // Caller
202 LocationSignature::Builder locations1(zone(), 1, 3);
203 MachineSignature::Builder types1(zone(), 1, 3);
204 locations1.AddReturn(RegisterLocation(0));
205 types1.AddReturn(kMachAnyTagged);
206 locations1.AddParam(StackLocation(3));
207 types1.AddParam(kMachAnyTagged);
208 locations1.AddParam(StackLocation(2));
209 types1.AddParam(kMachAnyTagged);
210 locations1.AddParam(StackLocation(1));
211 types1.AddParam(kMachAnyTagged);
212 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
213
214 // Callee
215 LocationSignature::Builder locations2(zone(), 1, 3);
216 MachineSignature::Builder types2(zone(), 1, 3);
217 locations2.AddReturn(RegisterLocation(0));
218 types2.AddReturn(kMachAnyTagged);
219 locations2.AddParam(StackLocation(3));
220 types2.AddParam(kMachAnyTagged);
221 locations2.AddParam(StackLocation(2));
222 types2.AddParam(kMachAnyTagged);
223 locations2.AddParam(StackLocation(1));
224 types2.AddParam(kMachAnyTagged);
225 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
226
227 CommonOperatorBuilder common(zone());
228 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
229 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
230 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
231 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
232 Node* parameters[] = {p0, p1, p2, p3};
233 const Operator* op = common.Call(desc2);
234 Node* const node =
235 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
236 EXPECT_TRUE(desc1->CanTailCall(node));
237 }
238
239
240 TEST_F(LinkageTailCall, NonMatchingStackParameters) {
241 // Caller
242 LocationSignature::Builder locations1(zone(), 1, 3);
243 MachineSignature::Builder types1(zone(), 1, 3);
244 locations1.AddReturn(RegisterLocation(0));
245 types1.AddReturn(kMachAnyTagged);
246 locations1.AddParam(StackLocation(3));
247 types1.AddParam(kMachAnyTagged);
248 locations1.AddParam(StackLocation(2));
249 types1.AddParam(kMachAnyTagged);
250 locations1.AddParam(StackLocation(1));
251 types1.AddParam(kMachAnyTagged);
252 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
253
254 // Callee
255 LocationSignature::Builder locations2(zone(), 1, 3);
256 MachineSignature::Builder types2(zone(), 1, 3);
257 locations2.AddReturn(RegisterLocation(0));
258 types2.AddReturn(kMachAnyTagged);
259 locations2.AddParam(StackLocation(3));
260 types2.AddParam(kMachAnyTagged);
261 locations2.AddParam(StackLocation(2));
262 types2.AddParam(kMachAnyTagged);
263 locations2.AddParam(StackLocation(1));
264 types2.AddParam(kMachAnyTagged);
265 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
266
267 CommonOperatorBuilder common(zone());
268 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
269 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
270 Node* p2 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
271 Node* p3 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
272 Node* parameters[] = {p0, p1, p2, p3};
273 const Operator* op = common.Call(desc2);
274 Node* const node =
275 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
276 EXPECT_FALSE(desc1->CanTailCall(node));
277 }
278
279
280 TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegisters) {
281 // Caller
282 LocationSignature::Builder locations1(zone(), 1, 5);
283 MachineSignature::Builder types1(zone(), 1, 5);
284 locations1.AddReturn(RegisterLocation(0));
285 types1.AddReturn(kMachAnyTagged);
286 locations1.AddParam(StackLocation(3));
287 types1.AddParam(kMachAnyTagged);
288 locations1.AddParam(StackLocation(2));
289 types1.AddParam(kMachAnyTagged);
290 locations1.AddParam(StackLocation(1));
291 types1.AddParam(kMachAnyTagged);
292 locations1.AddParam(RegisterLocation(1));
293 types1.AddParam(kMachAnyTagged);
294 locations1.AddParam(RegisterLocation(2));
295 types1.AddParam(kMachAnyTagged);
296 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
297
298 // Callee
299 LocationSignature::Builder locations2(zone(), 1, 3);
300 MachineSignature::Builder types2(zone(), 1, 3);
301 locations2.AddReturn(RegisterLocation(0));
302 types2.AddReturn(kMachAnyTagged);
303 locations2.AddParam(StackLocation(3));
304 types2.AddParam(kMachAnyTagged);
305 locations2.AddParam(StackLocation(2));
306 types2.AddParam(kMachAnyTagged);
307 locations2.AddParam(StackLocation(1));
308 types2.AddParam(kMachAnyTagged);
309 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
310
311 CommonOperatorBuilder common(zone());
312 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
313 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
314 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
315 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
316 Node* parameters[] = {p0, p1, p2, p3};
317 const Operator* op = common.Call(desc2);
318 Node* const node =
319 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
320 EXPECT_TRUE(desc1->CanTailCall(node));
321 }
322
323
324 TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegisters) {
325 // Caller
326 LocationSignature::Builder locations1(zone(), 1, 3);
327 MachineSignature::Builder types1(zone(), 1, 3);
328 locations1.AddReturn(RegisterLocation(0));
329 types1.AddReturn(kMachAnyTagged);
330 locations1.AddParam(StackLocation(3));
331 types1.AddParam(kMachAnyTagged);
332 locations1.AddParam(StackLocation(2));
333 types1.AddParam(kMachAnyTagged);
334 locations1.AddParam(StackLocation(1));
335 types1.AddParam(kMachAnyTagged);
336 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
337
338 // Callee
339 LocationSignature::Builder locations2(zone(), 1, 5);
340 MachineSignature::Builder types2(zone(), 1, 5);
341 locations2.AddReturn(RegisterLocation(0));
342 types2.AddReturn(kMachAnyTagged);
343 locations2.AddParam(StackLocation(3));
344 types2.AddParam(kMachAnyTagged);
345 locations2.AddParam(StackLocation(2));
346 types2.AddParam(kMachAnyTagged);
347 locations2.AddParam(StackLocation(1));
348 types2.AddParam(kMachAnyTagged);
349 locations2.AddParam(RegisterLocation(1));
350 types2.AddParam(kMachAnyTagged);
351 locations2.AddParam(RegisterLocation(2));
352 types2.AddParam(kMachAnyTagged);
353 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
354
355 CommonOperatorBuilder common(zone());
356 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
357 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
358 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
359 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
360 Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
361 Node* parameters[] = {p0, p1, p2, p3, p4};
362 const Operator* op = common.Call(desc2);
363 Node* const node =
364 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
365 EXPECT_TRUE(desc1->CanTailCall(node));
366 }
367
368
369 TEST_F(LinkageTailCall, MatchingStackParametersExtraCallerRegistersAndStack) {
370 // Caller
371 LocationSignature::Builder locations1(zone(), 1, 6);
372 MachineSignature::Builder types1(zone(), 1, 6);
373 locations1.AddReturn(RegisterLocation(0));
374 types1.AddReturn(kMachAnyTagged);
375 locations1.AddParam(StackLocation(3));
376 types1.AddParam(kMachAnyTagged);
377 locations1.AddParam(StackLocation(2));
378 types1.AddParam(kMachAnyTagged);
379 locations1.AddParam(StackLocation(1));
380 types1.AddParam(kMachAnyTagged);
381 locations1.AddParam(RegisterLocation(1));
382 types1.AddParam(kMachAnyTagged);
383 locations1.AddParam(RegisterLocation(2));
384 types1.AddParam(kMachAnyTagged);
385 locations1.AddParam(StackLocation(4));
386 types1.AddParam(kMachAnyTagged);
387 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
388
389 // Callee
390 LocationSignature::Builder locations2(zone(), 1, 3);
391 MachineSignature::Builder types2(zone(), 1, 3);
392 locations2.AddReturn(RegisterLocation(0));
393 types2.AddReturn(kMachAnyTagged);
394 locations2.AddParam(StackLocation(3));
395 types2.AddParam(kMachAnyTagged);
396 locations2.AddParam(StackLocation(2));
397 types2.AddParam(kMachAnyTagged);
398 locations2.AddParam(StackLocation(1));
399 types2.AddParam(kMachAnyTagged);
400 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
401
402 CommonOperatorBuilder common(zone());
403 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
404 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
405 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
406 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
407 Node* parameters[] = {p0, p1, p2, p3};
408 const Operator* op = common.Call(desc2);
409 Node* const node =
410 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
411 EXPECT_FALSE(desc1->CanTailCall(node));
412 }
413
414
415 TEST_F(LinkageTailCall, MatchingStackParametersExtraCalleeRegistersAndStack) {
416 // Caller
417 LocationSignature::Builder locations1(zone(), 1, 3);
418 MachineSignature::Builder types1(zone(), 1, 3);
419 locations1.AddReturn(RegisterLocation(0));
420 types1.AddReturn(kMachAnyTagged);
421 locations1.AddParam(StackLocation(3));
422 types1.AddParam(kMachAnyTagged);
423 locations1.AddParam(StackLocation(2));
424 types1.AddParam(kMachAnyTagged);
425 locations1.AddParam(StackLocation(1));
426 types1.AddParam(kMachAnyTagged);
427 CallDescriptor* desc1 = NewStandardCallDescriptor(&locations1, &types1);
428
429 // Callee
430 LocationSignature::Builder locations2(zone(), 1, 6);
431 MachineSignature::Builder types2(zone(), 1, 6);
432 locations2.AddReturn(RegisterLocation(0));
433 types2.AddReturn(kMachAnyTagged);
434 locations2.AddParam(StackLocation(3));
435 types2.AddParam(kMachAnyTagged);
436 locations2.AddParam(StackLocation(2));
437 types2.AddParam(kMachAnyTagged);
438 locations2.AddParam(StackLocation(1));
439 types2.AddParam(kMachAnyTagged);
440 locations2.AddParam(RegisterLocation(1));
441 types2.AddParam(kMachAnyTagged);
442 locations2.AddParam(RegisterLocation(2));
443 types2.AddParam(kMachAnyTagged);
444 locations2.AddParam(StackLocation(4));
445 types2.AddParam(kMachAnyTagged);
446 CallDescriptor* desc2 = NewStandardCallDescriptor(&locations2, &types2);
447
448 CommonOperatorBuilder common(zone());
449 Node* p0 = Node::New(zone(), 0, nullptr, 0, nullptr, false);
450 Node* p1 = Node::New(zone(), 0, common.Parameter(0), 0, nullptr, false);
451 Node* p2 = Node::New(zone(), 0, common.Parameter(1), 0, nullptr, false);
452 Node* p3 = Node::New(zone(), 0, common.Parameter(2), 0, nullptr, false);
453 Node* p4 = Node::New(zone(), 0, common.Parameter(3), 0, nullptr, false);
454 Node* parameters[] = {p0, p1, p2, p3, p4};
455 const Operator* op = common.Call(desc2);
456 Node* const node =
457 Node::New(zone(), 1, op, arraysize(parameters), parameters, false);
458 EXPECT_FALSE(desc1->CanTailCall(node));
459 }
460
461 } // namespace compiler
462 } // namespace internal
463 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/linkage.cc ('k') | test/unittests/unittests.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698