| 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 |