OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/graph.h" | 6 #include "src/compiler/graph.h" |
7 #include "src/compiler/graph-visualizer.h" | 7 #include "src/compiler/graph-visualizer.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/loop-peeling.h" | 9 #include "src/compiler/loop-peeling.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 OFStream os(stdout); | 64 OFStream os(stdout); |
65 os << AsRPO(*graph()); | 65 os << AsRPO(*graph()); |
66 } | 66 } |
67 Zone zone; | 67 Zone zone; |
68 return LoopFinder::BuildLoopTree(graph(), &zone); | 68 return LoopFinder::BuildLoopTree(graph(), &zone); |
69 } | 69 } |
70 | 70 |
71 | 71 |
72 PeeledIteration* PeelOne() { | 72 PeeledIteration* PeelOne() { |
73 LoopTree* loop_tree = GetLoopTree(); | 73 LoopTree* loop_tree = GetLoopTree(); |
74 return Peel(loop_tree, loop_tree->outer_loops()[0]); | 74 LoopTree::Loop* loop = loop_tree->outer_loops()[0]; |
| 75 EXPECT_TRUE(LoopPeeler::CanPeel(loop_tree, loop)); |
| 76 return Peel(loop_tree, loop); |
75 } | 77 } |
76 | 78 |
77 PeeledIteration* Peel(LoopTree* loop_tree, LoopTree::Loop* loop) { | 79 PeeledIteration* Peel(LoopTree* loop_tree, LoopTree::Loop* loop) { |
| 80 EXPECT_TRUE(LoopPeeler::CanPeel(loop_tree, loop)); |
78 PeeledIteration* peeled = | 81 PeeledIteration* peeled = |
79 LoopPeeler::Peel(graph(), common(), loop_tree, loop, zone()); | 82 LoopPeeler::Peel(graph(), common(), loop_tree, loop, zone()); |
80 if (FLAG_trace_turbo_graph) { | 83 if (FLAG_trace_turbo_graph) { |
81 OFStream os(stdout); | 84 OFStream os(stdout); |
82 os << AsRPO(*graph()); | 85 os << AsRPO(*graph()); |
83 } | 86 } |
84 return peeled; | 87 return peeled; |
85 } | 88 } |
86 | 89 |
87 Node* InsertReturn(Node* val, Node* effect, Node* control) { | 90 Node* InsertReturn(Node* val, Node* effect, Node* control) { |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 IsInt32Add(phi, IsInt32Constant(2)), loop)); | 442 IsInt32Add(phi, IsInt32Constant(2)), loop)); |
440 | 443 |
441 Capture<Node*> merge; | 444 Capture<Node*> merge; |
442 EXPECT_THAT( | 445 EXPECT_THAT( |
443 r, IsReturn(IsPhi(kMachAnyTagged, phi, IsInt32Constant(0), | 446 r, IsReturn(IsPhi(kMachAnyTagged, phi, IsInt32Constant(0), |
444 AllOf(CaptureEq(&merge), IsMerge(b1.if_false, b1f))), | 447 AllOf(CaptureEq(&merge), IsMerge(b1.if_false, b1f))), |
445 start(), CaptureEq(&merge))); | 448 start(), CaptureEq(&merge))); |
446 } | 449 } |
447 | 450 |
448 | 451 |
| 452 TEST_F(LoopPeelingTest, TwoExitLoop_nope) { |
| 453 Node* p0 = Parameter(0); |
| 454 Node* loop = graph()->NewNode(common()->Loop(2), start(), start()); |
| 455 Branch b1 = NewBranch(p0, loop); |
| 456 Branch b2 = NewBranch(p0, b1.if_true); |
| 457 |
| 458 loop->ReplaceInput(1, b2.if_true); |
| 459 Node* merge = graph()->NewNode(common()->Merge(2), b1.if_false, b2.if_false); |
| 460 InsertReturn(p0, start(), merge); |
| 461 |
| 462 { |
| 463 LoopTree* loop_tree = GetLoopTree(); |
| 464 LoopTree::Loop* loop = loop_tree->outer_loops()[0]; |
| 465 EXPECT_FALSE(LoopPeeler::CanPeel(loop_tree, loop)); |
| 466 } |
| 467 } |
| 468 |
| 469 |
| 470 const Operator kMockCall(IrOpcode::kCall, Operator::kNoProperties, "MockCall", |
| 471 0, 0, 1, 1, 0, 2); |
| 472 |
| 473 |
| 474 TEST_F(LoopPeelingTest, TwoExitLoopWithCall_nope) { |
| 475 Node* p0 = Parameter(0); |
| 476 Node* loop = graph()->NewNode(common()->Loop(2), start(), start()); |
| 477 Branch b1 = NewBranch(p0, loop); |
| 478 |
| 479 Node* call = graph()->NewNode(&kMockCall, b1.if_true); |
| 480 Node* if_success = graph()->NewNode(common()->IfSuccess(), call); |
| 481 Node* if_exception = graph()->NewNode(common()->IfException(), call); |
| 482 |
| 483 loop->ReplaceInput(1, if_success); |
| 484 Node* merge = graph()->NewNode(common()->Merge(2), b1.if_false, if_exception); |
| 485 InsertReturn(p0, start(), merge); |
| 486 |
| 487 { |
| 488 LoopTree* loop_tree = GetLoopTree(); |
| 489 LoopTree::Loop* loop = loop_tree->outer_loops()[0]; |
| 490 EXPECT_FALSE(LoopPeeler::CanPeel(loop_tree, loop)); |
| 491 } |
| 492 } |
| 493 |
| 494 |
449 } // namespace compiler | 495 } // namespace compiler |
450 } // namespace internal | 496 } // namespace internal |
451 } // namespace v8 | 497 } // namespace v8 |
OLD | NEW |