| 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 |