OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler.h" | 5 #include "src/compiler.h" |
6 #include "src/compiler/all-nodes.h" | 6 #include "src/compiler/all-nodes.h" |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/control-reducer.h" | 8 #include "src/compiler/control-reducer.h" |
9 #include "src/compiler/frame.h" | 9 #include "src/compiler/frame.h" |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 } | 96 } |
97 | 97 |
98 // Construct the transfer from the previous graph copies to the new copy. | 98 // Construct the transfer from the previous graph copies to the new copy. |
99 Node* loop_header = loop_tree->HeaderNode(loop); | 99 Node* loop_header = loop_tree->HeaderNode(loop); |
100 NodeVector* previous = | 100 NodeVector* previous = |
101 copies.size() > 1 ? copies[copies.size() - 2] : nullptr; | 101 copies.size() > 1 ? copies[copies.size() - 2] : nullptr; |
102 const int backedges = loop_header->op()->ControlInputCount() - 1; | 102 const int backedges = loop_header->op()->ControlInputCount() - 1; |
103 if (backedges == 1) { | 103 if (backedges == 1) { |
104 // Simple case. Map the incoming edges to the loop to the previous copy. | 104 // Simple case. Map the incoming edges to the loop to the previous copy. |
105 for (Node* node : loop_tree->HeaderNodes(loop)) { | 105 for (Node* node : loop_tree->HeaderNodes(loop)) { |
| 106 if (!all.IsLive(node)) continue; // dead phi hanging off loop. |
106 Node* copy = mapping->at(node->id()); | 107 Node* copy = mapping->at(node->id()); |
107 Node* backedge = node->InputAt(1); | 108 Node* backedge = node->InputAt(1); |
108 if (previous) backedge = previous->at(backedge->id()); | 109 if (previous) backedge = previous->at(backedge->id()); |
109 copy->ReplaceInput(0, backedge); | 110 copy->ReplaceInput(0, backedge); |
110 } | 111 } |
111 } else { | 112 } else { |
112 // Complex case. Multiple backedges. Introduce a merge for incoming edges. | 113 // Complex case. Multiple backedges. Introduce a merge for incoming edges. |
113 tmp_inputs.clear(); | 114 tmp_inputs.clear(); |
114 for (int i = 0; i < backedges; i++) { | 115 for (int i = 0; i < backedges; i++) { |
115 Node* backedge = loop_header->InputAt(i + 1); | 116 Node* backedge = loop_header->InputAt(i + 1); |
116 if (previous) backedge = previous->at(backedge->id()); | 117 if (previous) backedge = previous->at(backedge->id()); |
117 tmp_inputs.push_back(backedge); | 118 tmp_inputs.push_back(backedge); |
118 } | 119 } |
119 Node* merge = | 120 Node* merge = |
120 graph->NewNode(common->Merge(backedges), backedges, &tmp_inputs[0]); | 121 graph->NewNode(common->Merge(backedges), backedges, &tmp_inputs[0]); |
121 for (Node* node : loop_tree->HeaderNodes(loop)) { | 122 for (Node* node : loop_tree->HeaderNodes(loop)) { |
| 123 if (!all.IsLive(node)) continue; // dead phi hanging off loop. |
122 Node* copy = mapping->at(node->id()); | 124 Node* copy = mapping->at(node->id()); |
123 if (node == loop_header) { | 125 if (node == loop_header) { |
124 // The entry to the loop is the merge. | 126 // The entry to the loop is the merge. |
125 copy->ReplaceInput(0, merge); | 127 copy->ReplaceInput(0, merge); |
126 } else { | 128 } else { |
127 // Merge inputs to the phi at the loop entry. | 129 // Merge inputs to the phi at the loop entry. |
128 tmp_inputs.clear(); | 130 tmp_inputs.clear(); |
129 for (int i = 0; i < backedges; i++) { | 131 for (int i = 0; i < backedges; i++) { |
130 Node* backedge = node->InputAt(i + 1); | 132 Node* backedge = node->InputAt(i + 1); |
131 if (previous) backedge = previous->at(backedge->id()); | 133 if (previous) backedge = previous->at(backedge->id()); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 Node* dead = jsgraph->DeadControl(); | 209 Node* dead = jsgraph->DeadControl(); |
208 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); | 210 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); |
209 if (loop->depth() > 0) { | 211 if (loop->depth() > 0) { |
210 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, | 212 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, |
211 osr_normal_entry, osr_loop_entry); | 213 osr_normal_entry, osr_loop_entry); |
212 } | 214 } |
213 | 215 |
214 // Replace the normal entry with {Dead} and the loop entry with {Start} | 216 // Replace the normal entry with {Dead} and the loop entry with {Start} |
215 // and run the control reducer to clean up the graph. | 217 // and run the control reducer to clean up the graph. |
216 osr_normal_entry->ReplaceUses(dead); | 218 osr_normal_entry->ReplaceUses(dead); |
| 219 osr_normal_entry->Kill(); |
217 osr_loop_entry->ReplaceUses(graph->start()); | 220 osr_loop_entry->ReplaceUses(graph->start()); |
| 221 osr_loop_entry->Kill(); |
218 | 222 |
219 // Normally the control reducer removes loops whose first input is dead, | 223 // Normally the control reducer removes loops whose first input is dead, |
220 // but we need to avoid that because the osr_loop is reachable through | 224 // but we need to avoid that because the osr_loop is reachable through |
221 // the second input, so reduce it and its phis manually. | 225 // the second input, so reduce it and its phis manually. |
222 osr_loop->ReplaceInput(0, dead); | 226 osr_loop->ReplaceInput(0, dead); |
223 Node* node = ControlReducer::ReduceMerge(jsgraph, common, osr_loop); | 227 Node* node = ControlReducer::ReduceMerge(jsgraph, common, osr_loop); |
224 if (node != osr_loop) osr_loop->ReplaceUses(node); | 228 if (node != osr_loop) osr_loop->ReplaceUses(node); |
225 | 229 |
226 // Run the normal control reduction, which naturally trims away the dead | 230 // Run the normal control reduction, which naturally trims away the dead |
227 // parts of the graph. | 231 // parts of the graph. |
228 ControlReducer::ReduceGraph(tmp_zone, jsgraph, common); | 232 ControlReducer::ReduceGraph(tmp_zone, jsgraph, common); |
229 | 233 |
230 return true; | 234 return true; |
231 } | 235 } |
232 | 236 |
233 | 237 |
234 void OsrHelper::SetupFrame(Frame* frame) { | 238 void OsrHelper::SetupFrame(Frame* frame) { |
235 // The optimized frame will subsume the unoptimized frame. Do so by reserving | 239 // The optimized frame will subsume the unoptimized frame. Do so by reserving |
236 // the first spill slots. | 240 // the first spill slots. |
237 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); | 241 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); |
238 // The frame needs to be adjusted by the number of unoptimized frame slots. | 242 // The frame needs to be adjusted by the number of unoptimized frame slots. |
239 frame->SetOsrStackSlotCount(static_cast<int>(UnoptimizedFrameSlots())); | 243 frame->SetOsrStackSlotCount(static_cast<int>(UnoptimizedFrameSlots())); |
240 } | 244 } |
241 | 245 |
242 | 246 |
243 } // namespace compiler | 247 } // namespace compiler |
244 } // namespace internal | 248 } // namespace internal |
245 } // namespace v8 | 249 } // namespace v8 |
OLD | NEW |