Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: src/hydrogen.cc

Issue 6624061: Improve dead phi elimination.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698