| 457 | } |
| 458 | |
| 459 | bool LoopUtils::MakeLoopClosedSSA() { |
| 460 | if (!CreateLoopDedicatedExits()) { |
| 461 | return false; |
| 462 | } |
| 463 | |
| 464 | Function* function = loop_->GetHeaderBlock()->GetParent(); |
| 465 | CFG& cfg = *context_->cfg(); |
| 466 | DominatorTree& dom_tree = |
| 467 | context_->GetDominatorAnalysis(function)->GetDomTree(); |
| 468 | |
| 469 | std::unordered_set<BasicBlock*> exit_bb; |
| 470 | { |
| 471 | std::unordered_set<uint32_t> exit_bb_id; |
| 472 | loop_->GetExitBlocks(&exit_bb_id); |
| 473 | for (uint32_t bb_id : exit_bb_id) { |
| 474 | exit_bb.insert(cfg.block(bb_id)); |
| 475 | } |
| 476 | } |
| 477 | |
| 478 | LCSSARewriter lcssa_rewriter(context_, dom_tree, exit_bb, |
| 479 | loop_->GetMergeBlock()); |
| 480 | if (!MakeSetClosedSSA(context_, function, loop_->GetBlocks(), exit_bb, |
| 481 | &lcssa_rewriter)) { |
| 482 | return false; |
| 483 | } |
| 484 | |
| 485 | // Make sure all defs post-dominated by the merge block have their last use no |
| 486 | // further than the merge block. |
| 487 | if (loop_->GetMergeBlock()) { |
| 488 | std::unordered_set<uint32_t> merging_bb_id; |
| 489 | loop_->GetMergingBlocks(&merging_bb_id); |
| 490 | merging_bb_id.erase(loop_->GetMergeBlock()->id()); |
| 491 | // Reset the exit set, now only the merge block is the exit. |
| 492 | exit_bb.clear(); |
| 493 | exit_bb.insert(loop_->GetMergeBlock()); |
| 494 | // LCSSARewriter is reusable here only because it forces the creation of a |
| 495 | // phi instruction in the merge block. |
| 496 | if (!MakeSetClosedSSA(context_, function, merging_bb_id, exit_bb, |
| 497 | &lcssa_rewriter)) { |
| 498 | return false; |
| 499 | } |
| 500 | } |
| 501 | |
| 502 | context_->InvalidateAnalysesExceptFor( |
| 503 | IRContext::Analysis::kAnalysisCFG | |
| 504 | IRContext::Analysis::kAnalysisDominatorAnalysis | |
| 505 | IRContext::Analysis::kAnalysisLoopAnalysis); |
| 506 | return true; |
| 507 | } |
| 508 | |
| 509 | Loop* LoopUtils::CloneLoop(LoopCloningResult* cloning_result) const { |
| 510 | // Compute the structured order of the loop basic blocks and store it in the |
no test coverage detected