OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |