Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: src/compiler/scheduler.cc

Issue 928213003: Model exceptional edges from call nodes in TurboFan. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments by Benedikt Meurer. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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)) break;
titzer 2015/02/17 10:32:52 Flip condition?
Michael Starzinger 2015/02/17 10:58:30 Done.
325 BuildBlocksForSuccessors(node);
326 break;
323 default: 327 default:
324 break; 328 break;
325 } 329 }
326 } 330 }
327 331
328 void ConnectBlocks(Node* node) { 332 void ConnectBlocks(Node* node) {
329 switch (node->opcode()) { 333 switch (node->opcode()) {
330 case IrOpcode::kLoop: 334 case IrOpcode::kLoop:
331 case IrOpcode::kMerge: 335 case IrOpcode::kMerge:
332 ConnectMerge(node); 336 ConnectMerge(node);
333 break; 337 break;
334 case IrOpcode::kBranch: 338 case IrOpcode::kBranch:
335 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 339 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
336 ConnectBranch(node); 340 ConnectBranch(node);
337 break; 341 break;
338 case IrOpcode::kSwitch: 342 case IrOpcode::kSwitch:
339 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 343 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
340 ConnectSwitch(node); 344 ConnectSwitch(node);
341 break; 345 break;
342 case IrOpcode::kReturn: 346 case IrOpcode::kReturn:
343 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 347 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
344 ConnectReturn(node); 348 ConnectReturn(node);
345 break; 349 break;
346 case IrOpcode::kThrow: 350 case IrOpcode::kThrow:
347 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 351 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
348 ConnectThrow(node); 352 ConnectThrow(node);
349 break; 353 break;
354 case IrOpcode::kCall:
355 if (!IsExceptionalCall(node)) break;
titzer 2015/02/17 10:32:52 Same.
Michael Starzinger 2015/02/17 10:58:29 Done.
356 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
357 ConnectCall(node);
358 break;
350 default: 359 default:
351 break; 360 break;
352 } 361 }
353 } 362 }
354 363
355 BasicBlock* BuildBlockForNode(Node* node) { 364 BasicBlock* BuildBlockForNode(Node* node) {
356 BasicBlock* block = schedule_->block(node); 365 BasicBlock* block = schedule_->block(node);
357 if (block == NULL) { 366 if (block == NULL) {
358 block = schedule_->NewBasicBlock(); 367 block = schedule_->NewBasicBlock();
359 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), 368 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(),
360 node->op()->mnemonic()); 369 node->op()->mnemonic());
361 FixNode(block, node); 370 FixNode(block, node);
362 } 371 }
363 return block; 372 return block;
364 } 373 }
365 374
366 void BuildBlocksForSuccessors(Node* node) { 375 void BuildBlocksForSuccessors(Node* node) {
367 size_t const successor_count = node->op()->ControlOutputCount(); 376 size_t const successor_count = node->op()->ControlOutputCount();
368 Node** successors = zone_->NewArray<Node*>(successor_count); 377 Node** successors = zone_->NewArray<Node*>(successor_count);
369 CollectSuccessorProjections(node, successors, successor_count); 378 CollectSuccessorProjections(node, successors, successor_count);
370 for (size_t index = 0; index < successor_count; ++index) { 379 for (size_t index = 0; index < successor_count; ++index) {
371 BuildBlockForNode(successors[index]); 380 BuildBlockForNode(successors[index]);
372 } 381 }
373 } 382 }
374 383
375 // Collect the branch-related projections from a node, such as IfTrue, 384 // Collect the branch-related projections from a node, such as IfTrue,
376 // IfFalse, and Case. 385 // IfFalse, IfException, IfSuccess, and Case.
377 void CollectSuccessorProjections(Node* node, Node** successors, 386 void CollectSuccessorProjections(Node* node, Node** successors,
378 size_t successor_count) { 387 size_t successor_count) {
379 #ifdef DEBUG 388 #ifdef DEBUG
380 DCHECK_EQ(static_cast<int>(successor_count), node->UseCount()); 389 DCHECK_LE(static_cast<int>(successor_count), node->UseCount());
381 std::memset(successors, 0, sizeof(*successors) * successor_count); 390 std::memset(successors, 0, sizeof(*successors) * successor_count);
382 #endif 391 #endif
383 for (Node* const use : node->uses()) { 392 for (Node* const use : node->uses()) {
384 size_t index; 393 size_t index;
385 switch (use->opcode()) { 394 switch (use->opcode()) {
386 default:
387 UNREACHABLE();
388 // Fall through.
389 case IrOpcode::kIfTrue: 395 case IrOpcode::kIfTrue:
390 DCHECK_EQ(IrOpcode::kBranch, node->opcode()); 396 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
391 index = 0; 397 index = 0;
392 break; 398 break;
393 case IrOpcode::kIfFalse: 399 case IrOpcode::kIfFalse:
394 DCHECK_EQ(IrOpcode::kBranch, node->opcode()); 400 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
395 index = 1; 401 index = 1;
396 break; 402 break;
403 case IrOpcode::kIfException:
404 DCHECK_EQ(IrOpcode::kCall, node->opcode());
405 index = 1;
406 break;
407 case IrOpcode::kIfSuccess:
408 DCHECK_EQ(IrOpcode::kCall, node->opcode());
409 index = 0;
410 break;
397 case IrOpcode::kCase: 411 case IrOpcode::kCase:
398 DCHECK_EQ(IrOpcode::kSwitch, node->opcode()); 412 DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
399 index = CaseIndexOf(use->op()); 413 index = CaseIndexOf(use->op());
400 break; 414 break;
415 default:
416 continue;
401 } 417 }
402 DCHECK_LT(index, successor_count); 418 DCHECK_LT(index, successor_count);
403 DCHECK(successors[index] == nullptr); 419 DCHECK(successors[index] == nullptr);
404 successors[index] = use; 420 successors[index] = use;
405 } 421 }
406 #ifdef DEBUG 422 #ifdef DEBUG
407 for (size_t index = 0; index < successor_count; ++index) { 423 for (size_t index = 0; index < successor_count; ++index) {
408 DCHECK_NOT_NULL(successors[index]); 424 DCHECK_NOT_NULL(successors[index]);
409 } 425 }
410 #endif 426 #endif
411 } 427 }
412 428
413 void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks, 429 void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks,
414 size_t successor_count) { 430 size_t successor_count) {
415 Node** successors = reinterpret_cast<Node**>(successor_blocks); 431 Node** successors = reinterpret_cast<Node**>(successor_blocks);
416 CollectSuccessorProjections(node, successors, successor_count); 432 CollectSuccessorProjections(node, successors, successor_count);
417 for (size_t index = 0; index < successor_count; ++index) { 433 for (size_t index = 0; index < successor_count; ++index) {
418 successor_blocks[index] = schedule_->block(successors[index]); 434 successor_blocks[index] = schedule_->block(successors[index]);
419 } 435 }
420 } 436 }
421 437
438 BasicBlock* FindPredecessorBlock(Node* node) {
439 BasicBlock* predecessor_block = nullptr;
440 while (true) {
441 predecessor_block = schedule_->block(node);
442 if (predecessor_block != nullptr) break;
443 node = NodeProperties::GetControlInput(node);
444 }
445 return predecessor_block;
446 }
447
448 void ConnectCall(Node* call) {
449 BasicBlock* successor_blocks[2];
450 CollectSuccessorBlocks(call, successor_blocks, arraysize(successor_blocks));
451
452 // Consider the exception continuation to be deferred.
453 successor_blocks[1]->set_deferred(true);
454
455 Node* call_control = NodeProperties::GetControlInput(call);
456 BasicBlock* call_block = FindPredecessorBlock(call_control);
457 TraceConnect(call, call_block, successor_blocks[0]);
458 TraceConnect(call, call_block, successor_blocks[1]);
459 schedule_->AddCall(call_block, call, successor_blocks[0],
460 successor_blocks[1]);
461 }
462
422 void ConnectBranch(Node* branch) { 463 void ConnectBranch(Node* branch) {
423 BasicBlock* successor_blocks[2]; 464 BasicBlock* successor_blocks[2];
424 CollectSuccessorBlocks(branch, successor_blocks, 465 CollectSuccessorBlocks(branch, successor_blocks,
425 arraysize(successor_blocks)); 466 arraysize(successor_blocks));
426 467
427 // Consider branch hints. 468 // Consider branch hints.
428 switch (BranchHintOf(branch->op())) { 469 switch (BranchHintOf(branch->op())) {
429 case BranchHint::kNone: 470 case BranchHint::kNone:
430 break; 471 break;
431 case BranchHint::kTrue: 472 case BranchHint::kTrue:
432 successor_blocks[1]->set_deferred(true); 473 successor_blocks[1]->set_deferred(true);
433 break; 474 break;
434 case BranchHint::kFalse: 475 case BranchHint::kFalse:
435 successor_blocks[0]->set_deferred(true); 476 successor_blocks[0]->set_deferred(true);
436 break; 477 break;
437 } 478 }
438 479
439 if (branch == component_entry_) { 480 if (branch == component_entry_) {
440 TraceConnect(branch, component_start_, successor_blocks[0]); 481 TraceConnect(branch, component_start_, successor_blocks[0]);
441 TraceConnect(branch, component_start_, successor_blocks[1]); 482 TraceConnect(branch, component_start_, successor_blocks[1]);
442 schedule_->InsertBranch(component_start_, component_end_, branch, 483 schedule_->InsertBranch(component_start_, component_end_, branch,
443 successor_blocks[0], successor_blocks[1]); 484 successor_blocks[0], successor_blocks[1]);
444 } else { 485 } else {
445 Node* branch_block_node = NodeProperties::GetControlInput(branch); 486 Node* branch_control = NodeProperties::GetControlInput(branch);
446 BasicBlock* branch_block = schedule_->block(branch_block_node); 487 BasicBlock* branch_block = FindPredecessorBlock(branch_control);
447 DCHECK_NOT_NULL(branch_block);
448
449 TraceConnect(branch, branch_block, successor_blocks[0]); 488 TraceConnect(branch, branch_block, successor_blocks[0]);
450 TraceConnect(branch, branch_block, successor_blocks[1]); 489 TraceConnect(branch, branch_block, successor_blocks[1]);
451 schedule_->AddBranch(branch_block, branch, successor_blocks[0], 490 schedule_->AddBranch(branch_block, branch, successor_blocks[0],
452 successor_blocks[1]); 491 successor_blocks[1]);
453 } 492 }
454 } 493 }
455 494
456 void ConnectSwitch(Node* sw) { 495 void ConnectSwitch(Node* sw) {
457 size_t const successor_count = sw->op()->ControlOutputCount(); 496 size_t const successor_count = sw->op()->ControlOutputCount();
458 BasicBlock** successor_blocks = 497 BasicBlock** successor_blocks =
459 zone_->NewArray<BasicBlock*>(successor_count); 498 zone_->NewArray<BasicBlock*>(successor_count);
460 CollectSuccessorBlocks(sw, successor_blocks, successor_count); 499 CollectSuccessorBlocks(sw, successor_blocks, successor_count);
461 500
462 if (sw == component_entry_) { 501 if (sw == component_entry_) {
463 for (size_t index = 0; index < successor_count; ++index) { 502 for (size_t index = 0; index < successor_count; ++index) {
464 TraceConnect(sw, component_start_, successor_blocks[index]); 503 TraceConnect(sw, component_start_, successor_blocks[index]);
465 } 504 }
466 schedule_->InsertSwitch(component_start_, component_end_, sw, 505 schedule_->InsertSwitch(component_start_, component_end_, sw,
467 successor_blocks, successor_count); 506 successor_blocks, successor_count);
468 } else { 507 } else {
469 Node* sw_block_node = NodeProperties::GetControlInput(sw); 508 Node* switch_control = NodeProperties::GetControlInput(sw);
470 BasicBlock* sw_block = schedule_->block(sw_block_node); 509 BasicBlock* switch_block = FindPredecessorBlock(switch_control);
471 DCHECK_NOT_NULL(sw_block);
472
473 for (size_t index = 0; index < successor_count; ++index) { 510 for (size_t index = 0; index < successor_count; ++index) {
474 TraceConnect(sw, sw_block, successor_blocks[index]); 511 TraceConnect(sw, switch_block, successor_blocks[index]);
475 } 512 }
476 schedule_->AddSwitch(sw_block, sw, successor_blocks, successor_count); 513 schedule_->AddSwitch(switch_block, sw, successor_blocks, successor_count);
477 } 514 }
478 } 515 }
479 516
480 void ConnectMerge(Node* merge) { 517 void ConnectMerge(Node* merge) {
481 // Don't connect the special merge at the end to its predecessors. 518 // Don't connect the special merge at the end to its predecessors.
482 if (IsFinalMerge(merge)) return; 519 if (IsFinalMerge(merge)) return;
483 520
484 BasicBlock* block = schedule_->block(merge); 521 BasicBlock* block = schedule_->block(merge);
485 DCHECK_NOT_NULL(block); 522 DCHECK_NOT_NULL(block);
486 // For all of the merge's control inputs, add a goto at the end to the 523 // For all of the merge's control inputs, add a goto at the end to the
487 // merge's basic block. 524 // merge's basic block.
488 for (Node* const input : merge->inputs()) { 525 for (Node* const input : merge->inputs()) {
489 BasicBlock* predecessor_block = schedule_->block(input); 526 BasicBlock* predecessor_block = FindPredecessorBlock(input);
490 TraceConnect(merge, predecessor_block, block); 527 TraceConnect(merge, predecessor_block, block);
491 schedule_->AddGoto(predecessor_block, block); 528 schedule_->AddGoto(predecessor_block, block);
492 } 529 }
493 } 530 }
494 531
495 void ConnectReturn(Node* ret) { 532 void ConnectReturn(Node* ret) {
496 Node* return_block_node = NodeProperties::GetControlInput(ret); 533 Node* return_control = NodeProperties::GetControlInput(ret);
497 BasicBlock* return_block = schedule_->block(return_block_node); 534 BasicBlock* return_block = FindPredecessorBlock(return_control);
498 TraceConnect(ret, return_block, NULL); 535 TraceConnect(ret, return_block, NULL);
499 schedule_->AddReturn(return_block, ret); 536 schedule_->AddReturn(return_block, ret);
500 } 537 }
501 538
502 void ConnectThrow(Node* thr) { 539 void ConnectThrow(Node* thr) {
503 Node* throw_block_node = NodeProperties::GetControlInput(thr); 540 Node* throw_control = NodeProperties::GetControlInput(thr);
504 BasicBlock* throw_block = schedule_->block(throw_block_node); 541 BasicBlock* throw_block = FindPredecessorBlock(throw_control);
505 TraceConnect(thr, throw_block, NULL); 542 TraceConnect(thr, throw_block, NULL);
506 schedule_->AddThrow(throw_block, thr); 543 schedule_->AddThrow(throw_block, thr);
507 } 544 }
508 545
509 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { 546 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
510 DCHECK_NOT_NULL(block); 547 DCHECK_NOT_NULL(block);
511 if (succ == NULL) { 548 if (succ == NULL) {
512 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(), 549 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
513 block->id().ToInt()); 550 block->id().ToInt());
514 } else { 551 } else {
515 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(), 552 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
516 block->id().ToInt(), succ->id().ToInt()); 553 block->id().ToInt(), succ->id().ToInt());
517 } 554 }
518 } 555 }
519 556
557 bool IsExceptionalCall(Node* node) {
558 for (Node* const use : node->uses()) {
559 if (use->opcode() == IrOpcode::kIfException) return true;
560 }
561 return false;
562 }
563
520 bool IsFinalMerge(Node* node) { 564 bool IsFinalMerge(Node* node) {
521 return (node->opcode() == IrOpcode::kMerge && 565 return (node->opcode() == IrOpcode::kMerge &&
522 node == scheduler_->graph_->end()->InputAt(0)); 566 node == scheduler_->graph_->end()->InputAt(0));
523 } 567 }
524 568
525 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const { 569 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const {
526 size_t entry_class = scheduler_->equivalence_->ClassOf(entry); 570 size_t entry_class = scheduler_->equivalence_->ClassOf(entry);
527 size_t exit_class = scheduler_->equivalence_->ClassOf(exit); 571 size_t exit_class = scheduler_->equivalence_->ClassOf(exit);
528 return entry != exit && entry_class == exit_class; 572 return entry != exit && entry_class == exit_class;
529 } 573 }
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 block = hoist_block; 1399 block = hoist_block;
1356 hoist_block = GetPreHeader(hoist_block); 1400 hoist_block = GetPreHeader(hoist_block);
1357 } while (hoist_block && 1401 } while (hoist_block &&
1358 hoist_block->dominator_depth() >= min_block->dominator_depth()); 1402 hoist_block->dominator_depth() >= min_block->dominator_depth());
1359 } else if (scheduler_->flags_ & Scheduler::kSplitNodes) { 1403 } else if (scheduler_->flags_ & Scheduler::kSplitNodes) {
1360 // Split the {node} if beneficial and return the new {block} for it. 1404 // Split the {node} if beneficial and return the new {block} for it.
1361 block = SplitNode(block, node); 1405 block = SplitNode(block, node);
1362 } 1406 }
1363 1407
1364 // Schedule the node or a floating control structure. 1408 // Schedule the node or a floating control structure.
1365 if (NodeProperties::IsControl(node)) { 1409 if (IrOpcode::IsMergeOpcode(node->opcode())) {
1366 ScheduleFloatingControl(block, node); 1410 ScheduleFloatingControl(block, node);
1367 } else { 1411 } else {
1368 ScheduleNode(block, node); 1412 ScheduleNode(block, node);
1369 } 1413 }
1370 } 1414 }
1371 1415
1372 // Mark {block} and push its non-marked predecessor on the marking queue. 1416 // Mark {block} and push its non-marked predecessor on the marking queue.
1373 void MarkBlock(BasicBlock* block) { 1417 void MarkBlock(BasicBlock* block) {
1374 DCHECK_LT(block->id().ToSize(), marked_.size()); 1418 DCHECK_LT(block->id().ToSize(), marked_.size());
1375 marked_[block->id().ToSize()] = true; 1419 marked_[block->id().ToSize()] = true;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1479 for (Edge edge : node->use_edges()) { 1523 for (Edge edge : node->use_edges()) {
1480 BasicBlock* use_block = GetBlockForUse(edge); 1524 BasicBlock* use_block = GetBlockForUse(edge);
1481 block = block == NULL ? use_block : use_block == NULL 1525 block = block == NULL ? use_block : use_block == NULL
1482 ? block 1526 ? block
1483 : BasicBlock::GetCommonDominator( 1527 : BasicBlock::GetCommonDominator(
1484 block, use_block); 1528 block, use_block);
1485 } 1529 }
1486 return block; 1530 return block;
1487 } 1531 }
1488 1532
1533 BasicBlock* FindPredecessorBlock(Node* node) {
1534 return scheduler_->control_flow_builder_->FindPredecessorBlock(node);
1535 }
1536
1489 BasicBlock* GetBlockForUse(Edge edge) { 1537 BasicBlock* GetBlockForUse(Edge edge) {
1490 Node* use = edge.from(); 1538 Node* use = edge.from();
1491 IrOpcode::Value opcode = use->opcode(); 1539 if (IrOpcode::IsPhiOpcode(use->opcode())) {
1492 if (IrOpcode::IsPhiOpcode(opcode)) {
1493 // If the use is from a coupled (i.e. floating) phi, compute the common 1540 // If the use is from a coupled (i.e. floating) phi, compute the common
1494 // dominator of its uses. This will not recurse more than one level. 1541 // dominator of its uses. This will not recurse more than one level.
1495 if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) { 1542 if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) {
1496 Trace(" inspecting uses of coupled #%d:%s\n", use->id(), 1543 Trace(" inspecting uses of coupled #%d:%s\n", use->id(),
1497 use->op()->mnemonic()); 1544 use->op()->mnemonic());
1498 DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use)); 1545 DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use));
1499 return GetCommonDominatorOfUses(use); 1546 return GetCommonDominatorOfUses(use);
1500 } 1547 }
1501 // If the use is from a fixed (i.e. non-floating) phi, use the block 1548 // If the use is from a fixed (i.e. non-floating) phi, we use the
1502 // of the corresponding control input to the merge. 1549 // predecessor block of the corresponding control input to the merge.
1503 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) { 1550 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
1504 Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(), 1551 Trace(" input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
1505 use->op()->mnemonic()); 1552 use->op()->mnemonic());
1506 Node* merge = NodeProperties::GetControlInput(use, 0); 1553 Node* merge = NodeProperties::GetControlInput(use, 0);
1507 opcode = merge->opcode(); 1554 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode()));
1508 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop); 1555 Node* input = NodeProperties::GetControlInput(merge, edge.index());
1509 use = NodeProperties::GetControlInput(merge, edge.index()); 1556 return FindPredecessorBlock(input);
1557 }
1558 } else if (IrOpcode::IsMergeOpcode(use->opcode())) {
1559 // If the use is from a fixed (i.e. non-floating) merge, we use the
1560 // predecessor block of the current input to the merge.
1561 if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
1562 Trace(" input@%d into a fixed merge #%d:%s\n", edge.index(), use->id(),
1563 use->op()->mnemonic());
1564 return FindPredecessorBlock(edge.to());
1510 } 1565 }
1511 } 1566 }
1512 BasicBlock* result = schedule_->block(use); 1567 BasicBlock* result = schedule_->block(use);
1513 if (result == NULL) return NULL; 1568 if (result == NULL) return NULL;
1514 Trace(" must dominate use #%d:%s in B%d\n", use->id(), 1569 Trace(" must dominate use #%d:%s in B%d\n", use->id(),
1515 use->op()->mnemonic(), result->id().ToInt()); 1570 use->op()->mnemonic(), result->id().ToInt());
1516 return result; 1571 return result;
1517 } 1572 }
1518 1573
1519 void ScheduleFloatingControl(BasicBlock* block, Node* node) { 1574 void ScheduleFloatingControl(BasicBlock* block, Node* node) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1648 for (Node* const node : *nodes) { 1703 for (Node* const node : *nodes) {
1649 schedule_->SetBlockForNode(to, node); 1704 schedule_->SetBlockForNode(to, node);
1650 scheduled_nodes_[to->id().ToSize()].push_back(node); 1705 scheduled_nodes_[to->id().ToSize()].push_back(node);
1651 } 1706 }
1652 nodes->clear(); 1707 nodes->clear();
1653 } 1708 }
1654 1709
1655 } // namespace compiler 1710 } // namespace compiler
1656 } // namespace internal 1711 } // namespace internal
1657 } // namespace v8 1712 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698