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 "src/compiler/schedule.h" | 5 #include "src/compiler/schedule.h" |
6 | 6 |
7 #include "src/compiler/node.h" | 7 #include "src/compiler/node.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 #include "src/ostreams.h" | 9 #include "src/ostreams.h" |
10 | 10 |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 MoveSuccessors(block, end); | 291 MoveSuccessors(block, end); |
292 for (size_t index = 0; index < succ_count; ++index) { | 292 for (size_t index = 0; index < succ_count; ++index) { |
293 AddSuccessor(block, succ_blocks[index]); | 293 AddSuccessor(block, succ_blocks[index]); |
294 } | 294 } |
295 if (block->control_input() != nullptr) { | 295 if (block->control_input() != nullptr) { |
296 SetControlInput(end, block->control_input()); | 296 SetControlInput(end, block->control_input()); |
297 } | 297 } |
298 SetControlInput(block, sw); | 298 SetControlInput(block, sw); |
299 } | 299 } |
300 | 300 |
| 301 void Schedule::EnsureSplitEdgeForm() { |
| 302 // Make a copy of all the blocks for the iteration, since adding the split |
| 303 // edges will allocate new blocks. |
| 304 BasicBlockVector all_blocks_copy(all_blocks_); |
| 305 |
| 306 // Insert missing split edge blocks. |
| 307 for (auto block : all_blocks_copy) { |
| 308 if (block->PredecessorCount() > 1 && block != end_) { |
| 309 for (auto current_pred = block->predecessors().begin(); |
| 310 current_pred != block->predecessors().end(); ++current_pred) { |
| 311 BasicBlock* pred = *current_pred; |
| 312 if (pred->SuccessorCount() > 1) { |
| 313 // Found a predecessor block with multiple successors. |
| 314 BasicBlock* split_edge_block = NewBasicBlock(); |
| 315 split_edge_block->set_control(BasicBlock::kGoto); |
| 316 split_edge_block->successors().push_back(block); |
| 317 split_edge_block->predecessors().push_back(pred); |
| 318 split_edge_block->set_deferred(pred->deferred()); |
| 319 *current_pred = split_edge_block; |
| 320 // Find a corresponding successor in the previous block, replace it |
| 321 // with the split edge block... but only do it once, since we only |
| 322 // replace the previous blocks in the current block one at a time. |
| 323 for (auto successor = pred->successors().begin(); |
| 324 successor != pred->successors().end(); ++successor) { |
| 325 if (*successor == block) { |
| 326 *successor = split_edge_block; |
| 327 break; |
| 328 } |
| 329 } |
| 330 } |
| 331 } |
| 332 } |
| 333 } |
| 334 } |
| 335 |
| 336 void Schedule::PropagateDeferredMark() { |
| 337 // Push forward the deferred block marks through newly inserted blocks and |
| 338 // other improperly marked blocks until a fixed point is reached. |
| 339 // TODO(danno): optimize the propagation |
| 340 bool done = false; |
| 341 while (!done) { |
| 342 done = true; |
| 343 for (auto block : all_blocks_) { |
| 344 if (!block->deferred()) { |
| 345 bool deferred = block->PredecessorCount() > 0; |
| 346 for (auto pred : block->predecessors()) { |
| 347 if (!pred->deferred()) { |
| 348 deferred = false; |
| 349 } |
| 350 } |
| 351 if (deferred) { |
| 352 block->set_deferred(true); |
| 353 done = false; |
| 354 } |
| 355 } |
| 356 } |
| 357 } |
| 358 } |
301 | 359 |
302 void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) { | 360 void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) { |
303 block->AddSuccessor(succ); | 361 block->AddSuccessor(succ); |
304 succ->AddPredecessor(block); | 362 succ->AddPredecessor(block); |
305 } | 363 } |
306 | 364 |
307 | 365 |
308 void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) { | 366 void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) { |
309 for (BasicBlock* const successor : from->successors()) { | 367 for (BasicBlock* const successor : from->successors()) { |
310 to->AddSuccessor(successor); | 368 to->AddSuccessor(successor); |
(...skipping 13 matching lines...) Expand all Loading... |
324 | 382 |
325 void Schedule::SetBlockForNode(BasicBlock* block, Node* node) { | 383 void Schedule::SetBlockForNode(BasicBlock* block, Node* node) { |
326 if (node->id() >= nodeid_to_block_.size()) { | 384 if (node->id() >= nodeid_to_block_.size()) { |
327 nodeid_to_block_.resize(node->id() + 1); | 385 nodeid_to_block_.resize(node->id() + 1); |
328 } | 386 } |
329 nodeid_to_block_[node->id()] = block; | 387 nodeid_to_block_[node->id()] = block; |
330 } | 388 } |
331 | 389 |
332 | 390 |
333 std::ostream& operator<<(std::ostream& os, const Schedule& s) { | 391 std::ostream& operator<<(std::ostream& os, const Schedule& s) { |
334 for (BasicBlock* block : *s.rpo_order()) { | 392 for (BasicBlock* block : |
335 os << "--- BLOCK B" << block->rpo_number(); | 393 ((s.RpoBlockCount() == 0) ? *s.all_blocks() : *s.rpo_order())) { |
| 394 if (block->rpo_number() == -1) { |
| 395 os << "--- BLOCK B" << block->id().ToInt() << " (block id)"; |
| 396 } else { |
| 397 os << "--- BLOCK B" << block->rpo_number(); |
| 398 } |
336 if (block->deferred()) os << " (deferred)"; | 399 if (block->deferred()) os << " (deferred)"; |
337 if (block->PredecessorCount() != 0) os << " <- "; | 400 if (block->PredecessorCount() != 0) os << " <- "; |
338 bool comma = false; | 401 bool comma = false; |
339 for (BasicBlock const* predecessor : block->predecessors()) { | 402 for (BasicBlock const* predecessor : block->predecessors()) { |
340 if (comma) os << ", "; | 403 if (comma) os << ", "; |
341 comma = true; | 404 comma = true; |
342 os << "B" << predecessor->rpo_number(); | 405 if (predecessor->rpo_number() == -1) { |
| 406 os << "B" << predecessor->id().ToInt(); |
| 407 } else { |
| 408 os << "B" << predecessor->rpo_number(); |
| 409 } |
343 } | 410 } |
344 os << " ---\n"; | 411 os << " ---\n"; |
345 for (Node* node : *block) { | 412 for (Node* node : *block) { |
346 os << " " << *node; | 413 os << " " << *node; |
347 if (NodeProperties::IsTyped(node)) { | 414 if (NodeProperties::IsTyped(node)) { |
348 Type* type = NodeProperties::GetType(node); | 415 Type* type = NodeProperties::GetType(node); |
349 os << " : "; | 416 os << " : "; |
350 type->PrintTo(os); | 417 type->PrintTo(os); |
351 } | 418 } |
352 os << "\n"; | 419 os << "\n"; |
353 } | 420 } |
354 BasicBlock::Control control = block->control(); | 421 BasicBlock::Control control = block->control(); |
355 if (control != BasicBlock::kNone) { | 422 if (control != BasicBlock::kNone) { |
356 os << " "; | 423 os << " "; |
357 if (block->control_input() != nullptr) { | 424 if (block->control_input() != nullptr) { |
358 os << *block->control_input(); | 425 os << *block->control_input(); |
359 } else { | 426 } else { |
360 os << "Goto"; | 427 os << "Goto"; |
361 } | 428 } |
362 os << " -> "; | 429 os << " -> "; |
363 comma = false; | 430 comma = false; |
364 for (BasicBlock const* successor : block->successors()) { | 431 for (BasicBlock const* successor : block->successors()) { |
365 if (comma) os << ", "; | 432 if (comma) os << ", "; |
366 comma = true; | 433 comma = true; |
367 os << "B" << successor->rpo_number(); | 434 if (successor->rpo_number() == -1) { |
| 435 os << "B" << successor->id().ToInt(); |
| 436 } else { |
| 437 os << "B" << successor->rpo_number(); |
| 438 } |
368 } | 439 } |
369 os << "\n"; | 440 os << "\n"; |
370 } | 441 } |
371 } | 442 } |
372 return os; | 443 return os; |
373 } | 444 } |
374 | 445 |
375 } // namespace compiler | 446 } // namespace compiler |
376 } // namespace internal | 447 } // namespace internal |
377 } // namespace v8 | 448 } // namespace v8 |
OLD | NEW |