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

Side by Side Diff: src/hydrogen.cc

Issue 18791002: Turn dead code elimination into a proper HPhase. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use local worklists. Created 7 years, 5 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-dce.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "hydrogen.h" 28 #include "hydrogen.h"
29 29
30 #include <algorithm> 30 #include <algorithm>
31 31
32 #include "v8.h" 32 #include "v8.h"
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "full-codegen.h" 34 #include "full-codegen.h"
35 #include "hashmap.h" 35 #include "hashmap.h"
36 #include "hydrogen-dce.h"
36 #include "hydrogen-environment-liveness.h" 37 #include "hydrogen-environment-liveness.h"
37 #include "hydrogen-escape-analysis.h" 38 #include "hydrogen-escape-analysis.h"
38 #include "hydrogen-infer-representation.h" 39 #include "hydrogen-infer-representation.h"
39 #include "hydrogen-gvn.h" 40 #include "hydrogen-gvn.h"
40 #include "hydrogen-osr.h" 41 #include "hydrogen-osr.h"
41 #include "hydrogen-range-analysis.h" 42 #include "hydrogen-range-analysis.h"
42 #include "hydrogen-uint32-analysis.h" 43 #include "hydrogen-uint32-analysis.h"
43 #include "lithium-allocator.h" 44 #include "lithium-allocator.h"
44 #include "parser.h" 45 #include "parser.h"
45 #include "scopeinfo.h" 46 #include "scopeinfo.h"
(...skipping 3411 matching lines...) Expand 10 before | Expand all | Expand 10 after
3457 return false; 3458 return false;
3458 } 3459 }
3459 EliminateRedundantPhis(); 3460 EliminateRedundantPhis();
3460 if (!CheckArgumentsPhiUses()) { 3461 if (!CheckArgumentsPhiUses()) {
3461 *bailout_reason = SmartArrayPointer<char>(StrDup( 3462 *bailout_reason = SmartArrayPointer<char>(StrDup(
3462 "Unsupported phi use of arguments")); 3463 "Unsupported phi use of arguments"));
3463 return false; 3464 return false;
3464 } 3465 }
3465 3466
3466 // Remove dead code and phis 3467 // Remove dead code and phis
3467 if (FLAG_dead_code_elimination) { 3468 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3468 DeadCodeElimination("H_Eliminate early dead code");
3469 }
3470 CollectPhis(); 3469 CollectPhis();
3471 3470
3472 if (has_osr()) osr()->FinishOsrValues(); 3471 if (has_osr()) osr()->FinishOsrValues();
3473 3472
3474 Run<HInferRepresentationPhase>(); 3473 Run<HInferRepresentationPhase>();
3475 3474
3476 // Remove HSimulate instructions that have turned out not to be needed 3475 // Remove HSimulate instructions that have turned out not to be needed
3477 // after all by folding them into the following HSimulate. 3476 // after all by folding them into the following HSimulate.
3478 // This must happen after inferring representations. 3477 // This must happen after inferring representations.
3479 MergeRemovableSimulates(); 3478 MergeRemovableSimulates();
(...skipping 20 matching lines...) Expand all
3500 3499
3501 // Eliminate redundant stack checks on backwards branches. 3500 // Eliminate redundant stack checks on backwards branches.
3502 HStackCheckEliminator sce(this); 3501 HStackCheckEliminator sce(this);
3503 sce.Process(); 3502 sce.Process();
3504 3503
3505 if (FLAG_idefs) SetupInformativeDefinitions(); 3504 if (FLAG_idefs) SetupInformativeDefinitions();
3506 if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) { 3505 if (FLAG_array_bounds_checks_elimination && !FLAG_idefs) {
3507 EliminateRedundantBoundsChecks(); 3506 EliminateRedundantBoundsChecks();
3508 } 3507 }
3509 if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations(); 3508 if (FLAG_array_index_dehoisting) DehoistSimpleArrayIndexComputations();
3510 if (FLAG_dead_code_elimination) { 3509 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
3511 DeadCodeElimination("H_Eliminate late dead code");
3512 }
3513 3510
3514 RestoreActualValues(); 3511 RestoreActualValues();
3515 3512
3516 return true; 3513 return true;
3517 } 3514 }
3518 3515
3519 3516
3520 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) { 3517 void HGraph::SetupInformativeDefinitionsInBlock(HBasicBlock* block) {
3521 for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) { 3518 for (int phi_index = 0; phi_index < block->phis()->length(); phi_index++) {
3522 HPhi* phi = block->phis()->at(phi_index); 3519 HPhi* phi = block->phis()->at(phi_index);
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after
3983 array_instruction = static_cast<ArrayInstructionInterface*>(op); 3980 array_instruction = static_cast<ArrayInstructionInterface*>(op);
3984 } else { 3981 } else {
3985 continue; 3982 continue;
3986 } 3983 }
3987 DehoistArrayIndex(array_instruction); 3984 DehoistArrayIndex(array_instruction);
3988 } 3985 }
3989 } 3986 }
3990 } 3987 }
3991 3988
3992 3989
3993 void HGraph::DeadCodeElimination(const char* phase_name) {
3994 HPhase phase(phase_name, this);
3995 MarkLiveInstructions();
3996 RemoveDeadInstructions();
3997 }
3998
3999
4000 void HGraph::MarkLiveInstructions() {
4001 ZoneList<HValue*> worklist(blocks_.length(), zone());
4002
4003 // Mark initial root instructions for dead code elimination.
4004 for (int i = 0; i < blocks()->length(); ++i) {
4005 HBasicBlock* block = blocks()->at(i);
4006 for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
4007 HInstruction* instr = it.Current();
4008 if (instr->CannotBeEliminated()) MarkLive(NULL, instr, &worklist);
4009 }
4010 for (int j = 0; j < block->phis()->length(); j++) {
4011 HPhi* phi = block->phis()->at(j);
4012 if (phi->CannotBeEliminated()) MarkLive(NULL, phi, &worklist);
4013 }
4014 }
4015
4016 // Transitively mark all inputs of live instructions live.
4017 while (!worklist.is_empty()) {
4018 HValue* instr = worklist.RemoveLast();
4019 for (int i = 0; i < instr->OperandCount(); ++i) {
4020 MarkLive(instr, instr->OperandAt(i), &worklist);
4021 }
4022 }
4023 }
4024
4025
4026 void HGraph::MarkLive(HValue* ref, HValue* instr, ZoneList<HValue*>* worklist) {
4027 if (!instr->CheckFlag(HValue::kIsLive)) {
4028 instr->SetFlag(HValue::kIsLive);
4029 worklist->Add(instr, zone());
4030
4031 if (FLAG_trace_dead_code_elimination) {
4032 HeapStringAllocator allocator;
4033 StringStream stream(&allocator);
4034 if (ref != NULL) {
4035 ref->PrintTo(&stream);
4036 } else {
4037 stream.Add("root ");
4038 }
4039 stream.Add(" -> ");
4040 instr->PrintTo(&stream);
4041 PrintF("[MarkLive %s]\n", *stream.ToCString());
4042 }
4043 }
4044 }
4045
4046
4047 void HGraph::RemoveDeadInstructions() {
4048 ZoneList<HPhi*> dead_phis(blocks_.length(), zone());
4049
4050 // Remove any instruction not marked kIsLive.
4051 for (int i = 0; i < blocks()->length(); ++i) {
4052 HBasicBlock* block = blocks()->at(i);
4053 for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
4054 HInstruction* instr = it.Current();
4055 if (!instr->CheckFlag(HValue::kIsLive)) {
4056 // Instruction has not been marked live; assume it is dead and remove.
4057 // TODO(titzer): we don't remove constants because some special ones
4058 // might be used by later phases and are assumed to be in the graph
4059 if (!instr->IsConstant()) instr->DeleteAndReplaceWith(NULL);
4060 } else {
4061 // Clear the liveness flag to leave the graph clean for the next DCE.
4062 instr->ClearFlag(HValue::kIsLive);
4063 }
4064 }
4065 // Collect phis that are dead and remove them in the next pass.
4066 for (int j = 0; j < block->phis()->length(); j++) {
4067 HPhi* phi = block->phis()->at(j);
4068 if (!phi->CheckFlag(HValue::kIsLive)) {
4069 dead_phis.Add(phi, zone());
4070 } else {
4071 phi->ClearFlag(HValue::kIsLive);
4072 }
4073 }
4074 }
4075
4076 // Process phis separately to avoid simultaneously mutating the phi list.
4077 while (!dead_phis.is_empty()) {
4078 HPhi* phi = dead_phis.RemoveLast();
4079 HBasicBlock* block = phi->block();
4080 phi->DeleteAndReplaceWith(NULL);
4081 block->RecordDeletedPhi(phi->merged_index());
4082 }
4083 }
4084
4085
4086 void HGraph::RestoreActualValues() { 3990 void HGraph::RestoreActualValues() {
4087 HPhase phase("H_Restore actual values", this); 3991 HPhase phase("H_Restore actual values", this);
4088 3992
4089 for (int block_index = 0; block_index < blocks()->length(); block_index++) { 3993 for (int block_index = 0; block_index < blocks()->length(); block_index++) {
4090 HBasicBlock* block = blocks()->at(block_index); 3994 HBasicBlock* block = blocks()->at(block_index);
4091 3995
4092 #ifdef DEBUG 3996 #ifdef DEBUG
4093 for (int i = 0; i < block->phis()->length(); i++) { 3997 for (int i = 0; i < block->phis()->length(); i++) {
4094 HPhi* phi = block->phis()->at(i); 3998 HPhi* phi = block->phis()->at(i);
4095 ASSERT(phi->ActualValue() == phi); 3999 ASSERT(phi->ActualValue() == phi);
(...skipping 6741 matching lines...) Expand 10 before | Expand all | Expand 10 after
10837 if (ShouldProduceTraceOutput()) { 10741 if (ShouldProduceTraceOutput()) {
10838 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10742 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10839 } 10743 }
10840 10744
10841 #ifdef DEBUG 10745 #ifdef DEBUG
10842 graph_->Verify(false); // No full verify. 10746 graph_->Verify(false); // No full verify.
10843 #endif 10747 #endif
10844 } 10748 }
10845 10749
10846 } } // namespace v8::internal 10750 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-dce.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698