OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 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/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
6 #include "src/compiler/control-reducer.h" | 6 #include "src/compiler/control-reducer.h" |
7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/node-marker.h" | 9 #include "src/compiler/node-marker.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 int index = 0; | 500 int index = 0; |
501 int live_index = 0; | 501 int live_index = 0; |
502 for (Node* const input : node->inputs()) { | 502 for (Node* const input : node->inputs()) { |
503 if (input->opcode() != IrOpcode::kDead) { | 503 if (input->opcode() != IrOpcode::kDead) { |
504 live++; | 504 live++; |
505 live_index = index; | 505 live_index = index; |
506 } | 506 } |
507 index++; | 507 index++; |
508 } | 508 } |
509 | 509 |
510 if (live > 1 && live == node->InputCount()) return node; // nothing to do. | |
511 | |
512 TRACE(("ReduceMerge: #%d:%s (%d live)\n", node->id(), | 510 TRACE(("ReduceMerge: #%d:%s (%d live)\n", node->id(), |
513 node->op()->mnemonic(), live)); | 511 node->op()->mnemonic(), live)); |
514 | 512 |
515 if (live == 0) return dead(); // no remaining inputs. | 513 if (live == 0) return dead(); // no remaining inputs. |
516 | 514 |
517 // Gather phis and effect phis to be edited. | 515 // Gather phis and effect phis to be edited. |
518 ZoneVector<Node*> phis(zone_); | 516 ZoneVector<Node*> phis(zone_); |
519 for (Node* const use : node->uses()) { | 517 for (Node* const use : node->uses()) { |
520 if (NodeProperties::IsPhi(use)) phis.push_back(use); | 518 if (NodeProperties::IsPhi(use)) phis.push_back(use); |
521 } | 519 } |
522 | 520 |
523 if (live == 1) { | 521 if (live == 1) { |
524 // All phis are redundant. Replace them with their live input. | 522 // All phis are redundant. Replace them with their live input. |
525 for (Node* const phi : phis) ReplaceNode(phi, phi->InputAt(live_index)); | 523 for (Node* const phi : phis) ReplaceNode(phi, phi->InputAt(live_index)); |
526 // The merge itself is redundant. | 524 // The merge itself is redundant. |
527 return node->InputAt(live_index); | 525 return node->InputAt(live_index); |
528 } | 526 } |
529 | 527 |
530 // Edit phis in place, removing dead inputs and revisiting them. | 528 DCHECK_LE(2, live); |
531 for (Node* const phi : phis) { | 529 |
532 TRACE((" PhiInMerge: #%d:%s (%d live)\n", phi->id(), | 530 if (live < node->InputCount()) { |
533 phi->op()->mnemonic(), live)); | 531 // Edit phis in place, removing dead inputs and revisiting them. |
534 RemoveDeadInputs(node, phi); | 532 for (Node* const phi : phis) { |
535 Revisit(phi); | 533 TRACE((" PhiInMerge: #%d:%s (%d live)\n", phi->id(), |
534 phi->op()->mnemonic(), live)); | |
535 RemoveDeadInputs(node, phi); | |
536 Revisit(phi); | |
537 } | |
538 // Edit the merge in place, removing dead inputs. | |
539 RemoveDeadInputs(node, node); | |
536 } | 540 } |
537 // Edit the merge in place, removing dead inputs. | 541 |
538 RemoveDeadInputs(node, node); | 542 DCHECK_EQ(live, node->InputCount()); |
543 | |
544 // Check if it's an unused diamond. | |
545 if (live == 2 && phis.empty()) { | |
546 Node* node0 = node->InputAt(0); | |
547 Node* node1 = node->InputAt(1); | |
548 if (((node0->opcode() == IrOpcode::kIfTrue && | |
549 node1->opcode() == IrOpcode::kIfFalse) || | |
550 (node0->opcode() == IrOpcode::kIfTrue && | |
551 node1->opcode() == IrOpcode::kIfFalse)) && | |
brucedawson
2015/03/13 18:38:21
This test looks wrong. This showed up as a new VC+
Jarin
2015/03/14 19:17:34
Good catch. This should test that node0/1 is kIfTr
| |
552 node0->OwnedBy(node) && node1->OwnedBy(node)) { | |
553 Node* branch0 = NodeProperties::GetControlInput(node0); | |
554 Node* branch1 = NodeProperties::GetControlInput(node1); | |
555 if (branch0 == branch1) { | |
556 // It's a dead diamond, i.e. neither the IfTrue nor the IfFalse nodes | |
557 // have users except for the Merge and the Merge has no Phi or | |
558 // EffectPhi uses, so replace the Merge with the control input of the | |
559 // diamond. | |
560 TRACE((" DeadDiamond: #%d:%s #%d:%s #%d:%s\n", node0->id(), | |
561 node0->op()->mnemonic(), node1->id(), node1->op()->mnemonic(), | |
562 branch0->id(), branch0->op()->mnemonic())); | |
563 return NodeProperties::GetControlInput(branch0); | |
564 } | |
565 } | |
566 } | |
567 | |
539 return node; | 568 return node; |
540 } | 569 } |
541 | 570 |
542 // Reduce branches if they have constant inputs. | 571 // Reduce branches if they have constant inputs. |
543 Node* ReduceIfTrue(Node* node) { | 572 Node* ReduceIfTrue(Node* node) { |
544 Node* branch = node->InputAt(0); | 573 Node* branch = node->InputAt(0); |
545 DCHECK_EQ(IrOpcode::kBranch, branch->opcode()); | 574 DCHECK_EQ(IrOpcode::kBranch, branch->opcode()); |
546 Decision result = DecideCondition(branch->InputAt(0)); | 575 Decision result = DecideCondition(branch->InputAt(0)); |
547 if (result == kTrue) { | 576 if (result == kTrue) { |
548 // fold a true branch by replacing IfTrue with the branch control. | 577 // fold a true branch by replacing IfTrue with the branch control. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
648 return impl.ReduceIfTrue(node); | 677 return impl.ReduceIfTrue(node); |
649 case IrOpcode::kIfFalse: | 678 case IrOpcode::kIfFalse: |
650 return impl.ReduceIfFalse(node); | 679 return impl.ReduceIfFalse(node); |
651 default: | 680 default: |
652 return node; | 681 return node; |
653 } | 682 } |
654 } | 683 } |
655 } | 684 } |
656 } | 685 } |
657 } // namespace v8::internal::compiler | 686 } // namespace v8::internal::compiler |
OLD | NEW |