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 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
714 // Skip phi node if it was already replaced. | 714 // Skip phi node if it was already replaced. |
715 if (block == NULL) continue; | 715 if (block == NULL) continue; |
716 | 716 |
717 // Get replacement value if phi is redundant. | 717 // Get replacement value if phi is redundant. |
718 HValue* value = phi->GetRedundantReplacement(); | 718 HValue* value = phi->GetRedundantReplacement(); |
719 | 719 |
720 if (value != NULL) { | 720 if (value != NULL) { |
721 // Iterate through uses finding the ones that should be | 721 // Iterate through uses finding the ones that should be |
722 // replaced. | 722 // replaced. |
723 const ZoneList<HValue*>* uses = phi->uses(); | 723 const ZoneList<HValue*>* uses = phi->uses(); |
724 for (int i = 0; i < uses->length(); ++i) { | 724 for (int i = 0; i < uses->length(); ++i) { |
Kevin Millikin (Chromium)
2011/03/08 08:51:03
This pair of loops that copies the uses off to the
fschneider
2011/03/08 10:03:39
Done.
| |
725 HValue* use = uses->at(i); | 725 HValue* use = uses->at(i); |
726 if (!use->block()->IsStartBlock()) { | 726 ASSERT(!use->block()->IsStartBlock()); |
727 uses_to_replace.Add(use); | 727 uses_to_replace.Add(use); |
728 } | |
729 } | 728 } |
730 // Replace the uses and add phis modified to the work list. | 729 // Replace the uses and add phis modified to the work list. |
731 for (int i = 0; i < uses_to_replace.length(); ++i) { | 730 for (int i = 0; i < uses_to_replace.length(); ++i) { |
732 HValue* use = uses_to_replace[i]; | 731 HValue* use = uses_to_replace[i]; |
733 phi->ReplaceAtUse(use, value); | 732 phi->ReplaceAtUse(use, value); |
734 if (use->IsPhi()) worklist.Add(HPhi::cast(use)); | 733 if (use->IsPhi()) worklist.Add(HPhi::cast(use)); |
735 } | 734 } |
736 uses_to_replace.Rewind(0); | 735 uses_to_replace.Rewind(0); |
737 block->RemovePhi(phi); | 736 block->RemovePhi(phi); |
738 } else if (FLAG_eliminate_dead_phis && phi->HasNoUses() && | 737 } |
739 !phi->IsReceiver()) { | 738 } |
739 } | |
740 | |
741 | |
742 void HGraph::EliminateDeadPhis() { | |
743 HPhase phase("Dead phi elimination", this); | |
744 | |
745 // Initialize worklist. | |
746 ZoneList<HPhi*> phi_list(blocks_.length()); | |
747 ZoneList<HPhi*> worklist(blocks_.length()); | |
748 for (int i = 0; i < blocks_.length(); ++i) { | |
749 for (int j = 0; j < blocks_[i]->phis()->length(); j++) { | |
750 HPhi* phi = blocks_[i]->phis()->at(j); | |
751 phi_list.Add(phi); | |
740 // We can't eliminate phis in the receiver position in the environment | 752 // 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 | 753 // because in case of throwing an error we need this value to |
742 // construct a stack trace. | 754 // construct a stack trace. |
755 if (phi->HasRealUses() || phi->IsReceiver()) { | |
756 phi->set_is_live(true); | |
757 worklist.Add(phi); | |
758 } | |
759 } | |
760 } | |
761 | |
762 // Iteratively mark live phis. | |
763 while (!worklist.is_empty()) { | |
764 HPhi* phi = worklist.RemoveLast(); | |
765 for (int i = 0; i < phi->OperandCount(); i++) { | |
766 HValue* operand = phi->OperandAt(i); | |
767 if (operand->IsPhi() && !HPhi::cast(operand)->is_live()) { | |
768 HPhi::cast(operand)->set_is_live(true); | |
769 worklist.Add(HPhi::cast(operand)); | |
770 } | |
771 } | |
772 } | |
773 | |
774 // Remove dead phis. | |
775 for (int i = 0; i < phi_list.length(); i++) { | |
776 HPhi* phi = phi_list[i]; | |
777 if (!phi->is_live()) { | |
778 if (FLAG_trace_hydrogen) PrintF("Removing dead phi %d\n", phi->id()); | |
779 HBasicBlock* block = phi->block(); | |
743 block->RemovePhi(phi); | 780 block->RemovePhi(phi); |
744 block->RecordDeletedPhi(phi->merged_index()); | 781 block->RecordDeletedPhi(phi->merged_index()); |
745 } | 782 } |
746 } | 783 } |
747 } | 784 } |
748 | 785 |
749 | 786 |
750 bool HGraph::CollectPhis() { | 787 bool HGraph::CollectPhis() { |
751 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); | 788 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); |
752 phi_list_ = new ZoneList<HPhi*>(blocks->length()); | 789 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) { | 2197 if (current_block() != NULL) { |
2161 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); | 2198 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); |
2162 current_block()->FinishExit(instr); | 2199 current_block()->FinishExit(instr); |
2163 set_current_block(NULL); | 2200 set_current_block(NULL); |
2164 } | 2201 } |
2165 } | 2202 } |
2166 | 2203 |
2167 graph()->OrderBlocks(); | 2204 graph()->OrderBlocks(); |
2168 graph()->AssignDominators(); | 2205 graph()->AssignDominators(); |
2169 graph()->EliminateRedundantPhis(); | 2206 graph()->EliminateRedundantPhis(); |
2207 if (FLAG_eliminate_dead_phis) graph()->EliminateDeadPhis(); | |
2170 if (!graph()->CollectPhis()) { | 2208 if (!graph()->CollectPhis()) { |
2171 Bailout("Phi-use of arguments object"); | 2209 Bailout("Phi-use of arguments object"); |
2172 return NULL; | 2210 return NULL; |
2173 } | 2211 } |
2174 | 2212 |
2175 HInferRepresentation rep(graph()); | 2213 HInferRepresentation rep(graph()); |
2176 rep.Analyze(); | 2214 rep.Analyze(); |
2177 | 2215 |
2178 if (FLAG_use_range) { | 2216 if (FLAG_use_range) { |
2179 HRangeAnalysis rangeAnalysis(graph()); | 2217 HRangeAnalysis rangeAnalysis(graph()); |
(...skipping 3759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5939 } | 5977 } |
5940 } | 5978 } |
5941 | 5979 |
5942 #ifdef DEBUG | 5980 #ifdef DEBUG |
5943 if (graph_ != NULL) graph_->Verify(); | 5981 if (graph_ != NULL) graph_->Verify(); |
5944 if (allocator_ != NULL) allocator_->Verify(); | 5982 if (allocator_ != NULL) allocator_->Verify(); |
5945 #endif | 5983 #endif |
5946 } | 5984 } |
5947 | 5985 |
5948 } } // namespace v8::internal | 5986 } } // namespace v8::internal |
OLD | NEW |