OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 void HBasicBlock::AddPhi(HPhi* phi) { | 85 void HBasicBlock::AddPhi(HPhi* phi) { |
86 ASSERT(!IsStartBlock()); | 86 ASSERT(!IsStartBlock()); |
87 phis_.Add(phi); | 87 phis_.Add(phi); |
88 phi->SetBlock(this); | 88 phi->SetBlock(this); |
89 } | 89 } |
90 | 90 |
91 | 91 |
92 void HBasicBlock::RemovePhi(HPhi* phi) { | 92 void HBasicBlock::RemovePhi(HPhi* phi) { |
93 ASSERT(phi->block() == this); | 93 ASSERT(phi->block() == this); |
94 ASSERT(phis_.Contains(phi)); | 94 ASSERT(phis_.Contains(phi)); |
95 ASSERT(phi->HasNoUses()); | 95 ASSERT(phi->HasNoUses() || !phi->is_live()); |
96 phi->ClearOperands(); | 96 phi->ClearOperands(); |
97 phis_.RemoveElement(phi); | 97 phis_.RemoveElement(phi); |
98 phi->SetBlock(NULL); | 98 phi->SetBlock(NULL); |
99 } | 99 } |
100 | 100 |
101 | 101 |
102 void HBasicBlock::AddInstruction(HInstruction* instr) { | 102 void HBasicBlock::AddInstruction(HInstruction* instr) { |
103 ASSERT(!IsStartBlock() || !IsFinished()); | 103 ASSERT(!IsStartBlock() || !IsFinished()); |
104 ASSERT(!instr->IsLinked()); | 104 ASSERT(!instr->IsLinked()); |
105 ASSERT(!IsFinished()); | 105 ASSERT(!IsFinished()); |
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 } else { | 689 } else { |
690 for (int j = 0; j < blocks_[i]->predecessors()->length(); ++j) { | 690 for (int j = 0; j < blocks_[i]->predecessors()->length(); ++j) { |
691 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); | 691 blocks_[i]->AssignCommonDominator(blocks_[i]->predecessors()->at(j)); |
692 } | 692 } |
693 } | 693 } |
694 } | 694 } |
695 } | 695 } |
696 | 696 |
697 | 697 |
698 void HGraph::EliminateRedundantPhis() { | 698 void HGraph::EliminateRedundantPhis() { |
699 HPhase phase("Phi elimination", this); | 699 HPhase phase("Redundant phi elimination", this); |
700 ZoneList<HValue*> uses_to_replace(2); | |
701 | 700 |
702 // Worklist of phis that can potentially be eliminated. Initialized | 701 // Worklist of phis that can potentially be eliminated. Initialized |
703 // with all phi nodes. When elimination of a phi node modifies | 702 // with all phi nodes. When elimination of a phi node modifies |
704 // another phi node the modified phi node is added to the worklist. | 703 // another phi node the modified phi node is added to the worklist. |
705 ZoneList<HPhi*> worklist(blocks_.length()); | 704 ZoneList<HPhi*> worklist(blocks_.length()); |
706 for (int i = 0; i < blocks_.length(); ++i) { | 705 for (int i = 0; i < blocks_.length(); ++i) { |
707 worklist.AddAll(*blocks_[i]->phis()); | 706 worklist.AddAll(*blocks_[i]->phis()); |
708 } | 707 } |
709 | 708 |
710 while (!worklist.is_empty()) { | 709 while (!worklist.is_empty()) { |
711 HPhi* phi = worklist.RemoveLast(); | 710 HPhi* phi = worklist.RemoveLast(); |
712 HBasicBlock* block = phi->block(); | 711 HBasicBlock* block = phi->block(); |
713 | 712 |
714 // Skip phi node if it was already replaced. | 713 // Skip phi node if it was already replaced. |
715 if (block == NULL) continue; | 714 if (block == NULL) continue; |
716 | 715 |
717 // Get replacement value if phi is redundant. | 716 // Get replacement value if phi is redundant. |
718 HValue* value = phi->GetRedundantReplacement(); | 717 HValue* value = phi->GetRedundantReplacement(); |
719 | 718 |
720 if (value != NULL) { | 719 if (value != NULL) { |
721 // Iterate through uses finding the ones that should be | 720 // Iterate through uses finding the ones that should be |
722 // replaced. | 721 // replaced. |
723 const ZoneList<HValue*>* uses = phi->uses(); | 722 ZoneList<HValue*>* uses = phi->uses(); |
724 for (int i = 0; i < uses->length(); ++i) { | 723 while (!uses->is_empty()) { |
725 HValue* use = uses->at(i); | 724 HValue* use = uses->RemoveLast(); |
726 if (!use->block()->IsStartBlock()) { | 725 if (use != NULL) { |
727 uses_to_replace.Add(use); | 726 phi->ReplaceAtUse(use, value); |
| 727 if (use->IsPhi()) worklist.Add(HPhi::cast(use)); |
728 } | 728 } |
729 } | 729 } |
730 // Replace the uses and add phis modified to the work list. | |
731 for (int i = 0; i < uses_to_replace.length(); ++i) { | |
732 HValue* use = uses_to_replace[i]; | |
733 phi->ReplaceAtUse(use, value); | |
734 if (use->IsPhi()) worklist.Add(HPhi::cast(use)); | |
735 } | |
736 uses_to_replace.Rewind(0); | |
737 block->RemovePhi(phi); | 730 block->RemovePhi(phi); |
738 } else if (FLAG_eliminate_dead_phis && phi->HasNoUses() && | 731 } |
739 !phi->IsReceiver()) { | 732 } |
| 733 } |
| 734 |
| 735 |
| 736 void HGraph::EliminateUnreachablePhis() { |
| 737 HPhase phase("Unreachable phi elimination", this); |
| 738 |
| 739 // Initialize worklist. |
| 740 ZoneList<HPhi*> phi_list(blocks_.length()); |
| 741 ZoneList<HPhi*> worklist(blocks_.length()); |
| 742 for (int i = 0; i < blocks_.length(); ++i) { |
| 743 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { |
| 744 HPhi* phi = blocks_[i]->phis()->at(j); |
| 745 phi_list.Add(phi); |
740 // We can't eliminate phis in the receiver position in the environment | 746 // We can't eliminate phis in the receiver position in the environment |
741 // because in case of throwing an error we need this value to | 747 // because in case of throwing an error we need this value to |
742 // construct a stack trace. | 748 // construct a stack trace. |
| 749 if (phi->HasRealUses() || phi->IsReceiver()) { |
| 750 phi->set_is_live(true); |
| 751 worklist.Add(phi); |
| 752 } |
| 753 } |
| 754 } |
| 755 |
| 756 // Iteratively mark live phis. |
| 757 while (!worklist.is_empty()) { |
| 758 HPhi* phi = worklist.RemoveLast(); |
| 759 for (int i = 0; i < phi->OperandCount(); i++) { |
| 760 HValue* operand = phi->OperandAt(i); |
| 761 if (operand->IsPhi() && !HPhi::cast(operand)->is_live()) { |
| 762 HPhi::cast(operand)->set_is_live(true); |
| 763 worklist.Add(HPhi::cast(operand)); |
| 764 } |
| 765 } |
| 766 } |
| 767 |
| 768 // Remove unreachable phis. |
| 769 for (int i = 0; i < phi_list.length(); i++) { |
| 770 HPhi* phi = phi_list[i]; |
| 771 if (!phi->is_live()) { |
| 772 HBasicBlock* block = phi->block(); |
743 block->RemovePhi(phi); | 773 block->RemovePhi(phi); |
744 block->RecordDeletedPhi(phi->merged_index()); | 774 block->RecordDeletedPhi(phi->merged_index()); |
745 } | 775 } |
746 } | 776 } |
747 } | 777 } |
748 | 778 |
749 | 779 |
750 bool HGraph::CollectPhis() { | 780 bool HGraph::CollectPhis() { |
751 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 781 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
752 phi_list_ = new ZoneList<HPhi*>(blocks->length()); | 782 phi_list_ = new ZoneList<HPhi*>(blocks->length()); |
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 if (current_block() != NULL) { | 2190 if (current_block() != NULL) { |
2161 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); | 2191 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); |
2162 current_block()->FinishExit(instr); | 2192 current_block()->FinishExit(instr); |
2163 set_current_block(NULL); | 2193 set_current_block(NULL); |
2164 } | 2194 } |
2165 } | 2195 } |
2166 | 2196 |
2167 graph()->OrderBlocks(); | 2197 graph()->OrderBlocks(); |
2168 graph()->AssignDominators(); | 2198 graph()->AssignDominators(); |
2169 graph()->EliminateRedundantPhis(); | 2199 graph()->EliminateRedundantPhis(); |
| 2200 if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); |
2170 if (!graph()->CollectPhis()) { | 2201 if (!graph()->CollectPhis()) { |
2171 Bailout("Phi-use of arguments object"); | 2202 Bailout("Phi-use of arguments object"); |
2172 return NULL; | 2203 return NULL; |
2173 } | 2204 } |
2174 | 2205 |
2175 HInferRepresentation rep(graph()); | 2206 HInferRepresentation rep(graph()); |
2176 rep.Analyze(); | 2207 rep.Analyze(); |
2177 | 2208 |
2178 if (FLAG_use_range) { | 2209 if (FLAG_use_range) { |
2179 HRangeAnalysis rangeAnalysis(graph()); | 2210 HRangeAnalysis rangeAnalysis(graph()); |
(...skipping 3759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5939 } | 5970 } |
5940 } | 5971 } |
5941 | 5972 |
5942 #ifdef DEBUG | 5973 #ifdef DEBUG |
5943 if (graph_ != NULL) graph_->Verify(); | 5974 if (graph_ != NULL) graph_->Verify(); |
5944 if (allocator_ != NULL) allocator_->Verify(); | 5975 if (allocator_ != NULL) allocator_->Verify(); |
5945 #endif | 5976 #endif |
5946 } | 5977 } |
5947 | 5978 |
5948 } } // namespace v8::internal | 5979 } } // namespace v8::internal |
OLD | NEW |