OLD | NEW |
| (Empty) |
1 // Copyright 2013 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/hydrogen-dce.h" | |
6 | |
7 namespace v8 { | |
8 namespace internal { | |
9 | |
10 void HDeadCodeEliminationPhase::MarkLive( | |
11 HValue* instr, ZoneList<HValue*>* worklist) { | |
12 if (instr->CheckFlag(HValue::kIsLive)) return; // Already live. | |
13 | |
14 if (FLAG_trace_dead_code_elimination) PrintLive(NULL, instr); | |
15 | |
16 // Transitively mark all inputs of live instructions live. | |
17 worklist->Add(instr, zone()); | |
18 while (!worklist->is_empty()) { | |
19 HValue* instr = worklist->RemoveLast(); | |
20 instr->SetFlag(HValue::kIsLive); | |
21 for (int i = 0; i < instr->OperandCount(); ++i) { | |
22 HValue* input = instr->OperandAt(i); | |
23 if (!input->CheckFlag(HValue::kIsLive)) { | |
24 input->SetFlag(HValue::kIsLive); | |
25 worklist->Add(input, zone()); | |
26 if (FLAG_trace_dead_code_elimination) PrintLive(instr, input); | |
27 } | |
28 } | |
29 } | |
30 } | |
31 | |
32 | |
33 void HDeadCodeEliminationPhase::PrintLive(HValue* ref, HValue* instr) { | |
34 AllowHandleDereference allow_deref; | |
35 OFStream os(stdout); | |
36 os << "[MarkLive "; | |
37 if (ref != NULL) { | |
38 os << *ref; | |
39 } else { | |
40 os << "root"; | |
41 } | |
42 os << " -> " << *instr << "]" << std::endl; | |
43 } | |
44 | |
45 | |
46 void HDeadCodeEliminationPhase::MarkLiveInstructions() { | |
47 ZoneList<HValue*> worklist(10, zone()); | |
48 | |
49 // Transitively mark all live instructions, starting from roots. | |
50 for (int i = 0; i < graph()->blocks()->length(); ++i) { | |
51 HBasicBlock* block = graph()->blocks()->at(i); | |
52 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { | |
53 HInstruction* instr = it.Current(); | |
54 if (instr->CannotBeEliminated()) MarkLive(instr, &worklist); | |
55 } | |
56 for (int j = 0; j < block->phis()->length(); j++) { | |
57 HPhi* phi = block->phis()->at(j); | |
58 if (phi->CannotBeEliminated()) MarkLive(phi, &worklist); | |
59 } | |
60 } | |
61 | |
62 DCHECK(worklist.is_empty()); // Should have processed everything. | |
63 } | |
64 | |
65 | |
66 void HDeadCodeEliminationPhase::RemoveDeadInstructions() { | |
67 ZoneList<HPhi*> worklist(graph()->blocks()->length(), zone()); | |
68 | |
69 // Remove any instruction not marked kIsLive. | |
70 for (int i = 0; i < graph()->blocks()->length(); ++i) { | |
71 HBasicBlock* block = graph()->blocks()->at(i); | |
72 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { | |
73 HInstruction* instr = it.Current(); | |
74 if (!instr->CheckFlag(HValue::kIsLive)) { | |
75 // Instruction has not been marked live, so remove it. | |
76 instr->DeleteAndReplaceWith(NULL); | |
77 } else { | |
78 // Clear the liveness flag to leave the graph clean for the next DCE. | |
79 instr->ClearFlag(HValue::kIsLive); | |
80 } | |
81 } | |
82 // Collect phis that are dead and remove them in the next pass. | |
83 for (int j = 0; j < block->phis()->length(); j++) { | |
84 HPhi* phi = block->phis()->at(j); | |
85 if (!phi->CheckFlag(HValue::kIsLive)) { | |
86 worklist.Add(phi, zone()); | |
87 } else { | |
88 phi->ClearFlag(HValue::kIsLive); | |
89 } | |
90 } | |
91 } | |
92 | |
93 // Process phis separately to avoid simultaneously mutating the phi list. | |
94 while (!worklist.is_empty()) { | |
95 HPhi* phi = worklist.RemoveLast(); | |
96 HBasicBlock* block = phi->block(); | |
97 phi->DeleteAndReplaceWith(NULL); | |
98 if (phi->HasMergedIndex()) { | |
99 block->RecordDeletedPhi(phi->merged_index()); | |
100 } | |
101 } | |
102 } | |
103 | |
104 } // namespace internal | |
105 } // namespace v8 | |
OLD | NEW |