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

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

Issue 474983003: Move some methods from OperatorProperties into Scheduler that are only related to scheduling. Now t… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler/scheduler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/compiler/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/graph-inl.h" 8 #include "src/compiler/graph-inl.h"
9 #include "src/compiler/node.h" 9 #include "src/compiler/node.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 scheduler.GenerateImmediateDominatorTree(); 46 scheduler.GenerateImmediateDominatorTree();
47 47
48 scheduler.PrepareUses(); 48 scheduler.PrepareUses();
49 scheduler.ScheduleEarly(); 49 scheduler.ScheduleEarly();
50 scheduler.ScheduleLate(); 50 scheduler.ScheduleLate();
51 51
52 return schedule; 52 return schedule;
53 } 53 }
54 54
55 55
56 bool Scheduler::IsBasicBlockBegin(Node* node) {
57 return OperatorProperties::IsBasicBlockBegin(node->op());
58 }
59
60
61 bool Scheduler::CanBeScheduled(Node* node) { return true; }
62
63
64 bool Scheduler::HasFixedSchedulePosition(Node* node) {
65 IrOpcode::Value opcode = node->opcode();
66 return (IrOpcode::IsControlOpcode(opcode)) ||
67 opcode == IrOpcode::kParameter || opcode == IrOpcode::kEffectPhi ||
68 opcode == IrOpcode::kPhi;
69 }
70
71
72 bool Scheduler::IsScheduleRoot(Node* node) {
73 IrOpcode::Value opcode = node->opcode();
74 return opcode == IrOpcode::kEnd || opcode == IrOpcode::kEffectPhi ||
75 opcode == IrOpcode::kPhi;
76 }
77
78
56 class CreateBlockVisitor : public NullNodeVisitor { 79 class CreateBlockVisitor : public NullNodeVisitor {
57 public: 80 public:
58 explicit CreateBlockVisitor(Scheduler* scheduler) : scheduler_(scheduler) {} 81 explicit CreateBlockVisitor(Scheduler* scheduler) : scheduler_(scheduler) {}
59 82
60 GenericGraphVisit::Control Post(Node* node) { 83 GenericGraphVisit::Control Post(Node* node) {
61 Schedule* schedule = scheduler_->schedule_; 84 Schedule* schedule = scheduler_->schedule_;
62 switch (node->opcode()) { 85 switch (node->opcode()) {
63 case IrOpcode::kIfTrue: 86 case IrOpcode::kIfTrue:
64 case IrOpcode::kIfFalse: 87 case IrOpcode::kIfFalse:
65 case IrOpcode::kContinuation: 88 case IrOpcode::kContinuation:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 166
144 void Scheduler::AddPredecessorsForLoopsAndMerges() { 167 void Scheduler::AddPredecessorsForLoopsAndMerges() {
145 for (NodeVectorIter i = loops_and_merges_.begin(); 168 for (NodeVectorIter i = loops_and_merges_.begin();
146 i != loops_and_merges_.end(); ++i) { 169 i != loops_and_merges_.end(); ++i) {
147 Node* merge_or_loop = *i; 170 Node* merge_or_loop = *i;
148 BasicBlock* block = schedule_->block(merge_or_loop); 171 BasicBlock* block = schedule_->block(merge_or_loop);
149 DCHECK(block != NULL); 172 DCHECK(block != NULL);
150 // For all of the merge's control inputs, add a goto at the end to the 173 // For all of the merge's control inputs, add a goto at the end to the
151 // merge's basic block. 174 // merge's basic block.
152 for (InputIter j = (*i)->inputs().begin(); j != (*i)->inputs().end(); ++j) { 175 for (InputIter j = (*i)->inputs().begin(); j != (*i)->inputs().end(); ++j) {
153 if (OperatorProperties::IsBasicBlockBegin((*i)->op())) { 176 if (IsBasicBlockBegin((*i))) {
154 BasicBlock* predecessor_block = schedule_->block(*j); 177 BasicBlock* predecessor_block = schedule_->block(*j);
155 if ((*j)->opcode() != IrOpcode::kReturn && 178 if ((*j)->opcode() != IrOpcode::kReturn &&
156 (*j)->opcode() != IrOpcode::kDeoptimize) { 179 (*j)->opcode() != IrOpcode::kDeoptimize) {
157 DCHECK(predecessor_block != NULL); 180 DCHECK(predecessor_block != NULL);
158 if (FLAG_trace_turbo_scheduler) { 181 if (FLAG_trace_turbo_scheduler) {
159 IrOpcode::Value opcode = (*i)->opcode(); 182 IrOpcode::Value opcode = (*i)->opcode();
160 PrintF("node %d (%s) in block %d -> block %d\n", (*i)->id(), 183 PrintF("node %d (%s) in block %d -> block %d\n", (*i)->id(),
161 IrOpcode::Mnemonic(opcode), predecessor_block->id(), 184 IrOpcode::Mnemonic(opcode), predecessor_block->id(),
162 block->id()); 185 block->id());
163 } 186 }
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 384 }
362 } 385 }
363 return GenericGraphVisit::CONTINUE; 386 return GenericGraphVisit::CONTINUE;
364 } 387 }
365 388
366 GenericGraphVisit::Control Post(Node* node) { 389 GenericGraphVisit::Control Post(Node* node) {
367 int id = node->id(); 390 int id = node->id();
368 int max_rpo = 0; 391 int max_rpo = 0;
369 // Otherwise, the minimum rpo for the node is the max of all of the inputs. 392 // Otherwise, the minimum rpo for the node is the max of all of the inputs.
370 if (!IsFixedNode(node)) { 393 if (!IsFixedNode(node)) {
371 DCHECK(!OperatorProperties::IsBasicBlockBegin(node->op())); 394 DCHECK(!scheduler_->IsBasicBlockBegin(node));
372 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); 395 for (InputIter i = node->inputs().begin(); i != node->inputs().end();
373 ++i) { 396 ++i) {
374 int control_rpo = scheduler_->schedule_early_rpo_index_[(*i)->id()]; 397 int control_rpo = scheduler_->schedule_early_rpo_index_[(*i)->id()];
375 if (control_rpo > max_rpo) { 398 if (control_rpo > max_rpo) {
376 max_rpo = control_rpo; 399 max_rpo = control_rpo;
377 } 400 }
378 } 401 }
379 if (scheduler_->schedule_early_rpo_index_[id] != max_rpo) { 402 if (scheduler_->schedule_early_rpo_index_[id] != max_rpo) {
380 has_changed_rpo_constraints_ = true; 403 has_changed_rpo_constraints_ = true;
381 } 404 }
382 scheduler_->schedule_early_rpo_index_[id] = max_rpo; 405 scheduler_->schedule_early_rpo_index_[id] = max_rpo;
383 if (FLAG_trace_turbo_scheduler) { 406 if (FLAG_trace_turbo_scheduler) {
384 PrintF("Node %d post-scheduled early at rpo limit %d\n", id, max_rpo); 407 PrintF("Node %d post-scheduled early at rpo limit %d\n", id, max_rpo);
385 } 408 }
386 } 409 }
387 return GenericGraphVisit::CONTINUE; 410 return GenericGraphVisit::CONTINUE;
388 } 411 }
389 412
390 static bool IsFixedNode(Node* node) { 413 bool IsFixedNode(Node* node) {
391 return OperatorProperties::HasFixedSchedulePosition(node->op()) || 414 return scheduler_->HasFixedSchedulePosition(node) ||
392 !OperatorProperties::CanBeScheduled(node->op()); 415 !scheduler_->CanBeScheduled(node);
393 } 416 }
394 417
395 // TODO(mstarzinger): Dirty hack to unblock others, schedule early should be 418 // TODO(mstarzinger): Dirty hack to unblock others, schedule early should be
396 // rewritten to use a pre-order traversal from the start instead. 419 // rewritten to use a pre-order traversal from the start instead.
397 bool has_changed_rpo_constraints_; 420 bool has_changed_rpo_constraints_;
398 421
399 private: 422 private:
400 Scheduler* scheduler_; 423 Scheduler* scheduler_;
401 Schedule* schedule_; 424 Schedule* schedule_;
402 }; 425 };
(...skipping 21 matching lines...) Expand all
424 class PrepareUsesVisitor : public NullNodeVisitor { 447 class PrepareUsesVisitor : public NullNodeVisitor {
425 public: 448 public:
426 explicit PrepareUsesVisitor(Scheduler* scheduler) 449 explicit PrepareUsesVisitor(Scheduler* scheduler)
427 : scheduler_(scheduler), schedule_(scheduler->schedule_) {} 450 : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
428 451
429 GenericGraphVisit::Control Pre(Node* node) { 452 GenericGraphVisit::Control Pre(Node* node) {
430 // Some nodes must be scheduled explicitly to ensure they are in exactly the 453 // Some nodes must be scheduled explicitly to ensure they are in exactly the
431 // right place; it's a convenient place during the preparation of use counts 454 // right place; it's a convenient place during the preparation of use counts
432 // to schedule them. 455 // to schedule them.
433 if (!schedule_->IsScheduled(node) && 456 if (!schedule_->IsScheduled(node) &&
434 OperatorProperties::HasFixedSchedulePosition(node->op())) { 457 scheduler_->HasFixedSchedulePosition(node)) {
435 if (FLAG_trace_turbo_scheduler) { 458 if (FLAG_trace_turbo_scheduler) {
436 PrintF("Fixed position node %d is unscheduled, scheduling now\n", 459 PrintF("Fixed position node %d is unscheduled, scheduling now\n",
437 node->id()); 460 node->id());
438 } 461 }
439 IrOpcode::Value opcode = node->opcode(); 462 IrOpcode::Value opcode = node->opcode();
440 BasicBlock* block = 463 BasicBlock* block =
441 opcode == IrOpcode::kParameter 464 opcode == IrOpcode::kParameter
442 ? schedule_->entry() 465 ? schedule_->entry()
443 : schedule_->block(NodeProperties::GetControlInput(node)); 466 : schedule_->block(NodeProperties::GetControlInput(node));
444 DCHECK(block != NULL); 467 DCHECK(block != NULL);
445 schedule_->AddNode(block, node); 468 schedule_->AddNode(block, node);
446 } 469 }
447 470
448 if (OperatorProperties::IsScheduleRoot(node->op())) { 471 if (scheduler_->IsScheduleRoot(node)) {
449 scheduler_->schedule_root_nodes_.push_back(node); 472 scheduler_->schedule_root_nodes_.push_back(node);
450 } 473 }
451 474
452 return GenericGraphVisit::CONTINUE; 475 return GenericGraphVisit::CONTINUE;
453 } 476 }
454 477
455 void PostEdge(Node* from, int index, Node* to) { 478 void PostEdge(Node* from, int index, Node* to) {
456 // If the edge is from an unscheduled node, then tally it in the use count 479 // If the edge is from an unscheduled node, then tally it in the use count
457 // for all of its inputs. The same criterion will be used in ScheduleLate 480 // for all of its inputs. The same criterion will be used in ScheduleLate
458 // for decrementing use counts. 481 // for decrementing use counts.
459 if (!schedule_->IsScheduled(from) && 482 if (!schedule_->IsScheduled(from) && scheduler_->CanBeScheduled(from)) {
460 OperatorProperties::CanBeScheduled(from->op())) { 483 DCHECK(!scheduler_->HasFixedSchedulePosition(from));
461 DCHECK(!OperatorProperties::HasFixedSchedulePosition(from->op()));
462 ++scheduler_->unscheduled_uses_[to->id()]; 484 ++scheduler_->unscheduled_uses_[to->id()];
463 if (FLAG_trace_turbo_scheduler) { 485 if (FLAG_trace_turbo_scheduler) {
464 PrintF("Incrementing uses of node %d from %d to %d\n", to->id(), 486 PrintF("Incrementing uses of node %d from %d to %d\n", to->id(),
465 from->id(), scheduler_->unscheduled_uses_[to->id()]); 487 from->id(), scheduler_->unscheduled_uses_[to->id()]);
466 } 488 }
467 } 489 }
468 } 490 }
469 491
470 private: 492 private:
471 Scheduler* scheduler_; 493 Scheduler* scheduler_;
(...skipping 12 matching lines...) Expand all
484 } 506 }
485 507
486 508
487 class ScheduleLateNodeVisitor : public NullNodeVisitor { 509 class ScheduleLateNodeVisitor : public NullNodeVisitor {
488 public: 510 public:
489 explicit ScheduleLateNodeVisitor(Scheduler* scheduler) 511 explicit ScheduleLateNodeVisitor(Scheduler* scheduler)
490 : scheduler_(scheduler), schedule_(scheduler_->schedule_) {} 512 : scheduler_(scheduler), schedule_(scheduler_->schedule_) {}
491 513
492 GenericGraphVisit::Control Pre(Node* node) { 514 GenericGraphVisit::Control Pre(Node* node) {
493 // Don't schedule nodes that cannot be scheduled or are already scheduled. 515 // Don't schedule nodes that cannot be scheduled or are already scheduled.
494 if (!OperatorProperties::CanBeScheduled(node->op()) || 516 if (!scheduler_->CanBeScheduled(node) || schedule_->IsScheduled(node)) {
495 schedule_->IsScheduled(node)) {
496 return GenericGraphVisit::CONTINUE; 517 return GenericGraphVisit::CONTINUE;
497 } 518 }
498 DCHECK(!OperatorProperties::HasFixedSchedulePosition(node->op())); 519 DCHECK(!scheduler_->HasFixedSchedulePosition(node));
499 520
500 // If all the uses of a node have been scheduled, then the node itself can 521 // If all the uses of a node have been scheduled, then the node itself can
501 // be scheduled. 522 // be scheduled.
502 bool eligible = scheduler_->unscheduled_uses_[node->id()] == 0; 523 bool eligible = scheduler_->unscheduled_uses_[node->id()] == 0;
503 if (FLAG_trace_turbo_scheduler) { 524 if (FLAG_trace_turbo_scheduler) {
504 PrintF("Testing for schedule eligibility for node %d -> %s\n", node->id(), 525 PrintF("Testing for schedule eligibility for node %d -> %s\n", node->id(),
505 eligible ? "true" : "false"); 526 eligible ? "true" : "false");
506 } 527 }
507 if (!eligible) return GenericGraphVisit::DEFER; 528 if (!eligible) return GenericGraphVisit::DEFER;
508 529
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 576
556 ScheduleNode(block, node); 577 ScheduleNode(block, node);
557 578
558 return GenericGraphVisit::CONTINUE; 579 return GenericGraphVisit::CONTINUE;
559 } 580 }
560 581
561 private: 582 private:
562 BasicBlock* GetBlockForUse(Node::Edge edge) { 583 BasicBlock* GetBlockForUse(Node::Edge edge) {
563 Node* use = edge.from(); 584 Node* use = edge.from();
564 IrOpcode::Value opcode = use->opcode(); 585 IrOpcode::Value opcode = use->opcode();
565 // If the use is a phi, forward through the the phi to the basic block 586 // If the use is a phi, forward through the phi to the basic block
566 // corresponding to the phi's input. 587 // corresponding to the phi's input.
567 if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) { 588 if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
568 int index = edge.index(); 589 int index = edge.index();
569 if (FLAG_trace_turbo_scheduler) { 590 if (FLAG_trace_turbo_scheduler) {
570 PrintF("Use %d is input %d to a phi\n", use->id(), index); 591 PrintF("Use %d is input %d to a phi\n", use->id(), index);
571 } 592 }
572 use = NodeProperties::GetControlInput(use, 0); 593 use = NodeProperties::GetControlInput(use, 0);
573 opcode = use->opcode(); 594 opcode = use->opcode();
574 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop); 595 DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop);
575 use = NodeProperties::GetControlInput(use, index); 596 use = NodeProperties::GetControlInput(use, index);
576 } 597 }
577 BasicBlock* result = schedule_->block(use); 598 BasicBlock* result = schedule_->block(use);
578 if (result == NULL) return NULL; 599 if (result == NULL) return NULL;
579 if (FLAG_trace_turbo_scheduler) { 600 if (FLAG_trace_turbo_scheduler) {
580 PrintF("Must dominate use %d in block %d\n", use->id(), result->id()); 601 PrintF("Must dominate use %d in block %d\n", use->id(), result->id());
581 } 602 }
582 return result; 603 return result;
583 } 604 }
584 605
585 bool IsNodeEligible(Node* node) {
586 bool eligible = scheduler_->unscheduled_uses_[node->id()] == 0;
587 return eligible;
588 }
589
590 void ScheduleNode(BasicBlock* block, Node* node) { 606 void ScheduleNode(BasicBlock* block, Node* node) {
591 schedule_->PlanNode(block, node); 607 schedule_->PlanNode(block, node);
592 scheduler_->scheduled_nodes_[block->id()].push_back(node); 608 scheduler_->scheduled_nodes_[block->id()].push_back(node);
593 609
594 // Reduce the use count of the node's inputs to potentially make them 610 // Reduce the use count of the node's inputs to potentially make them
595 // scheduable. 611 // scheduable.
596 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { 612 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
597 DCHECK(scheduler_->unscheduled_uses_[(*i)->id()] > 0); 613 DCHECK(scheduler_->unscheduled_uses_[(*i)->id()] > 0);
598 --scheduler_->unscheduled_uses_[(*i)->id()]; 614 --scheduler_->unscheduled_uses_[(*i)->id()];
599 if (FLAG_trace_turbo_scheduler) { 615 if (FLAG_trace_turbo_scheduler) {
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 1056
1041 #if DEBUG 1057 #if DEBUG
1042 if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order); 1058 if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order);
1043 VerifySpecialRPO(num_loops, loops, final_order); 1059 VerifySpecialRPO(num_loops, loops, final_order);
1044 #endif 1060 #endif
1045 return final_order; 1061 return final_order;
1046 } 1062 }
1047 } 1063 }
1048 } 1064 }
1049 } // namespace v8::internal::compiler 1065 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698