| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/scheduler.h" | 5 #include "src/compiler/scheduler.h" |
| 6 | 6 |
| 7 #include "src/bit-vector.h" | 7 #include "src/bit-vector.h" |
| 8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
| 9 #include "src/compiler/control-equivalence.h" | 9 #include "src/compiler/control-equivalence.h" |
| 10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 DCHECK(component_entry_); | 281 DCHECK(component_entry_); |
| 282 | 282 |
| 283 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { | 283 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { |
| 284 ConnectBlocks(*i); // Connect block to its predecessor/successors. | 284 ConnectBlocks(*i); // Connect block to its predecessor/successors. |
| 285 } | 285 } |
| 286 } | 286 } |
| 287 | 287 |
| 288 private: | 288 private: |
| 289 // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl. | 289 friend class ScheduleLateNodeVisitor; |
| 290 friend class Scheduler; | 290 friend class Scheduler; |
| 291 | 291 |
| 292 void FixNode(BasicBlock* block, Node* node) { | 292 void FixNode(BasicBlock* block, Node* node) { |
| 293 schedule_->AddNode(block, node); | 293 schedule_->AddNode(block, node); |
| 294 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 294 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void Queue(Node* node) { | 297 void Queue(Node* node) { |
| 298 // Mark the connected control nodes as they are queued. | 298 // Mark the connected control nodes as they are queued. |
| 299 if (!queued_.Get(node)) { | 299 if (!queued_.Get(node)) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 313 FixNode(schedule_->start(), node); | 313 FixNode(schedule_->start(), node); |
| 314 break; | 314 break; |
| 315 case IrOpcode::kLoop: | 315 case IrOpcode::kLoop: |
| 316 case IrOpcode::kMerge: | 316 case IrOpcode::kMerge: |
| 317 BuildBlockForNode(node); | 317 BuildBlockForNode(node); |
| 318 break; | 318 break; |
| 319 case IrOpcode::kBranch: | 319 case IrOpcode::kBranch: |
| 320 case IrOpcode::kSwitch: | 320 case IrOpcode::kSwitch: |
| 321 BuildBlocksForSuccessors(node); | 321 BuildBlocksForSuccessors(node); |
| 322 break; | 322 break; |
| 323 case IrOpcode::kCall: |
| 324 if (IsExceptionalCall(node)) { |
| 325 BuildBlocksForSuccessors(node); |
| 326 } |
| 327 break; |
| 323 default: | 328 default: |
| 324 break; | 329 break; |
| 325 } | 330 } |
| 326 } | 331 } |
| 327 | 332 |
| 328 void ConnectBlocks(Node* node) { | 333 void ConnectBlocks(Node* node) { |
| 329 switch (node->opcode()) { | 334 switch (node->opcode()) { |
| 330 case IrOpcode::kLoop: | 335 case IrOpcode::kLoop: |
| 331 case IrOpcode::kMerge: | 336 case IrOpcode::kMerge: |
| 332 ConnectMerge(node); | 337 ConnectMerge(node); |
| 333 break; | 338 break; |
| 334 case IrOpcode::kBranch: | 339 case IrOpcode::kBranch: |
| 335 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 340 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 336 ConnectBranch(node); | 341 ConnectBranch(node); |
| 337 break; | 342 break; |
| 338 case IrOpcode::kSwitch: | 343 case IrOpcode::kSwitch: |
| 339 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 344 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 340 ConnectSwitch(node); | 345 ConnectSwitch(node); |
| 341 break; | 346 break; |
| 342 case IrOpcode::kReturn: | 347 case IrOpcode::kReturn: |
| 343 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 348 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 344 ConnectReturn(node); | 349 ConnectReturn(node); |
| 345 break; | 350 break; |
| 346 case IrOpcode::kThrow: | 351 case IrOpcode::kThrow: |
| 347 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 352 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 348 ConnectThrow(node); | 353 ConnectThrow(node); |
| 349 break; | 354 break; |
| 355 case IrOpcode::kCall: |
| 356 if (IsExceptionalCall(node)) { |
| 357 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 358 ConnectCall(node); |
| 359 } |
| 360 break; |
| 350 default: | 361 default: |
| 351 break; | 362 break; |
| 352 } | 363 } |
| 353 } | 364 } |
| 354 | 365 |
| 355 BasicBlock* BuildBlockForNode(Node* node) { | 366 BasicBlock* BuildBlockForNode(Node* node) { |
| 356 BasicBlock* block = schedule_->block(node); | 367 BasicBlock* block = schedule_->block(node); |
| 357 if (block == NULL) { | 368 if (block == NULL) { |
| 358 block = schedule_->NewBasicBlock(); | 369 block = schedule_->NewBasicBlock(); |
| 359 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), | 370 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), |
| (...skipping 14 matching lines...) Expand all Loading... |
| 374 | 385 |
| 375 void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks, | 386 void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks, |
| 376 size_t successor_cnt) { | 387 size_t successor_cnt) { |
| 377 Node** successors = reinterpret_cast<Node**>(successor_blocks); | 388 Node** successors = reinterpret_cast<Node**>(successor_blocks); |
| 378 NodeProperties::CollectControlProjections(node, successors, successor_cnt); | 389 NodeProperties::CollectControlProjections(node, successors, successor_cnt); |
| 379 for (size_t index = 0; index < successor_cnt; ++index) { | 390 for (size_t index = 0; index < successor_cnt; ++index) { |
| 380 successor_blocks[index] = schedule_->block(successors[index]); | 391 successor_blocks[index] = schedule_->block(successors[index]); |
| 381 } | 392 } |
| 382 } | 393 } |
| 383 | 394 |
| 395 BasicBlock* FindPredecessorBlock(Node* node) { |
| 396 BasicBlock* predecessor_block = nullptr; |
| 397 while (true) { |
| 398 predecessor_block = schedule_->block(node); |
| 399 if (predecessor_block != nullptr) break; |
| 400 node = NodeProperties::GetControlInput(node); |
| 401 } |
| 402 return predecessor_block; |
| 403 } |
| 404 |
| 405 void ConnectCall(Node* call) { |
| 406 BasicBlock* successor_blocks[2]; |
| 407 CollectSuccessorBlocks(call, successor_blocks, arraysize(successor_blocks)); |
| 408 |
| 409 // Consider the exception continuation to be deferred. |
| 410 successor_blocks[1]->set_deferred(true); |
| 411 |
| 412 Node* call_control = NodeProperties::GetControlInput(call); |
| 413 BasicBlock* call_block = FindPredecessorBlock(call_control); |
| 414 TraceConnect(call, call_block, successor_blocks[0]); |
| 415 TraceConnect(call, call_block, successor_blocks[1]); |
| 416 schedule_->AddCall(call_block, call, successor_blocks[0], |
| 417 successor_blocks[1]); |
| 418 } |
| 419 |
| 384 void ConnectBranch(Node* branch) { | 420 void ConnectBranch(Node* branch) { |
| 385 BasicBlock* successor_blocks[2]; | 421 BasicBlock* successor_blocks[2]; |
| 386 CollectSuccessorBlocks(branch, successor_blocks, | 422 CollectSuccessorBlocks(branch, successor_blocks, |
| 387 arraysize(successor_blocks)); | 423 arraysize(successor_blocks)); |
| 388 | 424 |
| 389 // Consider branch hints. | 425 // Consider branch hints. |
| 390 switch (BranchHintOf(branch->op())) { | 426 switch (BranchHintOf(branch->op())) { |
| 391 case BranchHint::kNone: | 427 case BranchHint::kNone: |
| 392 break; | 428 break; |
| 393 case BranchHint::kTrue: | 429 case BranchHint::kTrue: |
| 394 successor_blocks[1]->set_deferred(true); | 430 successor_blocks[1]->set_deferred(true); |
| 395 break; | 431 break; |
| 396 case BranchHint::kFalse: | 432 case BranchHint::kFalse: |
| 397 successor_blocks[0]->set_deferred(true); | 433 successor_blocks[0]->set_deferred(true); |
| 398 break; | 434 break; |
| 399 } | 435 } |
| 400 | 436 |
| 401 if (branch == component_entry_) { | 437 if (branch == component_entry_) { |
| 402 TraceConnect(branch, component_start_, successor_blocks[0]); | 438 TraceConnect(branch, component_start_, successor_blocks[0]); |
| 403 TraceConnect(branch, component_start_, successor_blocks[1]); | 439 TraceConnect(branch, component_start_, successor_blocks[1]); |
| 404 schedule_->InsertBranch(component_start_, component_end_, branch, | 440 schedule_->InsertBranch(component_start_, component_end_, branch, |
| 405 successor_blocks[0], successor_blocks[1]); | 441 successor_blocks[0], successor_blocks[1]); |
| 406 } else { | 442 } else { |
| 407 Node* branch_block_node = NodeProperties::GetControlInput(branch); | 443 Node* branch_control = NodeProperties::GetControlInput(branch); |
| 408 BasicBlock* branch_block = schedule_->block(branch_block_node); | 444 BasicBlock* branch_block = FindPredecessorBlock(branch_control); |
| 409 DCHECK_NOT_NULL(branch_block); | |
| 410 | |
| 411 TraceConnect(branch, branch_block, successor_blocks[0]); | 445 TraceConnect(branch, branch_block, successor_blocks[0]); |
| 412 TraceConnect(branch, branch_block, successor_blocks[1]); | 446 TraceConnect(branch, branch_block, successor_blocks[1]); |
| 413 schedule_->AddBranch(branch_block, branch, successor_blocks[0], | 447 schedule_->AddBranch(branch_block, branch, successor_blocks[0], |
| 414 successor_blocks[1]); | 448 successor_blocks[1]); |
| 415 } | 449 } |
| 416 } | 450 } |
| 417 | 451 |
| 418 void ConnectSwitch(Node* sw) { | 452 void ConnectSwitch(Node* sw) { |
| 419 size_t const successor_count = sw->op()->ControlOutputCount(); | 453 size_t const successor_count = sw->op()->ControlOutputCount(); |
| 420 BasicBlock** successor_blocks = | 454 BasicBlock** successor_blocks = |
| 421 zone_->NewArray<BasicBlock*>(successor_count); | 455 zone_->NewArray<BasicBlock*>(successor_count); |
| 422 CollectSuccessorBlocks(sw, successor_blocks, successor_count); | 456 CollectSuccessorBlocks(sw, successor_blocks, successor_count); |
| 423 | 457 |
| 424 if (sw == component_entry_) { | 458 if (sw == component_entry_) { |
| 425 for (size_t index = 0; index < successor_count; ++index) { | 459 for (size_t index = 0; index < successor_count; ++index) { |
| 426 TraceConnect(sw, component_start_, successor_blocks[index]); | 460 TraceConnect(sw, component_start_, successor_blocks[index]); |
| 427 } | 461 } |
| 428 schedule_->InsertSwitch(component_start_, component_end_, sw, | 462 schedule_->InsertSwitch(component_start_, component_end_, sw, |
| 429 successor_blocks, successor_count); | 463 successor_blocks, successor_count); |
| 430 } else { | 464 } else { |
| 431 Node* sw_block_node = NodeProperties::GetControlInput(sw); | 465 Node* switch_control = NodeProperties::GetControlInput(sw); |
| 432 BasicBlock* sw_block = schedule_->block(sw_block_node); | 466 BasicBlock* switch_block = FindPredecessorBlock(switch_control); |
| 433 DCHECK_NOT_NULL(sw_block); | |
| 434 | |
| 435 for (size_t index = 0; index < successor_count; ++index) { | 467 for (size_t index = 0; index < successor_count; ++index) { |
| 436 TraceConnect(sw, sw_block, successor_blocks[index]); | 468 TraceConnect(sw, switch_block, successor_blocks[index]); |
| 437 } | 469 } |
| 438 schedule_->AddSwitch(sw_block, sw, successor_blocks, successor_count); | 470 schedule_->AddSwitch(switch_block, sw, successor_blocks, successor_count); |
| 439 } | 471 } |
| 440 } | 472 } |
| 441 | 473 |
| 442 void ConnectMerge(Node* merge) { | 474 void ConnectMerge(Node* merge) { |
| 443 // Don't connect the special merge at the end to its predecessors. | 475 // Don't connect the special merge at the end to its predecessors. |
| 444 if (IsFinalMerge(merge)) return; | 476 if (IsFinalMerge(merge)) return; |
| 445 | 477 |
| 446 BasicBlock* block = schedule_->block(merge); | 478 BasicBlock* block = schedule_->block(merge); |
| 447 DCHECK_NOT_NULL(block); | 479 DCHECK_NOT_NULL(block); |
| 448 // For all of the merge's control inputs, add a goto at the end to the | 480 // For all of the merge's control inputs, add a goto at the end to the |
| 449 // merge's basic block. | 481 // merge's basic block. |
| 450 for (Node* const input : merge->inputs()) { | 482 for (Node* const input : merge->inputs()) { |
| 451 BasicBlock* predecessor_block = schedule_->block(input); | 483 BasicBlock* predecessor_block = FindPredecessorBlock(input); |
| 452 TraceConnect(merge, predecessor_block, block); | 484 TraceConnect(merge, predecessor_block, block); |
| 453 schedule_->AddGoto(predecessor_block, block); | 485 schedule_->AddGoto(predecessor_block, block); |
| 454 } | 486 } |
| 455 } | 487 } |
| 456 | 488 |
| 457 void ConnectReturn(Node* ret) { | 489 void ConnectReturn(Node* ret) { |
| 458 Node* return_block_node = NodeProperties::GetControlInput(ret); | 490 Node* return_control = NodeProperties::GetControlInput(ret); |
| 459 BasicBlock* return_block = schedule_->block(return_block_node); | 491 BasicBlock* return_block = FindPredecessorBlock(return_control); |
| 460 TraceConnect(ret, return_block, NULL); | 492 TraceConnect(ret, return_block, NULL); |
| 461 schedule_->AddReturn(return_block, ret); | 493 schedule_->AddReturn(return_block, ret); |
| 462 } | 494 } |
| 463 | 495 |
| 464 void ConnectThrow(Node* thr) { | 496 void ConnectThrow(Node* thr) { |
| 465 Node* throw_block_node = NodeProperties::GetControlInput(thr); | 497 Node* throw_control = NodeProperties::GetControlInput(thr); |
| 466 BasicBlock* throw_block = schedule_->block(throw_block_node); | 498 BasicBlock* throw_block = FindPredecessorBlock(throw_control); |
| 467 TraceConnect(thr, throw_block, NULL); | 499 TraceConnect(thr, throw_block, NULL); |
| 468 schedule_->AddThrow(throw_block, thr); | 500 schedule_->AddThrow(throw_block, thr); |
| 469 } | 501 } |
| 470 | 502 |
| 471 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { | 503 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { |
| 472 DCHECK_NOT_NULL(block); | 504 DCHECK_NOT_NULL(block); |
| 473 if (succ == NULL) { | 505 if (succ == NULL) { |
| 474 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(), | 506 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(), |
| 475 block->id().ToInt()); | 507 block->id().ToInt()); |
| 476 } else { | 508 } else { |
| 477 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(), | 509 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(), |
| 478 block->id().ToInt(), succ->id().ToInt()); | 510 block->id().ToInt(), succ->id().ToInt()); |
| 479 } | 511 } |
| 480 } | 512 } |
| 481 | 513 |
| 514 bool IsExceptionalCall(Node* node) { |
| 515 for (Node* const use : node->uses()) { |
| 516 if (use->opcode() == IrOpcode::kIfException) return true; |
| 517 } |
| 518 return false; |
| 519 } |
| 520 |
| 482 bool IsFinalMerge(Node* node) { | 521 bool IsFinalMerge(Node* node) { |
| 483 return (node->opcode() == IrOpcode::kMerge && | 522 return (node->opcode() == IrOpcode::kMerge && |
| 484 node == scheduler_->graph_->end()->InputAt(0)); | 523 node == scheduler_->graph_->end()->InputAt(0)); |
| 485 } | 524 } |
| 486 | 525 |
| 487 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const { | 526 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const { |
| 488 size_t entry_class = scheduler_->equivalence_->ClassOf(entry); | 527 size_t entry_class = scheduler_->equivalence_->ClassOf(entry); |
| 489 size_t exit_class = scheduler_->equivalence_->ClassOf(exit); | 528 size_t exit_class = scheduler_->equivalence_->ClassOf(exit); |
| 490 return entry != exit && entry_class == exit_class; | 529 return entry != exit && entry_class == exit_class; |
| 491 } | 530 } |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1317 block = hoist_block; | 1356 block = hoist_block; |
| 1318 hoist_block = GetPreHeader(hoist_block); | 1357 hoist_block = GetPreHeader(hoist_block); |
| 1319 } while (hoist_block && | 1358 } while (hoist_block && |
| 1320 hoist_block->dominator_depth() >= min_block->dominator_depth()); | 1359 hoist_block->dominator_depth() >= min_block->dominator_depth()); |
| 1321 } else if (scheduler_->flags_ & Scheduler::kSplitNodes) { | 1360 } else if (scheduler_->flags_ & Scheduler::kSplitNodes) { |
| 1322 // Split the {node} if beneficial and return the new {block} for it. | 1361 // Split the {node} if beneficial and return the new {block} for it. |
| 1323 block = SplitNode(block, node); | 1362 block = SplitNode(block, node); |
| 1324 } | 1363 } |
| 1325 | 1364 |
| 1326 // Schedule the node or a floating control structure. | 1365 // Schedule the node or a floating control structure. |
| 1327 if (NodeProperties::IsControl(node)) { | 1366 if (IrOpcode::IsMergeOpcode(node->opcode())) { |
| 1328 ScheduleFloatingControl(block, node); | 1367 ScheduleFloatingControl(block, node); |
| 1329 } else { | 1368 } else { |
| 1330 ScheduleNode(block, node); | 1369 ScheduleNode(block, node); |
| 1331 } | 1370 } |
| 1332 } | 1371 } |
| 1333 | 1372 |
| 1334 // Mark {block} and push its non-marked predecessor on the marking queue. | 1373 // Mark {block} and push its non-marked predecessor on the marking queue. |
| 1335 void MarkBlock(BasicBlock* block) { | 1374 void MarkBlock(BasicBlock* block) { |
| 1336 DCHECK_LT(block->id().ToSize(), marked_.size()); | 1375 DCHECK_LT(block->id().ToSize(), marked_.size()); |
| 1337 marked_[block->id().ToSize()] = true; | 1376 marked_[block->id().ToSize()] = true; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 for (Edge edge : node->use_edges()) { | 1480 for (Edge edge : node->use_edges()) { |
| 1442 BasicBlock* use_block = GetBlockForUse(edge); | 1481 BasicBlock* use_block = GetBlockForUse(edge); |
| 1443 block = block == NULL ? use_block : use_block == NULL | 1482 block = block == NULL ? use_block : use_block == NULL |
| 1444 ? block | 1483 ? block |
| 1445 : BasicBlock::GetCommonDominator( | 1484 : BasicBlock::GetCommonDominator( |
| 1446 block, use_block); | 1485 block, use_block); |
| 1447 } | 1486 } |
| 1448 return block; | 1487 return block; |
| 1449 } | 1488 } |
| 1450 | 1489 |
| 1490 BasicBlock* FindPredecessorBlock(Node* node) { |
| 1491 return scheduler_->control_flow_builder_->FindPredecessorBlock(node); |
| 1492 } |
| 1493 |
| 1451 BasicBlock* GetBlockForUse(Edge edge) { | 1494 BasicBlock* GetBlockForUse(Edge edge) { |
| 1452 Node* use = edge.from(); | 1495 Node* use = edge.from(); |
| 1453 IrOpcode::Value opcode = use->opcode(); | 1496 if (IrOpcode::IsPhiOpcode(use->opcode())) { |
| 1454 if (IrOpcode::IsPhiOpcode(opcode)) { | |
| 1455 // If the use is from a coupled (i.e. floating) phi, compute the common | 1497 // If the use is from a coupled (i.e. floating) phi, compute the common |
| 1456 // dominator of its uses. This will not recurse more than one level. | 1498 // dominator of its uses. This will not recurse more than one level. |
| 1457 if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) { | 1499 if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) { |
| 1458 Trace(" inspecting uses of coupled #%d:%s\n", use->id(), | 1500 Trace(" inspecting uses of coupled #%d:%s\n", use->id(), |
| 1459 use->op()->mnemonic()); | 1501 use->op()->mnemonic()); |
| 1460 DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use)); | 1502 DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use)); |
| 1461 return GetCommonDominatorOfUses(use); | 1503 return GetCommonDominatorOfUses(use); |
| 1462 } | 1504 } |
| 1463 // If the use is from a fixed (i.e. non-floating) phi, use the block | 1505 // If the use is from a fixed (i.e. non-floating) phi, we use the |
| 1464 // of the corresponding control input to the merge. | 1506 // predecessor block of the corresponding control input to the merge. |
| 1465 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) { | 1507 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) { |
| 1466 Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(), | 1508 Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(), |
| 1467 use->op()->mnemonic()); | 1509 use->op()->mnemonic()); |
| 1468 Node* merge = NodeProperties::GetControlInput(use, 0); | 1510 Node* merge = NodeProperties::GetControlInput(use, 0); |
| 1469 opcode = merge->opcode(); | 1511 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); |
| 1470 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop); | 1512 Node* input = NodeProperties::GetControlInput(merge, edge.index()); |
| 1471 use = NodeProperties::GetControlInput(merge, edge.index()); | 1513 return FindPredecessorBlock(input); |
| 1514 } |
| 1515 } else if (IrOpcode::IsMergeOpcode(use->opcode())) { |
| 1516 // If the use is from a fixed (i.e. non-floating) merge, we use the |
| 1517 // predecessor block of the current input to the merge. |
| 1518 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) { |
| 1519 Trace(" input@%d into a fixed merge #%d:%s\n", edge.index(), use->id(), |
| 1520 use->op()->mnemonic()); |
| 1521 return FindPredecessorBlock(edge.to()); |
| 1472 } | 1522 } |
| 1473 } | 1523 } |
| 1474 BasicBlock* result = schedule_->block(use); | 1524 BasicBlock* result = schedule_->block(use); |
| 1475 if (result == NULL) return NULL; | 1525 if (result == NULL) return NULL; |
| 1476 Trace(" must dominate use #%d:%s in B%d\n", use->id(), | 1526 Trace(" must dominate use #%d:%s in B%d\n", use->id(), |
| 1477 use->op()->mnemonic(), result->id().ToInt()); | 1527 use->op()->mnemonic(), result->id().ToInt()); |
| 1478 return result; | 1528 return result; |
| 1479 } | 1529 } |
| 1480 | 1530 |
| 1481 void ScheduleFloatingControl(BasicBlock* block, Node* node) { | 1531 void ScheduleFloatingControl(BasicBlock* block, Node* node) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1610 for (Node* const node : *nodes) { | 1660 for (Node* const node : *nodes) { |
| 1611 schedule_->SetBlockForNode(to, node); | 1661 schedule_->SetBlockForNode(to, node); |
| 1612 scheduled_nodes_[to->id().ToSize()].push_back(node); | 1662 scheduled_nodes_[to->id().ToSize()].push_back(node); |
| 1613 } | 1663 } |
| 1614 nodes->clear(); | 1664 nodes->clear(); |
| 1615 } | 1665 } |
| 1616 | 1666 |
| 1617 } // namespace compiler | 1667 } // namespace compiler |
| 1618 } // namespace internal | 1668 } // namespace internal |
| 1619 } // namespace v8 | 1669 } // namespace v8 |
| OLD | NEW |