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/osr.h" | 5 #include "src/compiler/osr.h" |
6 #include "src/ast/scopes.h" | 6 #include "src/ast/scopes.h" |
7 #include "src/compilation-info.h" | 7 #include "src/compilation-info.h" |
8 #include "src/compiler/all-nodes.h" | 8 #include "src/compiler/all-nodes.h" |
9 #include "src/compiler/common-operator-reducer.h" | 9 #include "src/compiler/common-operator-reducer.h" |
10 #include "src/compiler/common-operator.h" | 10 #include "src/compiler/common-operator.h" |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 87 |
88 // Copy all nodes. | 88 // Copy all nodes. |
89 for (size_t i = 0; i < all.reachable.size(); i++) { | 89 for (size_t i = 0; i < all.reachable.size(); i++) { |
90 Node* orig = all.reachable[i]; | 90 Node* orig = all.reachable[i]; |
91 Node* copy = mapping->at(orig->id()); | 91 Node* copy = mapping->at(orig->id()); |
92 if (copy != sentinel) { | 92 if (copy != sentinel) { |
93 // Mapping already exists. | 93 // Mapping already exists. |
94 continue; | 94 continue; |
95 } | 95 } |
96 if (orig->InputCount() == 0 || orig->opcode() == IrOpcode::kParameter || | 96 if (orig->InputCount() == 0 || orig->opcode() == IrOpcode::kParameter || |
97 orig->opcode() == IrOpcode::kOsrValue || | 97 orig->opcode() == IrOpcode::kOsrValue) { |
98 orig->opcode() == IrOpcode::kOsrGuard) { | |
99 // No need to copy leaf nodes or parameters. | 98 // No need to copy leaf nodes or parameters. |
100 mapping->at(orig->id()) = orig; | 99 mapping->at(orig->id()) = orig; |
101 continue; | 100 continue; |
102 } | 101 } |
103 | 102 |
104 // Copy the node. | 103 // Copy the node. |
105 tmp_inputs.clear(); | 104 tmp_inputs.clear(); |
106 for (Node* input : orig->inputs()) { | 105 for (Node* input : orig->inputs()) { |
107 tmp_inputs.push_back(mapping->at(input->id())); | 106 tmp_inputs.push_back(mapping->at(input->id())); |
108 } | 107 } |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 } | 246 } |
248 } | 247 } |
249 | 248 |
250 if (FLAG_trace_turbo_graph) { // Simple textual RPO. | 249 if (FLAG_trace_turbo_graph) { // Simple textual RPO. |
251 OFStream os(stdout); | 250 OFStream os(stdout); |
252 os << "-- Graph after OSR duplication -- " << std::endl; | 251 os << "-- Graph after OSR duplication -- " << std::endl; |
253 os << AsRPO(*graph); | 252 os << AsRPO(*graph); |
254 } | 253 } |
255 } | 254 } |
256 | 255 |
257 void SetTypeForOsrValue(Node* osr_value, Node* loop, | |
258 CommonOperatorBuilder* common) { | |
259 Node* osr_guard = nullptr; | |
260 for (Node* use : osr_value->uses()) { | |
261 if (use->opcode() == IrOpcode::kOsrGuard) { | |
262 DCHECK_EQ(use->InputAt(0), osr_value); | |
263 osr_guard = use; | |
264 break; | |
265 } | |
266 } | |
267 | |
268 NodeProperties::ChangeOp(osr_guard, common->OsrGuard(OsrGuardType::kAny)); | |
269 } | |
270 | |
271 } // namespace | 256 } // namespace |
272 | 257 |
273 void OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, | 258 void OsrHelper::Deconstruct(JSGraph* jsgraph, CommonOperatorBuilder* common, |
274 Zone* tmp_zone) { | 259 Zone* tmp_zone) { |
275 Graph* graph = jsgraph->graph(); | 260 Graph* graph = jsgraph->graph(); |
276 Node* osr_normal_entry = nullptr; | 261 Node* osr_normal_entry = nullptr; |
277 Node* osr_loop_entry = nullptr; | 262 Node* osr_loop_entry = nullptr; |
278 Node* osr_loop = nullptr; | 263 Node* osr_loop = nullptr; |
279 | 264 |
280 for (Node* node : graph->start()->uses()) { | 265 for (Node* node : graph->start()->uses()) { |
281 if (node->opcode() == IrOpcode::kOsrLoopEntry) { | 266 if (node->opcode() == IrOpcode::kOsrLoopEntry) { |
282 osr_loop_entry = node; // found the OSR loop entry | 267 osr_loop_entry = node; // found the OSR loop entry |
283 } else if (node->opcode() == IrOpcode::kOsrNormalEntry) { | 268 } else if (node->opcode() == IrOpcode::kOsrNormalEntry) { |
284 osr_normal_entry = node; | 269 osr_normal_entry = node; |
285 } | 270 } |
286 } | 271 } |
287 | 272 |
288 CHECK_NOT_NULL(osr_normal_entry); // Should have found the OSR normal entry. | 273 CHECK_NOT_NULL(osr_normal_entry); // Should have found the OSR normal entry. |
289 CHECK_NOT_NULL(osr_loop_entry); // Should have found the OSR loop entry. | 274 CHECK_NOT_NULL(osr_loop_entry); // Should have found the OSR loop entry. |
290 | 275 |
291 for (Node* use : osr_loop_entry->uses()) { | 276 for (Node* use : osr_loop_entry->uses()) { |
292 if (use->opcode() == IrOpcode::kLoop) { | 277 if (use->opcode() == IrOpcode::kLoop) { |
293 CHECK(!osr_loop); // should be only one OSR loop. | 278 CHECK(!osr_loop); // should be only one OSR loop. |
294 osr_loop = use; // found the OSR loop. | 279 osr_loop = use; // found the OSR loop. |
295 } | 280 } |
296 } | 281 } |
297 | 282 |
298 CHECK(osr_loop); // Should have found the OSR loop. | 283 CHECK(osr_loop); // Should have found the OSR loop. |
299 | 284 |
300 for (Node* use : osr_loop_entry->uses()) { | |
301 if (use->opcode() == IrOpcode::kOsrValue) { | |
302 SetTypeForOsrValue(use, osr_loop, common); | |
303 } | |
304 } | |
305 | |
306 // Analyze the graph to determine how deeply nested the OSR loop is. | 285 // Analyze the graph to determine how deeply nested the OSR loop is. |
307 LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone); | 286 LoopTree* loop_tree = LoopFinder::BuildLoopTree(graph, tmp_zone); |
308 | 287 |
309 Node* dead = jsgraph->Dead(); | 288 Node* dead = jsgraph->Dead(); |
310 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); | 289 LoopTree::Loop* loop = loop_tree->ContainingLoop(osr_loop); |
311 if (loop->depth() > 0) { | 290 if (loop->depth() > 0) { |
312 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, | 291 PeelOuterLoopsForOsr(graph, common, tmp_zone, dead, loop_tree, loop, |
313 osr_normal_entry, osr_loop_entry); | 292 osr_normal_entry, osr_loop_entry); |
314 } | 293 } |
315 | 294 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 | 331 |
353 void OsrHelper::SetupFrame(Frame* frame) { | 332 void OsrHelper::SetupFrame(Frame* frame) { |
354 // The optimized frame will subsume the unoptimized frame. Do so by reserving | 333 // The optimized frame will subsume the unoptimized frame. Do so by reserving |
355 // the first spill slots. | 334 // the first spill slots. |
356 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); | 335 frame->ReserveSpillSlots(UnoptimizedFrameSlots()); |
357 } | 336 } |
358 | 337 |
359 } // namespace compiler | 338 } // namespace compiler |
360 } // namespace internal | 339 } // namespace internal |
361 } // namespace v8 | 340 } // namespace v8 |
OLD | NEW |