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

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

Issue 738613005: Restrict floating control to minimal control-connected component. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_scheduler-loop-1
Patch Set: Rebased and adapted. Created 6 years 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
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/zone-allocator.h » ('j') | 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 <deque> 5 #include <deque>
6 #include <queue> 6 #include <queue>
7 7
8 #include "src/compiler/scheduler.h" 8 #include "src/compiler/scheduler.h"
9 9
10 #include "src/bit-vector.h" 10 #include "src/bit-vector.h"
11 #include "src/compiler/control-equivalence.h"
11 #include "src/compiler/graph.h" 12 #include "src/compiler/graph.h"
12 #include "src/compiler/graph-inl.h" 13 #include "src/compiler/graph-inl.h"
13 #include "src/compiler/node.h" 14 #include "src/compiler/node.h"
14 #include "src/compiler/node-properties.h" 15 #include "src/compiler/node-properties.h"
15 #include "src/compiler/node-properties-inl.h" 16 #include "src/compiler/node-properties-inl.h"
16 17
17 namespace v8 { 18 namespace v8 {
18 namespace internal { 19 namespace internal {
19 namespace compiler { 20 namespace compiler {
20 21
(...skipping 30 matching lines...) Expand all
51 scheduler.ScheduleEarly(); 52 scheduler.ScheduleEarly();
52 scheduler.ScheduleLate(); 53 scheduler.ScheduleLate();
53 54
54 scheduler.SealFinalSchedule(); 55 scheduler.SealFinalSchedule();
55 56
56 return schedule; 57 return schedule;
57 } 58 }
58 59
59 60
60 Scheduler::SchedulerData Scheduler::DefaultSchedulerData() { 61 Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
61 SchedulerData def = {schedule_->start(), 0, false, false, kUnknown}; 62 SchedulerData def = {schedule_->start(), 0, false, kUnknown};
62 return def; 63 return def;
63 } 64 }
64 65
65 66
66 Scheduler::SchedulerData* Scheduler::GetData(Node* node) { 67 Scheduler::SchedulerData* Scheduler::GetData(Node* node) {
67 DCHECK(node->id() < static_cast<int>(node_data_.size())); 68 DCHECK(node->id() < static_cast<int>(node_data_.size()));
68 return &node_data_[node->id()]; 69 return &node_data_[node->id()];
69 } 70 }
70 71
71 72
72 Scheduler::Placement Scheduler::GetPlacement(Node* node) { 73 Scheduler::Placement Scheduler::GetPlacement(Node* node) {
73 SchedulerData* data = GetData(node); 74 SchedulerData* data = GetData(node);
74 if (data->placement_ == kUnknown) { // Compute placement, once, on demand. 75 if (data->placement_ == kUnknown) { // Compute placement, once, on demand.
75 switch (node->opcode()) { 76 switch (node->opcode()) {
76 case IrOpcode::kParameter: 77 case IrOpcode::kParameter:
77 // Parameters are always fixed to the start node. 78 // Parameters are always fixed to the start node.
78 data->placement_ = kFixed; 79 data->placement_ = kFixed;
79 break; 80 break;
80 case IrOpcode::kPhi: 81 case IrOpcode::kPhi:
81 case IrOpcode::kEffectPhi: { 82 case IrOpcode::kEffectPhi: {
82 // Phis and effect phis are fixed if their control inputs are, whereas 83 // Phis and effect phis are fixed if their control inputs are, whereas
83 // otherwise they are coupled to a floating control node. 84 // otherwise they are coupled to a floating control node.
84 Placement p = GetPlacement(NodeProperties::GetControlInput(node)); 85 Placement p = GetPlacement(NodeProperties::GetControlInput(node));
85 data->placement_ = (p == kFixed ? kFixed : kCoupled); 86 data->placement_ = (p == kFixed ? kFixed : kCoupled);
86 break; 87 break;
87 } 88 }
88 #define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V: 89 #define DEFINE_CONTROL_CASE(V) case IrOpcode::k##V:
89 CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE) 90 CONTROL_OP_LIST(DEFINE_CONTROL_CASE)
90 #undef DEFINE_FLOATING_CONTROL_CASE 91 #undef DEFINE_CONTROL_CASE
91 { 92 {
92 // Control nodes that were not control-reachable from end may float. 93 // Control nodes that were not control-reachable from end may float.
93 data->placement_ = kSchedulable; 94 data->placement_ = kSchedulable;
94 if (!data->is_connected_control_) {
95 data->is_floating_control_ = true;
96 Trace("Floating control found: #%d:%s\n", node->id(),
97 node->op()->mnemonic());
98 }
99 break; 95 break;
100 } 96 }
101 default: 97 default:
102 data->placement_ = kSchedulable; 98 data->placement_ = kSchedulable;
103 break; 99 break;
104 } 100 }
105 } 101 }
106 return data->placement_; 102 return data->placement_;
107 } 103 }
108 104
109 105
110 void Scheduler::UpdatePlacement(Node* node, Placement placement) { 106 void Scheduler::UpdatePlacement(Node* node, Placement placement) {
111 SchedulerData* data = GetData(node); 107 SchedulerData* data = GetData(node);
112 if (data->placement_ != kUnknown) { // Trap on mutation, not initialization. 108 if (data->placement_ != kUnknown) { // Trap on mutation, not initialization.
113 switch (node->opcode()) { 109 switch (node->opcode()) {
114 case IrOpcode::kParameter: 110 case IrOpcode::kParameter:
115 // Parameters are fixed once and for all. 111 // Parameters are fixed once and for all.
116 UNREACHABLE(); 112 UNREACHABLE();
117 break; 113 break;
118 case IrOpcode::kPhi: 114 case IrOpcode::kPhi:
119 case IrOpcode::kEffectPhi: { 115 case IrOpcode::kEffectPhi: {
120 // Phis and effect phis are coupled to their respective blocks. 116 // Phis and effect phis are coupled to their respective blocks.
121 DCHECK_EQ(Scheduler::kCoupled, data->placement_); 117 DCHECK_EQ(Scheduler::kCoupled, data->placement_);
122 DCHECK_EQ(Scheduler::kFixed, placement); 118 DCHECK_EQ(Scheduler::kFixed, placement);
123 Node* control = NodeProperties::GetControlInput(node); 119 Node* control = NodeProperties::GetControlInput(node);
124 BasicBlock* block = schedule_->block(control); 120 BasicBlock* block = schedule_->block(control);
125 schedule_->AddNode(block, node); 121 schedule_->AddNode(block, node);
126 break; 122 break;
127 } 123 }
128 #define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V: 124 #define DEFINE_CONTROL_CASE(V) case IrOpcode::k##V:
129 CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE) 125 CONTROL_OP_LIST(DEFINE_CONTROL_CASE)
130 #undef DEFINE_FLOATING_CONTROL_CASE 126 #undef DEFINE_CONTROL_CASE
131 { 127 {
132 // Control nodes force coupled uses to be placed. 128 // Control nodes force coupled uses to be placed.
133 Node::Uses uses = node->uses(); 129 Node::Uses uses = node->uses();
134 for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) { 130 for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
135 if (GetPlacement(*i) == Scheduler::kCoupled) { 131 if (GetPlacement(*i) == Scheduler::kCoupled) {
136 DCHECK_EQ(node, NodeProperties::GetControlInput(*i)); 132 DCHECK_EQ(node, NodeProperties::GetControlInput(*i));
137 UpdatePlacement(*i, placement); 133 UpdatePlacement(*i, placement);
138 } 134 }
139 } 135 }
140 break; 136 break;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 // between them within a Schedule) from the node graph. Visits control edges of 230 // between them within a Schedule) from the node graph. Visits control edges of
235 // the graph backwards from an end node in order to find the connected control 231 // the graph backwards from an end node in order to find the connected control
236 // subgraph, needed for scheduling. 232 // subgraph, needed for scheduling.
237 class CFGBuilder : public ZoneObject { 233 class CFGBuilder : public ZoneObject {
238 public: 234 public:
239 CFGBuilder(Zone* zone, Scheduler* scheduler) 235 CFGBuilder(Zone* zone, Scheduler* scheduler)
240 : scheduler_(scheduler), 236 : scheduler_(scheduler),
241 schedule_(scheduler->schedule_), 237 schedule_(scheduler->schedule_),
242 queue_(zone), 238 queue_(zone),
243 control_(zone), 239 control_(zone),
244 component_head_(NULL), 240 component_entry_(NULL),
245 component_start_(NULL), 241 component_start_(NULL),
246 component_end_(NULL) {} 242 component_end_(NULL) {}
247 243
248 // Run the control flow graph construction algorithm by walking the graph 244 // Run the control flow graph construction algorithm by walking the graph
249 // backwards from end through control edges, building and connecting the 245 // backwards from end through control edges, building and connecting the
250 // basic blocks for control nodes. 246 // basic blocks for control nodes.
251 void Run() { 247 void Run() {
252 ResetDataStructures(); 248 ResetDataStructures();
253 Queue(scheduler_->graph_->end()); 249 Queue(scheduler_->graph_->end());
254 250
255 while (!queue_.empty()) { // Breadth-first backwards traversal. 251 while (!queue_.empty()) { // Breadth-first backwards traversal.
256 Node* node = queue_.front(); 252 Node* node = queue_.front();
257 queue_.pop(); 253 queue_.pop();
258 int max = NodeProperties::PastControlIndex(node); 254 int max = NodeProperties::PastControlIndex(node);
259 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { 255 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
260 Queue(node->InputAt(i)); 256 Queue(node->InputAt(i));
261 } 257 }
262 } 258 }
263 259
264 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { 260 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
265 ConnectBlocks(*i); // Connect block to its predecessor/successors. 261 ConnectBlocks(*i); // Connect block to its predecessor/successors.
266 } 262 }
267 } 263 }
268 264
269 // Run the control flow graph construction for a minimal control-connected 265 // Run the control flow graph construction for a minimal control-connected
270 // component ending in {node} and merge that component into an existing 266 // component ending in {exit} and merge that component into an existing
271 // control flow graph at the bottom of {block}. 267 // control flow graph at the bottom of {block}.
272 void Run(BasicBlock* block, Node* node) { 268 void Run(BasicBlock* block, Node* exit) {
273 ResetDataStructures(); 269 ResetDataStructures();
274 Queue(node); 270 Queue(exit);
275 271
272 component_entry_ = NULL;
276 component_start_ = block; 273 component_start_ = block;
277 component_end_ = schedule_->block(node); 274 component_end_ = schedule_->block(exit);
275 scheduler_->equivalence_->Run(exit);
278 while (!queue_.empty()) { // Breadth-first backwards traversal. 276 while (!queue_.empty()) { // Breadth-first backwards traversal.
279 Node* node = queue_.front(); 277 Node* node = queue_.front();
280 queue_.pop(); 278 queue_.pop();
281 bool is_dom = true; 279
280 // Use control dependence equivalence to find a canonical single-entry
281 // single-exit region that makes up a minimal component to be scheduled.
282 if (IsSingleEntrySingleExitRegion(node, exit)) {
283 Trace("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
284 DCHECK_EQ(NULL, component_entry_);
285 component_entry_ = node;
286 continue;
287 }
288
282 int max = NodeProperties::PastControlIndex(node); 289 int max = NodeProperties::PastControlIndex(node);
283 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { 290 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
284 is_dom = is_dom &&
285 !scheduler_->GetData(node->InputAt(i))->is_floating_control_;
286 Queue(node->InputAt(i)); 291 Queue(node->InputAt(i));
287 } 292 }
288 // TODO(mstarzinger): This is a hacky way to find component dominator.
289 if (is_dom) component_head_ = node;
290 } 293 }
291 DCHECK_NOT_NULL(component_head_); 294 DCHECK_NE(NULL, component_entry_);
292 295
293 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { 296 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
294 scheduler_->GetData(*i)->is_floating_control_ = false;
295 ConnectBlocks(*i); // Connect block to its predecessor/successors. 297 ConnectBlocks(*i); // Connect block to its predecessor/successors.
296 } 298 }
297 } 299 }
298 300
299 private: 301 private:
300 // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl. 302 // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl.
301 friend class Scheduler; 303 friend class Scheduler;
302 304
303 void FixNode(BasicBlock* block, Node* node) { 305 void FixNode(BasicBlock* block, Node* node) {
304 schedule_->AddNode(block, node); 306 schedule_->AddNode(block, node);
305 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 307 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
306 } 308 }
307 309
308 void Queue(Node* node) { 310 void Queue(Node* node) {
309 // Mark the connected control nodes as they are queued. 311 // Mark the connected control nodes as they are queued.
310 Scheduler::SchedulerData* data = scheduler_->GetData(node); 312 Scheduler::SchedulerData* data = scheduler_->GetData(node);
311 if (!data->is_connected_control_) { 313 if (!data->is_connected_control_) {
312 data->is_connected_control_ = true; 314 data->is_connected_control_ = true;
313 BuildBlocks(node); 315 BuildBlocks(node);
314 queue_.push(node); 316 queue_.push(node);
315 control_.push_back(node); 317 control_.push_back(node);
316 } 318 }
317 } 319 }
318 320
319
320 void BuildBlocks(Node* node) { 321 void BuildBlocks(Node* node) {
321 switch (node->opcode()) { 322 switch (node->opcode()) {
322 case IrOpcode::kEnd: 323 case IrOpcode::kEnd:
323 FixNode(schedule_->end(), node); 324 FixNode(schedule_->end(), node);
324 break; 325 break;
325 case IrOpcode::kStart: 326 case IrOpcode::kStart:
326 FixNode(schedule_->start(), node); 327 FixNode(schedule_->start(), node);
327 break; 328 break;
328 case IrOpcode::kLoop: 329 case IrOpcode::kLoop:
329 case IrOpcode::kMerge: 330 case IrOpcode::kMerge:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 384 }
384 385
385 // Collect the branch-related projections from a node, such as IfTrue, 386 // Collect the branch-related projections from a node, such as IfTrue,
386 // IfFalse. 387 // IfFalse.
387 // TODO(titzer): consider moving this to node.h 388 // TODO(titzer): consider moving this to node.h
388 void CollectSuccessorProjections(Node* node, Node** buffer, 389 void CollectSuccessorProjections(Node* node, Node** buffer,
389 IrOpcode::Value true_opcode, 390 IrOpcode::Value true_opcode,
390 IrOpcode::Value false_opcode) { 391 IrOpcode::Value false_opcode) {
391 buffer[0] = NULL; 392 buffer[0] = NULL;
392 buffer[1] = NULL; 393 buffer[1] = NULL;
393 for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) { 394 for (Node* use : node->uses()) {
394 if ((*i)->opcode() == true_opcode) { 395 if (use->opcode() == true_opcode) {
395 DCHECK_EQ(NULL, buffer[0]); 396 DCHECK_EQ(NULL, buffer[0]);
396 buffer[0] = *i; 397 buffer[0] = use;
397 } 398 }
398 if ((*i)->opcode() == false_opcode) { 399 if (use->opcode() == false_opcode) {
399 DCHECK_EQ(NULL, buffer[1]); 400 DCHECK_EQ(NULL, buffer[1]);
400 buffer[1] = *i; 401 buffer[1] = use;
401 } 402 }
402 } 403 }
403 DCHECK_NE(NULL, buffer[0]); 404 DCHECK_NE(NULL, buffer[0]);
404 DCHECK_NE(NULL, buffer[1]); 405 DCHECK_NE(NULL, buffer[1]);
405 } 406 }
406 407
407 void CollectSuccessorBlocks(Node* node, BasicBlock** buffer, 408 void CollectSuccessorBlocks(Node* node, BasicBlock** buffer,
408 IrOpcode::Value true_opcode, 409 IrOpcode::Value true_opcode,
409 IrOpcode::Value false_opcode) { 410 IrOpcode::Value false_opcode) {
410 Node* successors[2]; 411 Node* successors[2];
(...skipping 12 matching lines...) Expand all
423 case BranchHint::kNone: 424 case BranchHint::kNone:
424 break; 425 break;
425 case BranchHint::kTrue: 426 case BranchHint::kTrue:
426 successor_blocks[1]->set_deferred(true); 427 successor_blocks[1]->set_deferred(true);
427 break; 428 break;
428 case BranchHint::kFalse: 429 case BranchHint::kFalse:
429 successor_blocks[0]->set_deferred(true); 430 successor_blocks[0]->set_deferred(true);
430 break; 431 break;
431 } 432 }
432 433
433 if (branch == component_head_) { 434 if (branch == component_entry_) {
434 TraceConnect(branch, component_start_, successor_blocks[0]); 435 TraceConnect(branch, component_start_, successor_blocks[0]);
435 TraceConnect(branch, component_start_, successor_blocks[1]); 436 TraceConnect(branch, component_start_, successor_blocks[1]);
436 schedule_->InsertBranch(component_start_, component_end_, branch, 437 schedule_->InsertBranch(component_start_, component_end_, branch,
437 successor_blocks[0], successor_blocks[1]); 438 successor_blocks[0], successor_blocks[1]);
438 } else { 439 } else {
439 Node* branch_block_node = NodeProperties::GetControlInput(branch); 440 Node* branch_block_node = NodeProperties::GetControlInput(branch);
440 BasicBlock* branch_block = schedule_->block(branch_block_node); 441 BasicBlock* branch_block = schedule_->block(branch_block_node);
441 DCHECK(branch_block != NULL); 442 DCHECK(branch_block != NULL);
442 443
443 TraceConnect(branch, branch_block, successor_blocks[0]); 444 TraceConnect(branch, branch_block, successor_blocks[0]);
444 TraceConnect(branch, branch_block, successor_blocks[1]); 445 TraceConnect(branch, branch_block, successor_blocks[1]);
445 schedule_->AddBranch(branch_block, branch, successor_blocks[0], 446 schedule_->AddBranch(branch_block, branch, successor_blocks[0],
446 successor_blocks[1]); 447 successor_blocks[1]);
447 } 448 }
448 } 449 }
449 450
450 void ConnectMerge(Node* merge) { 451 void ConnectMerge(Node* merge) {
451 // Don't connect the special merge at the end to its predecessors. 452 // Don't connect the special merge at the end to its predecessors.
452 if (IsFinalMerge(merge)) return; 453 if (IsFinalMerge(merge)) return;
453 454
454 BasicBlock* block = schedule_->block(merge); 455 BasicBlock* block = schedule_->block(merge);
455 DCHECK(block != NULL); 456 DCHECK(block != NULL);
456 // For all of the merge's control inputs, add a goto at the end to the 457 // For all of the merge's control inputs, add a goto at the end to the
457 // merge's basic block. 458 // merge's basic block.
458 for (Node* const j : merge->inputs()) { 459 for (Node* const input : merge->inputs()) {
459 BasicBlock* predecessor_block = schedule_->block(j); 460 BasicBlock* predecessor_block = schedule_->block(input);
460 TraceConnect(merge, predecessor_block, block); 461 TraceConnect(merge, predecessor_block, block);
461 schedule_->AddGoto(predecessor_block, block); 462 schedule_->AddGoto(predecessor_block, block);
462 } 463 }
463 } 464 }
464 465
465 void ConnectReturn(Node* ret) { 466 void ConnectReturn(Node* ret) {
466 Node* return_block_node = NodeProperties::GetControlInput(ret); 467 Node* return_block_node = NodeProperties::GetControlInput(ret);
467 BasicBlock* return_block = schedule_->block(return_block_node); 468 BasicBlock* return_block = schedule_->block(return_block_node);
468 TraceConnect(ret, return_block, NULL); 469 TraceConnect(ret, return_block, NULL);
469 schedule_->AddReturn(return_block, ret); 470 schedule_->AddReturn(return_block, ret);
470 } 471 }
471 472
472 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { 473 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
473 DCHECK_NE(NULL, block); 474 DCHECK_NE(NULL, block);
474 if (succ == NULL) { 475 if (succ == NULL) {
475 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(), 476 Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
476 block->id().ToInt()); 477 block->id().ToInt());
477 } else { 478 } else {
478 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(), 479 Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
479 block->id().ToInt(), succ->id().ToInt()); 480 block->id().ToInt(), succ->id().ToInt());
480 } 481 }
481 } 482 }
482 483
483 bool IsFinalMerge(Node* node) { 484 bool IsFinalMerge(Node* node) {
484 return (node->opcode() == IrOpcode::kMerge && 485 return (node->opcode() == IrOpcode::kMerge &&
485 node == scheduler_->graph_->end()->InputAt(0)); 486 node == scheduler_->graph_->end()->InputAt(0));
486 } 487 }
487 488
489 bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const {
490 size_t entry_class = scheduler_->equivalence_->ClassOf(entry);
491 size_t exit_class = scheduler_->equivalence_->ClassOf(exit);
492 return entry != exit && entry_class == exit_class;
493 }
494
488 void ResetDataStructures() { 495 void ResetDataStructures() {
489 control_.clear(); 496 control_.clear();
490 DCHECK(queue_.empty()); 497 DCHECK(queue_.empty());
491 DCHECK(control_.empty()); 498 DCHECK(control_.empty());
492 } 499 }
493 500
494 Scheduler* scheduler_; 501 Scheduler* scheduler_;
495 Schedule* schedule_; 502 Schedule* schedule_;
496 ZoneQueue<Node*> queue_; 503 ZoneQueue<Node*> queue_;
497 NodeVector control_; 504 NodeVector control_;
498 Node* component_head_; 505 Node* component_entry_;
499 BasicBlock* component_start_; 506 BasicBlock* component_start_;
500 BasicBlock* component_end_; 507 BasicBlock* component_end_;
501 }; 508 };
502 509
503 510
504 void Scheduler::BuildCFG() { 511 void Scheduler::BuildCFG() {
505 Trace("--- CREATING CFG -------------------------------------------\n"); 512 Trace("--- CREATING CFG -------------------------------------------\n");
506 513
514 // Instantiate a new control equivalence algorithm for the graph.
515 equivalence_ = new (zone_) ControlEquivalence(zone_, graph_);
516
507 // Build a control-flow graph for the main control-connected component that 517 // Build a control-flow graph for the main control-connected component that
508 // is being spanned by the graph's start and end nodes. 518 // is being spanned by the graph's start and end nodes.
509 control_flow_builder_ = new (zone_) CFGBuilder(zone_, this); 519 control_flow_builder_ = new (zone_) CFGBuilder(zone_, this);
510 control_flow_builder_->Run(); 520 control_flow_builder_->Run();
511 521
512 // Initialize per-block data. 522 // Initialize per-block data.
513 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_)); 523 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_));
514 } 524 }
515 525
516 526
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 } 1366 }
1357 } 1367 }
1358 BasicBlock* result = schedule_->block(use); 1368 BasicBlock* result = schedule_->block(use);
1359 if (result == NULL) return NULL; 1369 if (result == NULL) return NULL;
1360 Trace(" must dominate use #%d:%s in B%d\n", use->id(), 1370 Trace(" must dominate use #%d:%s in B%d\n", use->id(),
1361 use->op()->mnemonic(), result->id().ToInt()); 1371 use->op()->mnemonic(), result->id().ToInt());
1362 return result; 1372 return result;
1363 } 1373 }
1364 1374
1365 void ScheduleFloatingControl(BasicBlock* block, Node* node) { 1375 void ScheduleFloatingControl(BasicBlock* block, Node* node) {
1366 DCHECK(scheduler_->GetData(node)->is_floating_control_);
1367 scheduler_->FuseFloatingControl(block, node); 1376 scheduler_->FuseFloatingControl(block, node);
1368 } 1377 }
1369 1378
1370 void ScheduleNode(BasicBlock* block, Node* node) { 1379 void ScheduleNode(BasicBlock* block, Node* node) {
1371 schedule_->PlanNode(block, node); 1380 schedule_->PlanNode(block, node);
1372 scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node); 1381 scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
1373 scheduler_->UpdatePlacement(node, Scheduler::kScheduled); 1382 scheduler_->UpdatePlacement(node, Scheduler::kScheduled);
1374 } 1383 }
1375 1384
1376 Scheduler* scheduler_; 1385 Scheduler* scheduler_;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { 1491 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
1483 schedule_->SetBlockForNode(to, *i); 1492 schedule_->SetBlockForNode(to, *i);
1484 scheduled_nodes_[to->id().ToSize()].push_back(*i); 1493 scheduled_nodes_[to->id().ToSize()].push_back(*i);
1485 } 1494 }
1486 nodes->clear(); 1495 nodes->clear();
1487 } 1496 }
1488 1497
1489 } // namespace compiler 1498 } // namespace compiler
1490 } // namespace internal 1499 } // namespace internal
1491 } // namespace v8 1500 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/zone-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698