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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 end->ReplaceInput(0, merge); | 166 end->ReplaceInput(0, merge); |
167 | 167 |
168 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 168 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
169 OFStream os(stdout); | 169 OFStream os(stdout); |
170 os << "-- Graph after OSR duplication -- " << std::endl; | 170 os << "-- Graph after OSR duplication -- " << std::endl; |
171 os << AsRPO(*graph); | 171 os << AsRPO(*graph); |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 | 175 |
| 176 static void TransferOsrValueTypesFromLoopPhis(Zone* zone, Node* osr_loop_entry, |
| 177 Node* osr_loop) { |
| 178 // Find the index of the osr loop entry into the loop. |
| 179 int index = 0; |
| 180 for (index = 0; index < osr_loop->InputCount(); index++) { |
| 181 if (osr_loop->InputAt(index) == osr_loop_entry) break; |
| 182 } |
| 183 if (index == osr_loop->InputCount()) return; |
| 184 |
| 185 for (Node* osr_value : osr_loop_entry->uses()) { |
| 186 if (osr_value->opcode() != IrOpcode::kOsrValue) continue; |
| 187 bool unknown = true; |
| 188 for (Node* phi : osr_value->uses()) { |
| 189 if (phi->opcode() != IrOpcode::kPhi) continue; |
| 190 if (NodeProperties::GetControlInput(phi) != osr_loop) continue; |
| 191 if (phi->InputAt(index) != osr_value) continue; |
| 192 if (NodeProperties::IsTyped(phi)) { |
| 193 // Transfer the type from the phi to the OSR value itself. |
| 194 Bounds phi_bounds = NodeProperties::GetBounds(phi); |
| 195 if (unknown) { |
| 196 NodeProperties::SetBounds(osr_value, phi_bounds); |
| 197 } else { |
| 198 Bounds osr_bounds = NodeProperties::GetBounds(osr_value); |
| 199 NodeProperties::SetBounds(osr_value, |
| 200 Bounds::Both(phi_bounds, osr_bounds, zone)); |
| 201 } |
| 202 unknown = false; |
| 203 } |
| 204 } |
| 205 if (unknown) NodeProperties::SetBounds(osr_value, Bounds::Unbounded(zone)); |
| 206 } |
| 207 } |
| 208 |
| 209 |
176 bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, | 210 bool OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, |
177 Zone* tmp_zone) { | 211 Zone* tmp_zone) { |
178 Graph* graph = jsgraph->graph(); | 212 Graph* graph = jsgraph->graph(); |
179 Node* osr_normal_entry = nullptr; | 213 Node* osr_normal_entry = nullptr; |
180 Node* osr_loop_entry = nullptr; | 214 Node* osr_loop_entry = nullptr; |
181 Node* osr_loop = nullptr; | 215 Node* osr_loop = nullptr; |
182 | 216 |
183 for (Node* node : graph->start()->uses()) { | 217 for (Node* node : graph->start()->uses()) { |
184 if (node->opcode() == IrOpcode::kOsrLoopEntry) { | 218 if (node->opcode() == IrOpcode::kOsrLoopEntry) { |
185 osr_loop_entry = node; // found the OSR loop entry | 219 osr_loop_entry = node; // found the OSR loop entry |
(...skipping 10 matching lines...) Expand all Loading... |
196 | 230 |
197 for (Node* use : osr_loop_entry->uses()) { | 231 for (Node* use : osr_loop_entry->uses()) { |
198 if (use->opcode() == IrOpcode::kLoop) { | 232 if (use->opcode() == IrOpcode::kLoop) { |
199 CHECK(!osr_loop); // should be only one OSR loop. | 233 CHECK(!osr_loop); // should be only one OSR loop. |
200 osr_loop = use; // found the OSR loop. | 234 osr_loop = use; // found the OSR loop. |
201 } | 235 } |
202 } | 236 } |
203 | 237 |
204 CHECK(osr_loop); // Should have found the OSR loop. | 238 CHECK(osr_loop); // Should have found the OSR loop. |
205 | 239 |
| 240 // Transfer the types from loop phis to the OSR values which flow into them. |
| 241 TransferOsrValueTypesFromLoopPhis(graph->zone(), osr_loop_entry, osr_loop); |
| 242 |
206 // Analyze the graph to determine how deeply nested the OSR loop is. | 243 // Analyze the graph to determine how deeply nested the OSR loop is. |
207 LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone); | 244 LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone); |
208 | 245 |
209 Node* dead = jsgraph->DeadControl(); | 246 Node* dead = jsgraph->DeadControl(); |
210 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); | 247 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); |
211 if (loop->depth() > 0) { | 248 if (loop->depth() > 0) { |
212 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, | 249 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, |
213 osr_normal_entry, osr_loop_entry); | 250 osr_normal_entry, osr_loop_entry); |
214 } | 251 } |
215 | 252 |
(...skipping 24 matching lines...) Expand all Loading... |
240 // the first spill slots. | 277 // the first spill slots. |
241 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); | 278 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); |
242 // The frame needs to be adjusted by the number of unoptimized frame slots. | 279 // The frame needs to be adjusted by the number of unoptimized frame slots. |
243 frame->SetOsrStackSlotCount(static_cast<int>(UnoptimizedFrameSlots())); | 280 frame->SetOsrStackSlotCount(static_cast<int>(UnoptimizedFrameSlots())); |
244 } | 281 } |
245 | 282 |
246 | 283 |
247 } // namespace compiler | 284 } // namespace compiler |
248 } // namespace internal | 285 } // namespace internal |
249 } // namespace v8 | 286 } // namespace v8 |
OLD | NEW |