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/bit-vector.h" | 5 #include "src/bit-vector.h" |
6 #include "src/compiler/instruction.h" | 6 #include "src/compiler/instruction.h" |
7 #include "src/compiler/register-allocator-verifier.h" | 7 #include "src/compiler/register-allocator-verifier.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 auto pred_rpo = block->predecessors()[i]; | 571 auto pred_rpo = block->predecessors()[i]; |
572 auto& pred_map = outgoing_maps_[pred_rpo.ToSize()]->map(); | 572 auto& pred_map = outgoing_maps_[pred_rpo.ToSize()]->map(); |
573 auto& pred_val = *pred_map.find(succ_val.first); | 573 auto& pred_val = *pred_map.find(succ_val.first); |
574 if (pred_val.second->use_vreg != kInvalidVreg) { | 574 if (pred_val.second->use_vreg != kInvalidVreg) { |
575 CHECK_EQ(succ_vreg, pred_val.second->use_vreg); | 575 CHECK_EQ(succ_vreg, pred_val.second->use_vreg); |
576 } | 576 } |
577 if (pred_val.second->define_vreg != kInvalidVreg) { | 577 if (pred_val.second->define_vreg != kInvalidVreg) { |
578 CHECK_EQ(succ_vreg, pred_val.second->define_vreg); | 578 CHECK_EQ(succ_vreg, pred_val.second->define_vreg); |
579 } | 579 } |
580 if (pred_val.second->succ_vreg != kInvalidVreg) { | 580 if (pred_val.second->succ_vreg != kInvalidVreg) { |
581 CHECK_EQ(succ_vreg, pred_val.second->succ_vreg); | 581 if (succ_vreg != pred_val.second->succ_vreg) { |
| 582 // When a block introduces 2 identical phis A and B, and both are |
| 583 // operands to other phis C and D, and we optimized the moves |
| 584 // defining A or B such that they now appear in the block defining |
| 585 // A and B, the back propagation will get confused when visiting |
| 586 // upwards from C and D. The operand in the block defining A and B |
| 587 // will be attributed to C (or D, depending which of these is |
| 588 // visited first). |
| 589 CHECK(IsPhi(pred_val.second->succ_vreg)); |
| 590 CHECK(IsPhi(succ_vreg)); |
| 591 const PhiData* current_phi = GetPhi(succ_vreg); |
| 592 const PhiData* assigned_phi = GetPhi(pred_val.second->succ_vreg); |
| 593 CHECK_EQ(current_phi->operands.size(), |
| 594 assigned_phi->operands.size()); |
| 595 CHECK_EQ(current_phi->definition_rpo, |
| 596 assigned_phi->definition_rpo); |
| 597 for (size_t i = 0; i < current_phi->operands.size(); ++i) { |
| 598 CHECK_EQ(current_phi->operands[i], assigned_phi->operands[i]); |
| 599 } |
| 600 } |
582 } else { | 601 } else { |
583 pred_val.second->succ_vreg = succ_vreg; | 602 pred_val.second->succ_vreg = succ_vreg; |
584 block_ids.insert(pred_rpo.ToSize()); | 603 block_ids.insert(pred_rpo.ToSize()); |
585 } | 604 } |
586 } | 605 } |
587 } | 606 } |
588 } | 607 } |
589 // Clear uses and back links for second pass. | 608 // Clear uses and back links for second pass. |
590 for (auto operand_map : incoming_maps_) { | 609 for (auto operand_map : incoming_maps_) { |
591 for (auto& succ_val : operand_map->map()) { | 610 for (auto& succ_val : operand_map->map()) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 USE(insert_result); | 746 USE(insert_result); |
728 } | 747 } |
729 } | 748 } |
730 } | 749 } |
731 } | 750 } |
732 } | 751 } |
733 | 752 |
734 } // namespace compiler | 753 } // namespace compiler |
735 } // namespace internal | 754 } // namespace internal |
736 } // namespace v8 | 755 } // namespace v8 |
OLD | NEW |