Chromium Code Reviews| 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 |