Revision f230a1cf deps/v8/src/hydrogen-dce.cc
deps/v8/src/hydrogen-dce.cc | ||
---|---|---|
31 | 31 |
namespace v8 { |
32 | 32 |
namespace internal { |
33 | 33 |
|
34 |
bool HDeadCodeEliminationPhase::MarkLive(HValue* ref, HValue* instr) { |
|
35 |
if (instr->CheckFlag(HValue::kIsLive)) return false; |
|
36 |
instr->SetFlag(HValue::kIsLive); |
|
37 |
|
|
38 |
if (FLAG_trace_dead_code_elimination) { |
|
39 |
HeapStringAllocator allocator; |
|
40 |
StringStream stream(&allocator); |
|
41 |
if (ref != NULL) { |
|
42 |
ref->PrintTo(&stream); |
|
43 |
} else { |
|
44 |
stream.Add("root "); |
|
34 |
void HDeadCodeEliminationPhase::MarkLive( |
|
35 |
HValue* instr, ZoneList<HValue*>* worklist) { |
|
36 |
if (instr->CheckFlag(HValue::kIsLive)) return; // Already live. |
|
37 |
|
|
38 |
if (FLAG_trace_dead_code_elimination) PrintLive(NULL, instr); |
|
39 |
|
|
40 |
// Transitively mark all inputs of live instructions live. |
|
41 |
worklist->Add(instr, zone()); |
|
42 |
while (!worklist->is_empty()) { |
|
43 |
HValue* instr = worklist->RemoveLast(); |
|
44 |
instr->SetFlag(HValue::kIsLive); |
|
45 |
for (int i = 0; i < instr->OperandCount(); ++i) { |
|
46 |
HValue* input = instr->OperandAt(i); |
|
47 |
if (!input->CheckFlag(HValue::kIsLive)) { |
|
48 |
input->SetFlag(HValue::kIsLive); |
|
49 |
worklist->Add(input, zone()); |
|
50 |
if (FLAG_trace_dead_code_elimination) PrintLive(instr, input); |
|
51 |
} |
|
45 | 52 |
} |
46 |
stream.Add(" -> "); |
|
47 |
instr->PrintTo(&stream); |
|
48 |
PrintF("[MarkLive %s]\n", *stream.ToCString()); |
|
49 | 53 |
} |
54 |
} |
|
55 |
|
|
50 | 56 |
|
51 |
return true; |
|
57 |
void HDeadCodeEliminationPhase::PrintLive(HValue* ref, HValue* instr) { |
|
58 |
HeapStringAllocator allocator; |
|
59 |
StringStream stream(&allocator); |
|
60 |
if (ref != NULL) { |
|
61 |
ref->PrintTo(&stream); |
|
62 |
} else { |
|
63 |
stream.Add("root "); |
|
64 |
} |
|
65 |
stream.Add(" -> "); |
|
66 |
instr->PrintTo(&stream); |
|
67 |
PrintF("[MarkLive %s]\n", *stream.ToCString()); |
|
52 | 68 |
} |
53 | 69 |
|
54 | 70 |
|
55 | 71 |
void HDeadCodeEliminationPhase::MarkLiveInstructions() { |
56 |
ZoneList<HValue*> worklist(graph()->blocks()->length(), zone());
|
|
72 |
ZoneList<HValue*> worklist(10, zone());
|
|
57 | 73 |
|
58 |
// Mark initial root instructions for dead code elimination.
|
|
74 |
// Transitively mark all live instructions, starting from roots.
|
|
59 | 75 |
for (int i = 0; i < graph()->blocks()->length(); ++i) { |
60 | 76 |
HBasicBlock* block = graph()->blocks()->at(i); |
61 | 77 |
for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
62 | 78 |
HInstruction* instr = it.Current(); |
63 |
if (instr->CannotBeEliminated() && MarkLive(NULL, instr)) { |
|
64 |
worklist.Add(instr, zone()); |
|
65 |
} |
|
79 |
if (instr->CannotBeEliminated()) MarkLive(instr, &worklist); |
|
66 | 80 |
} |
67 | 81 |
for (int j = 0; j < block->phis()->length(); j++) { |
68 | 82 |
HPhi* phi = block->phis()->at(j); |
69 |
if (phi->CannotBeEliminated() && MarkLive(NULL, phi)) { |
|
70 |
worklist.Add(phi, zone()); |
|
71 |
} |
|
83 |
if (phi->CannotBeEliminated()) MarkLive(phi, &worklist); |
|
72 | 84 |
} |
73 | 85 |
} |
74 | 86 |
|
75 |
// Transitively mark all inputs of live instructions live. |
|
76 |
while (!worklist.is_empty()) { |
|
77 |
HValue* instr = worklist.RemoveLast(); |
|
78 |
for (int i = 0; i < instr->OperandCount(); ++i) { |
|
79 |
if (MarkLive(instr, instr->OperandAt(i))) { |
|
80 |
worklist.Add(instr->OperandAt(i), zone()); |
|
81 |
} |
|
82 |
} |
|
83 |
} |
|
87 |
ASSERT(worklist.is_empty()); // Should have processed everything. |
|
84 | 88 |
} |
85 | 89 |
|
86 | 90 |
|
... | ... | |
93 | 97 |
for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
94 | 98 |
HInstruction* instr = it.Current(); |
95 | 99 |
if (!instr->CheckFlag(HValue::kIsLive)) { |
96 |
// Instruction has not been marked live; assume it is dead and remove. |
|
97 |
// TODO(titzer): we don't remove constants because some special ones |
|
98 |
// might be used by later phases and are assumed to be in the graph |
|
99 |
if (!instr->IsConstant()) instr->DeleteAndReplaceWith(NULL); |
|
100 |
// Instruction has not been marked live, so remove it. |
|
101 |
instr->DeleteAndReplaceWith(NULL); |
|
100 | 102 |
} else { |
101 | 103 |
// Clear the liveness flag to leave the graph clean for the next DCE. |
102 | 104 |
instr->ClearFlag(HValue::kIsLive); |
Also available in: Unified diff