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

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: The actual fix plus unit tests. 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
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 { 233 class CFGBuilder {
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 Queue(scheduler_->graph_->end()); 248 Queue(scheduler_->graph_->end());
253 249
250 // TODO(mstarzinger): This is just for testing, remove again.
251 scheduler_->equivalence_->Run(scheduler_->graph_->end());
252
254 while (!queue_.empty()) { // Breadth-first backwards traversal. 253 while (!queue_.empty()) { // Breadth-first backwards traversal.
255 Node* node = queue_.front(); 254 Node* node = queue_.front();
256 queue_.pop(); 255 queue_.pop();
257 int max = NodeProperties::PastControlIndex(node); 256 int max = NodeProperties::PastControlIndex(node);
258 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { 257 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
259 Queue(node->InputAt(i)); 258 Queue(node->InputAt(i));
260 } 259 }
261 } 260 }
262 261
263 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { 262 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
264 ConnectBlocks(*i); // Connect block to its predecessor/successors. 263 ConnectBlocks(*i); // Connect block to its predecessor/successors.
265 } 264 }
266 } 265 }
267 266
268 // Run the control flow graph construction for a minimal control-connected 267 // Run the control flow graph construction for a minimal control-connected
269 // component ending in {node} and merge that component into an existing 268 // component ending in {exit} and merge that component into an existing
270 // control flow graph at the bottom of {block}. 269 // control flow graph at the bottom of {block}.
271 void Run(BasicBlock* block, Node* node) { 270 void Run(BasicBlock* block, Node* exit) {
272 Queue(node); 271 Queue(exit);
273 272
274 component_start_ = block; 273 component_start_ = block;
275 component_end_ = schedule_->block(node); 274 component_end_ = schedule_->block(exit);
275 scheduler_->equivalence_->Run(exit);
276 while (!queue_.empty()) { // Breadth-first backwards traversal. 276 while (!queue_.empty()) { // Breadth-first backwards traversal.
277 Node* node = queue_.front(); 277 Node* node = queue_.front();
278 queue_.pop(); 278 queue_.pop();
279 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
280 int max = NodeProperties::PastControlIndex(node); 289 int max = NodeProperties::PastControlIndex(node);
281 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { 290 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
282 is_dom = is_dom &&
283 !scheduler_->GetData(node->InputAt(i))->is_floating_control_;
284 Queue(node->InputAt(i)); 291 Queue(node->InputAt(i));
285 } 292 }
286 // TODO(mstarzinger): This is a hacky way to find component dominator.
287 if (is_dom) component_head_ = node;
288 } 293 }
289 DCHECK_NOT_NULL(component_head_); 294 DCHECK_NE(NULL, component_entry_);
290 295
291 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { 296 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
292 scheduler_->GetData(*i)->is_floating_control_ = false;
293 ConnectBlocks(*i); // Connect block to its predecessor/successors. 297 ConnectBlocks(*i); // Connect block to its predecessor/successors.
294 } 298 }
295 } 299 }
296 300
297 private: 301 private:
298 // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl. 302 // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl.
299 friend class Scheduler; 303 friend class Scheduler;
300 304
301 void FixNode(BasicBlock* block, Node* node) { 305 void FixNode(BasicBlock* block, Node* node) {
302 schedule_->AddNode(block, node); 306 schedule_->AddNode(block, node);
303 scheduler_->UpdatePlacement(node, Scheduler::kFixed); 307 scheduler_->UpdatePlacement(node, Scheduler::kFixed);
304 } 308 }
305 309
306 void Queue(Node* node) { 310 void Queue(Node* node) {
307 // Mark the connected control nodes as they are queued. 311 // Mark the connected control nodes as they are queued.
308 Scheduler::SchedulerData* data = scheduler_->GetData(node); 312 Scheduler::SchedulerData* data = scheduler_->GetData(node);
309 if (!data->is_connected_control_) { 313 if (!data->is_connected_control_) {
310 data->is_connected_control_ = true; 314 data->is_connected_control_ = true;
311 BuildBlocks(node); 315 BuildBlocks(node);
312 queue_.push(node); 316 queue_.push(node);
313 control_.push_back(node); 317 control_.push_back(node);
314 } 318 }
315 } 319 }
316 320
317
318 void BuildBlocks(Node* node) { 321 void BuildBlocks(Node* node) {
319 switch (node->opcode()) { 322 switch (node->opcode()) {
320 case IrOpcode::kEnd: 323 case IrOpcode::kEnd:
321 FixNode(schedule_->end(), node); 324 FixNode(schedule_->end(), node);
322 break; 325 break;
323 case IrOpcode::kStart: 326 case IrOpcode::kStart:
324 FixNode(schedule_->start(), node); 327 FixNode(schedule_->start(), node);
325 break; 328 break;
326 case IrOpcode::kLoop: 329 case IrOpcode::kLoop:
327 case IrOpcode::kMerge: 330 case IrOpcode::kMerge:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 } 384 }
382 385
383 // Collect the branch-related projections from a node, such as IfTrue, 386 // Collect the branch-related projections from a node, such as IfTrue,
384 // IfFalse. 387 // IfFalse.
385 // TODO(titzer): consider moving this to node.h 388 // TODO(titzer): consider moving this to node.h
386 void CollectSuccessorProjections(Node* node, Node** buffer, 389 void CollectSuccessorProjections(Node* node, Node** buffer,
387 IrOpcode::Value true_opcode, 390 IrOpcode::Value true_opcode,
388 IrOpcode::Value false_opcode) { 391 IrOpcode::Value false_opcode) {
389 buffer[0] = NULL; 392 buffer[0] = NULL;
390 buffer[1] = NULL; 393 buffer[1] = NULL;
391 for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) { 394 for (Node* use : node->uses()) {
392 if ((*i)->opcode() == true_opcode) { 395 if (use->opcode() == true_opcode) {
393 DCHECK_EQ(NULL, buffer[0]); 396 DCHECK_EQ(NULL, buffer[0]);
394 buffer[0] = *i; 397 buffer[0] = use;
395 } 398 }
396 if ((*i)->opcode() == false_opcode) { 399 if (use->opcode() == false_opcode) {
397 DCHECK_EQ(NULL, buffer[1]); 400 DCHECK_EQ(NULL, buffer[1]);
398 buffer[1] = *i; 401 buffer[1] = use;
399 } 402 }
400 } 403 }
401 DCHECK_NE(NULL, buffer[0]); 404 DCHECK_NE(NULL, buffer[0]);
402 DCHECK_NE(NULL, buffer[1]); 405 DCHECK_NE(NULL, buffer[1]);
403 } 406 }
404 407
405 void CollectSuccessorBlocks(Node* node, BasicBlock** buffer, 408 void CollectSuccessorBlocks(Node* node, BasicBlock** buffer,
406 IrOpcode::Value true_opcode, 409 IrOpcode::Value true_opcode,
407 IrOpcode::Value false_opcode) { 410 IrOpcode::Value false_opcode) {
408 Node* successors[2]; 411 Node* successors[2];
(...skipping 12 matching lines...) Expand all
421 case BranchHint::kNone: 424 case BranchHint::kNone:
422 break; 425 break;
423 case BranchHint::kTrue: 426 case BranchHint::kTrue:
424 successor_blocks[1]->set_deferred(true); 427 successor_blocks[1]->set_deferred(true);
425 break; 428 break;
426 case BranchHint::kFalse: 429 case BranchHint::kFalse:
427 successor_blocks[0]->set_deferred(true); 430 successor_blocks[0]->set_deferred(true);
428 break; 431 break;
429 } 432 }
430 433
431 if (branch == component_head_) { 434 if (branch == component_entry_) {
432 TraceConnect(branch, component_start_, successor_blocks[0]); 435 TraceConnect(branch, component_start_, successor_blocks[0]);
433 TraceConnect(branch, component_start_, successor_blocks[1]); 436 TraceConnect(branch, component_start_, successor_blocks[1]);
434 schedule_->InsertBranch(component_start_, component_end_, branch, 437 schedule_->InsertBranch(component_start_, component_end_, branch,
435 successor_blocks[0], successor_blocks[1]); 438 successor_blocks[0], successor_blocks[1]);
436 } else { 439 } else {
437 Node* branch_block_node = NodeProperties::GetControlInput(branch); 440 Node* branch_block_node = NodeProperties::GetControlInput(branch);
438 BasicBlock* branch_block = schedule_->block(branch_block_node); 441 BasicBlock* branch_block = schedule_->block(branch_block_node);
439 DCHECK(branch_block != NULL); 442 DCHECK(branch_block != NULL);
440 443
441 TraceConnect(branch, branch_block, successor_blocks[0]); 444 TraceConnect(branch, branch_block, successor_blocks[0]);
442 TraceConnect(branch, branch_block, successor_blocks[1]); 445 TraceConnect(branch, branch_block, successor_blocks[1]);
443 schedule_->AddBranch(branch_block, branch, successor_blocks[0], 446 schedule_->AddBranch(branch_block, branch, successor_blocks[0],
444 successor_blocks[1]); 447 successor_blocks[1]);
445 } 448 }
446 } 449 }
447 450
448 void ConnectMerge(Node* merge) { 451 void ConnectMerge(Node* merge) {
449 // 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.
450 if (IsFinalMerge(merge)) return; 453 if (IsFinalMerge(merge)) return;
451 454
452 BasicBlock* block = schedule_->block(merge); 455 BasicBlock* block = schedule_->block(merge);
453 DCHECK(block != NULL); 456 DCHECK(block != NULL);
454 // 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
455 // merge's basic block. 458 // merge's basic block.
456 for (InputIter j = merge->inputs().begin(); j != merge->inputs().end(); 459 for (Node* input : merge->inputs()) {
457 ++j) { 460 BasicBlock* predecessor_block = schedule_->block(input);
458 BasicBlock* predecessor_block = schedule_->block(*j);
459 TraceConnect(merge, predecessor_block, block); 461 TraceConnect(merge, predecessor_block, block);
460 schedule_->AddGoto(predecessor_block, block); 462 schedule_->AddGoto(predecessor_block, block);
461 } 463 }
462 } 464 }
463 465
464 void ConnectReturn(Node* ret) { 466 void ConnectReturn(Node* ret) {
465 Node* return_block_node = NodeProperties::GetControlInput(ret); 467 Node* return_block_node = NodeProperties::GetControlInput(ret);
466 BasicBlock* return_block = schedule_->block(return_block_node); 468 BasicBlock* return_block = schedule_->block(return_block_node);
467 TraceConnect(ret, return_block, NULL); 469 TraceConnect(ret, return_block, NULL);
468 schedule_->AddReturn(return_block, ret); 470 schedule_->AddReturn(return_block, ret);
469 } 471 }
470 472
471 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) { 473 void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
472 DCHECK_NE(NULL, block); 474 DCHECK_NE(NULL, block);
473 if (succ == NULL) { 475 if (succ == NULL) {
474 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(),
475 block->id().ToInt()); 477 block->id().ToInt());
476 } else { 478 } else {
477 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(),
478 block->id().ToInt(), succ->id().ToInt()); 480 block->id().ToInt(), succ->id().ToInt());
479 } 481 }
480 } 482 }
481 483
482 bool IsFinalMerge(Node* node) { 484 bool IsFinalMerge(Node* node) {
483 return (node->opcode() == IrOpcode::kMerge && 485 return (node->opcode() == IrOpcode::kMerge &&
484 node == scheduler_->graph_->end()->InputAt(0)); 486 node == scheduler_->graph_->end()->InputAt(0));
485 } 487 }
486 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
487 Scheduler* scheduler_; 495 Scheduler* scheduler_;
488 Schedule* schedule_; 496 Schedule* schedule_;
489 ZoneQueue<Node*> queue_; 497 ZoneQueue<Node*> queue_;
490 NodeVector control_; 498 NodeVector control_;
491 Node* component_head_; 499 Node* component_entry_;
492 BasicBlock* component_start_; 500 BasicBlock* component_start_;
493 BasicBlock* component_end_; 501 BasicBlock* component_end_;
494 }; 502 };
495 503
496 504
497 void Scheduler::BuildCFG() { 505 void Scheduler::BuildCFG() {
498 Trace("--- CREATING CFG -------------------------------------------\n"); 506 Trace("--- CREATING CFG -------------------------------------------\n");
499 507
508 // Instantiate a new control equivalence algorithm for the graph.
509 equivalence_ = new (zone_) ControlEquivalence(zone_, graph_);
510
500 // Build a control-flow graph for the main control-connected component that 511 // Build a control-flow graph for the main control-connected component that
501 // is being spanned by the graph's start and end nodes. 512 // is being spanned by the graph's start and end nodes.
502 CFGBuilder cfg_builder(zone_, this); 513 CFGBuilder cfg_builder(zone_, this);
503 cfg_builder.Run(); 514 cfg_builder.Run();
504 515
505 // Initialize per-block data. 516 // Initialize per-block data.
506 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_)); 517 scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_));
507 } 518 }
508 519
509 520
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 } 1387 }
1377 } 1388 }
1378 BasicBlock* result = schedule_->block(use); 1389 BasicBlock* result = schedule_->block(use);
1379 if (result == NULL) return NULL; 1390 if (result == NULL) return NULL;
1380 Trace(" must dominate use #%d:%s in B%d\n", use->id(), 1391 Trace(" must dominate use #%d:%s in B%d\n", use->id(),
1381 use->op()->mnemonic(), result->id().ToInt()); 1392 use->op()->mnemonic(), result->id().ToInt());
1382 return result; 1393 return result;
1383 } 1394 }
1384 1395
1385 void ScheduleFloatingControl(BasicBlock* block, Node* node) { 1396 void ScheduleFloatingControl(BasicBlock* block, Node* node) {
1386 DCHECK(scheduler_->GetData(node)->is_floating_control_);
1387 scheduler_->FuseFloatingControl(block, node); 1397 scheduler_->FuseFloatingControl(block, node);
1388 } 1398 }
1389 1399
1390 void ScheduleNode(BasicBlock* block, Node* node) { 1400 void ScheduleNode(BasicBlock* block, Node* node) {
1391 schedule_->PlanNode(block, node); 1401 schedule_->PlanNode(block, node);
1392 scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node); 1402 scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
1393 scheduler_->UpdatePlacement(node, Scheduler::kScheduled); 1403 scheduler_->UpdatePlacement(node, Scheduler::kScheduled);
1394 } 1404 }
1395 1405
1396 Scheduler* scheduler_; 1406 Scheduler* scheduler_;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1503 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { 1513 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
1504 schedule_->SetBlockForNode(to, *i); 1514 schedule_->SetBlockForNode(to, *i);
1505 scheduled_nodes_[to->id().ToSize()].push_back(*i); 1515 scheduled_nodes_[to->id().ToSize()].push_back(*i);
1506 } 1516 }
1507 nodes->clear(); 1517 nodes->clear();
1508 } 1518 }
1509 1519
1510 } // namespace compiler 1520 } // namespace compiler
1511 } // namespace internal 1521 } // namespace internal
1512 } // namespace v8 1522 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698