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/codegen.h" | 5 #include "src/codegen.h" |
6 #include "src/compiler/all-nodes.h" | 6 #include "src/compiler/all-nodes.h" |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/diamond.h" | 8 #include "src/compiler/diamond.h" |
9 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 Node* inputs[6]; | 86 Node* inputs[6]; |
87 inputs[0] = incoming; | 87 inputs[0] = incoming; |
88 inputs[1] = osr_values[osr_value]; | 88 inputs[1] = osr_values[osr_value]; |
89 if (count > 2) inputs[2] = back1; | 89 if (count > 2) inputs[2] = back1; |
90 if (count > 3) inputs[3] = back2; | 90 if (count > 3) inputs[3] = back2; |
91 if (count > 4) inputs[4] = back3; | 91 if (count > 4) inputs[4] = back3; |
92 inputs[count] = loop; | 92 inputs[count] = loop; |
93 return graph.NewNode(common.Phi(kMachAnyTagged, count), count + 1, inputs); | 93 return graph.NewNode(common.Phi(kMachAnyTagged, count), count + 1, inputs); |
94 } | 94 } |
95 | 95 |
96 Node* NewLoop(bool is_osr, int num_backedges, Node* entry = NULL) { | 96 Node* NewLoop(bool is_osr, int num_backedges, Node* entry = nullptr) { |
97 CHECK_LT(num_backedges, 4); | 97 if (entry == nullptr) entry = osr_normal_entry; |
98 CHECK_GE(num_backedges, 0); | 98 Node* loop = graph.NewNode(common.Loop(1), entry); |
99 int count = 1 + num_backedges; | |
100 if (entry == NULL) entry = osr_normal_entry; | |
101 Node* inputs[5] = {entry, self, self, self, self}; | |
102 if (is_osr) { | 99 if (is_osr) { |
103 count = 2 + num_backedges; | 100 loop->AppendInput(graph.zone(), osr_loop_entry); |
104 inputs[1] = osr_loop_entry; | |
105 } | 101 } |
106 | 102 for (int i = 0; i < num_backedges; i++) { |
107 Node* loop = graph.NewNode(common.Loop(count), count, inputs); | 103 loop->AppendInput(graph.zone(), loop); |
108 for (int i = 0; i < loop->InputCount(); i++) { | |
109 if (loop->InputAt(i) == self) loop->ReplaceInput(i, loop); | |
110 } | 104 } |
111 | 105 NodeProperties::ChangeOp(loop, common.Loop(loop->InputCount())); |
112 return loop; | 106 return loop; |
113 } | 107 } |
114 | 108 |
115 Node* NewOsrLoop(int num_backedges, Node* entry = NULL) { | 109 Node* NewOsrLoop(int num_backedges, Node* entry = NULL) { |
116 return NewLoop(true, num_backedges, entry); | 110 return NewLoop(true, num_backedges, entry); |
117 } | 111 } |
118 | 112 |
119 void DeconstructOsr() { | 113 void DeconstructOsr() { |
120 OsrHelper helper(0, 0); | 114 OsrHelper helper(0, 0); |
121 helper.Deconstruct(&jsgraph, &common, main_zone()); | 115 helper.Deconstruct(&jsgraph, &common, main_zone()); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 | 484 |
491 TEST(Deconstruct_osr_nested3) { | 485 TEST(Deconstruct_osr_nested3) { |
492 OsrDeconstructorTester T(1); | 486 OsrDeconstructorTester T(1); |
493 | 487 |
494 // outermost loop. | 488 // outermost loop. |
495 While loop0(T, T.p0, false, 1); | 489 While loop0(T, T.p0, false, 1); |
496 Node* loop0_cntr = MakeCounter(&T.jsgraph, T.p0, loop0.loop); | 490 Node* loop0_cntr = MakeCounter(&T.jsgraph, T.p0, loop0.loop); |
497 loop0.branch->ReplaceInput(0, loop0_cntr); | 491 loop0.branch->ReplaceInput(0, loop0_cntr); |
498 | 492 |
499 // middle loop. | 493 // middle loop. |
500 Node* loop1 = T.graph.NewNode(T.common.Loop(2), loop0.if_true, T.self); | 494 Node* loop1 = T.graph.NewNode(T.common.Loop(1), loop0.if_true); |
501 loop1->ReplaceInput(0, loop0.if_true); | |
502 Node* loop1_phi = T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr, | 495 Node* loop1_phi = T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr, |
503 loop0_cntr, loop1); | 496 loop0_cntr, loop1); |
504 | 497 |
505 // innermost (OSR) loop. | 498 // innermost (OSR) loop. |
506 While loop2(T, T.p0, true, 1); | 499 While loop2(T, T.p0, true, 1); |
507 loop2.loop->ReplaceInput(0, loop1); | 500 loop2.loop->ReplaceInput(0, loop1); |
508 | 501 |
509 Node* loop2_cntr = MakeCounter(&T.jsgraph, loop1_phi, loop2.loop); | 502 Node* loop2_cntr = MakeCounter(&T.jsgraph, loop1_phi, loop2.loop); |
510 loop2_cntr->ReplaceInput(1, T.osr_values[0]); | 503 loop2_cntr->ReplaceInput(1, T.osr_values[0]); |
511 Node* osr_phi = loop2_cntr; | 504 Node* osr_phi = loop2_cntr; |
512 Node* loop2_inc = loop2_cntr->InputAt(2); | 505 Node* loop2_inc = loop2_cntr->InputAt(2); |
513 loop2.branch->ReplaceInput(0, loop2_cntr); | 506 loop2.branch->ReplaceInput(0, loop2_cntr); |
514 | 507 |
515 loop1_phi->ReplaceInput(1, loop2_cntr); | 508 loop1_phi->ReplaceInput(1, loop2_cntr); |
516 loop0_cntr->ReplaceInput(1, loop2_cntr); | 509 loop0_cntr->ReplaceInput(1, loop2_cntr); |
517 | 510 |
518 // Branch to either the outer or middle loop. | 511 // Branch to either the outer or middle loop. |
519 Node* branch = T.graph.NewNode(T.common.Branch(), loop2_cntr, loop2.exit); | 512 Node* branch = T.graph.NewNode(T.common.Branch(), loop2_cntr, loop2.exit); |
520 Node* if_true = T.graph.NewNode(T.common.IfTrue(), branch); | 513 Node* if_true = T.graph.NewNode(T.common.IfTrue(), branch); |
521 Node* if_false = T.graph.NewNode(T.common.IfFalse(), branch); | 514 Node* if_false = T.graph.NewNode(T.common.IfFalse(), branch); |
522 | 515 |
523 loop0.loop->ReplaceInput(1, if_true); | 516 loop0.loop->ReplaceInput(1, if_true); |
524 loop1->ReplaceInput(1, if_false); | 517 loop1->AppendInput(T.graph.zone(), if_false); |
| 518 NodeProperties::ChangeOp(loop1, T.common.Loop(2)); |
525 | 519 |
526 Node* ret = | 520 Node* ret = |
527 T.graph.NewNode(T.common.Return(), loop0_cntr, T.start, loop0.exit); | 521 T.graph.NewNode(T.common.Return(), loop0_cntr, T.start, loop0.exit); |
528 Node* end = T.graph.NewNode(T.common.End(1), ret); | 522 Node* end = T.graph.NewNode(T.common.End(1), ret); |
529 T.graph.SetEnd(end); | 523 T.graph.SetEnd(end); |
530 | 524 |
531 T.DeconstructOsr(); | 525 T.DeconstructOsr(); |
532 | 526 |
533 // Check structure of deconstructed graph. | 527 // Check structure of deconstructed graph. |
534 // Check loop2 (OSR loop) is directly connected to start. | 528 // Check loop2 (OSR loop) is directly connected to start. |
(...skipping 27 matching lines...) Expand all Loading... |
562 | 556 |
563 Node* new_loop0_phi = new_ret->InputAt(0); | 557 Node* new_loop0_phi = new_ret->InputAt(0); |
564 CHECK_EQ(IrOpcode::kPhi, new_loop0_phi->opcode()); | 558 CHECK_EQ(IrOpcode::kPhi, new_loop0_phi->opcode()); |
565 CHECK_EQ(new_loop0_loop, NodeProperties::GetControlInput(new_loop0_phi)); | 559 CHECK_EQ(new_loop0_loop, NodeProperties::GetControlInput(new_loop0_phi)); |
566 CHECK_EQ(new_loop0_phi, FindSuccessor(new_loop0_loop, IrOpcode::kPhi)); | 560 CHECK_EQ(new_loop0_phi, FindSuccessor(new_loop0_loop, IrOpcode::kPhi)); |
567 | 561 |
568 // Check that the return returns the phi from the OSR loop and control | 562 // Check that the return returns the phi from the OSR loop and control |
569 // depends on the copy of the outer loop0. | 563 // depends on the copy of the outer loop0. |
570 CheckInputs(new_ret, new_loop0_phi, T.graph.start(), new_loop0_exit); | 564 CheckInputs(new_ret, new_loop0_phi, T.graph.start(), new_loop0_exit); |
571 } | 565 } |
OLD | NEW |