| 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 <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/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 queue_(zone), | 234 queue_(zone), |
| 235 control_(zone), | 235 control_(zone), |
| 236 component_head_(NULL), | 236 component_head_(NULL), |
| 237 component_start_(NULL), | 237 component_start_(NULL), |
| 238 component_end_(NULL) {} | 238 component_end_(NULL) {} |
| 239 | 239 |
| 240 // Run the control flow graph construction algorithm by walking the graph | 240 // Run the control flow graph construction algorithm by walking the graph |
| 241 // backwards from end through control edges, building and connecting the | 241 // backwards from end through control edges, building and connecting the |
| 242 // basic blocks for control nodes. | 242 // basic blocks for control nodes. |
| 243 void Run() { | 243 void Run() { |
| 244 Graph* graph = scheduler_->graph_; | 244 Queue(scheduler_->graph_->end()); |
| 245 FixNode(schedule_->start(), graph->start()); | |
| 246 Queue(graph->end()); | |
| 247 | 245 |
| 248 while (!queue_.empty()) { // Breadth-first backwards traversal. | 246 while (!queue_.empty()) { // Breadth-first backwards traversal. |
| 249 Node* node = queue_.front(); | 247 Node* node = queue_.front(); |
| 250 queue_.pop(); | 248 queue_.pop(); |
| 251 int max = NodeProperties::PastControlIndex(node); | 249 int max = NodeProperties::PastControlIndex(node); |
| 252 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { | 250 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { |
| 253 Queue(node->InputAt(i)); | 251 Queue(node->InputAt(i)); |
| 254 } | 252 } |
| 255 } | 253 } |
| 256 | 254 |
| 257 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { | 255 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { |
| 258 ConnectBlocks(*i); // Connect block to its predecessor/successors. | 256 ConnectBlocks(*i); // Connect block to its predecessor/successors. |
| 259 } | 257 } |
| 260 | |
| 261 FixNode(schedule_->end(), graph->end()); | |
| 262 } | 258 } |
| 263 | 259 |
| 264 // Run the control flow graph construction for a minimal control-connected | 260 // Run the control flow graph construction for a minimal control-connected |
| 265 // component ending in {node} and merge that component into an existing | 261 // component ending in {node} and merge that component into an existing |
| 266 // control flow graph at the bottom of {block}. | 262 // control flow graph at the bottom of {block}. |
| 267 void Run(BasicBlock* block, Node* node) { | 263 void Run(BasicBlock* block, Node* node) { |
| 268 Queue(node); | 264 Queue(node); |
| 269 | 265 |
| 270 component_start_ = block; | 266 component_start_ = block; |
| 271 component_end_ = schedule_->block(node); | 267 component_end_ = schedule_->block(node); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 286 | 282 |
| 287 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { | 283 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { |
| 288 scheduler_->GetData(*i)->is_floating_control_ = false; | 284 scheduler_->GetData(*i)->is_floating_control_ = false; |
| 289 ConnectBlocks(*i); // Connect block to its predecessor/successors. | 285 ConnectBlocks(*i); // Connect block to its predecessor/successors. |
| 290 } | 286 } |
| 291 } | 287 } |
| 292 | 288 |
| 293 private: | 289 private: |
| 294 void FixNode(BasicBlock* block, Node* node) { | 290 void FixNode(BasicBlock* block, Node* node) { |
| 295 schedule_->AddNode(block, node); | 291 schedule_->AddNode(block, node); |
| 296 scheduler_->GetData(node)->is_connected_control_ = true; | |
| 297 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 292 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 298 } | 293 } |
| 299 | 294 |
| 300 void Queue(Node* node) { | 295 void Queue(Node* node) { |
| 301 // Mark the connected control nodes as they queued. | 296 // Mark the connected control nodes as they are queued. |
| 302 Scheduler::SchedulerData* data = scheduler_->GetData(node); | 297 Scheduler::SchedulerData* data = scheduler_->GetData(node); |
| 303 if (!data->is_connected_control_) { | 298 if (!data->is_connected_control_) { |
| 299 data->is_connected_control_ = true; |
| 304 BuildBlocks(node); | 300 BuildBlocks(node); |
| 305 queue_.push(node); | 301 queue_.push(node); |
| 306 control_.push_back(node); | 302 control_.push_back(node); |
| 307 data->is_connected_control_ = true; | |
| 308 } | 303 } |
| 309 } | 304 } |
| 310 | 305 |
| 311 | 306 |
| 312 void BuildBlocks(Node* node) { | 307 void BuildBlocks(Node* node) { |
| 313 switch (node->opcode()) { | 308 switch (node->opcode()) { |
| 309 case IrOpcode::kEnd: |
| 310 FixNode(schedule_->end(), node); |
| 311 break; |
| 312 case IrOpcode::kStart: |
| 313 FixNode(schedule_->start(), node); |
| 314 break; |
| 314 case IrOpcode::kLoop: | 315 case IrOpcode::kLoop: |
| 315 case IrOpcode::kMerge: | 316 case IrOpcode::kMerge: |
| 316 case IrOpcode::kTerminate: | |
| 317 BuildBlockForNode(node); | 317 BuildBlockForNode(node); |
| 318 break; | 318 break; |
| 319 case IrOpcode::kTerminate: { |
| 320 // Put Terminate in the loop to which it refers. |
| 321 Node* loop = NodeProperties::GetControlInput(node); |
| 322 BasicBlock* block = BuildBlockForNode(loop); |
| 323 FixNode(block, node); |
| 324 break; |
| 325 } |
| 319 case IrOpcode::kBranch: | 326 case IrOpcode::kBranch: |
| 320 BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse); | 327 BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse); |
| 321 break; | 328 break; |
| 322 default: | 329 default: |
| 323 break; | 330 break; |
| 324 } | 331 } |
| 325 } | 332 } |
| 326 | 333 |
| 327 void ConnectBlocks(Node* node) { | 334 void ConnectBlocks(Node* node) { |
| 328 switch (node->opcode()) { | 335 switch (node->opcode()) { |
| 329 case IrOpcode::kLoop: | 336 case IrOpcode::kLoop: |
| 330 case IrOpcode::kMerge: | 337 case IrOpcode::kMerge: |
| 331 ConnectMerge(node); | 338 ConnectMerge(node); |
| 332 break; | 339 break; |
| 333 case IrOpcode::kBranch: | 340 case IrOpcode::kBranch: |
| 334 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 341 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 335 ConnectBranch(node); | 342 ConnectBranch(node); |
| 336 break; | 343 break; |
| 337 case IrOpcode::kReturn: | 344 case IrOpcode::kReturn: |
| 338 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 345 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
| 339 ConnectReturn(node); | 346 ConnectReturn(node); |
| 340 break; | 347 break; |
| 341 default: | 348 default: |
| 342 break; | 349 break; |
| 343 } | 350 } |
| 344 } | 351 } |
| 345 | 352 |
| 346 void BuildBlockForNode(Node* node) { | 353 BasicBlock* BuildBlockForNode(Node* node) { |
| 347 if (schedule_->block(node) == NULL) { | 354 BasicBlock* block = schedule_->block(node); |
| 348 BasicBlock* block = schedule_->NewBasicBlock(); | 355 if (block == NULL) { |
| 356 block = schedule_->NewBasicBlock(); |
| 349 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), | 357 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), |
| 350 node->op()->mnemonic()); | 358 node->op()->mnemonic()); |
| 351 FixNode(block, node); | 359 FixNode(block, node); |
| 352 } | 360 } |
| 361 return block; |
| 353 } | 362 } |
| 354 | 363 |
| 355 void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a, | 364 void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a, |
| 356 IrOpcode::Value b) { | 365 IrOpcode::Value b) { |
| 357 Node* successors[2]; | 366 Node* successors[2]; |
| 358 CollectSuccessorProjections(node, successors, a, b); | 367 CollectSuccessorProjections(node, successors, a, b); |
| 359 BuildBlockForNode(successors[0]); | 368 BuildBlockForNode(successors[0]); |
| 360 BuildBlockForNode(successors[1]); | 369 BuildBlockForNode(successors[1]); |
| 361 } | 370 } |
| 362 | 371 |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1356 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { | 1365 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { |
| 1357 schedule_->SetBlockForNode(to, *i); | 1366 schedule_->SetBlockForNode(to, *i); |
| 1358 scheduled_nodes_[to->id().ToSize()].push_back(*i); | 1367 scheduled_nodes_[to->id().ToSize()].push_back(*i); |
| 1359 } | 1368 } |
| 1360 nodes->clear(); | 1369 nodes->clear(); |
| 1361 } | 1370 } |
| 1362 | 1371 |
| 1363 } // namespace compiler | 1372 } // namespace compiler |
| 1364 } // namespace internal | 1373 } // namespace internal |
| 1365 } // namespace v8 | 1374 } // namespace v8 |
| OLD | NEW |