| 515 | LoopDescriptor::~LoopDescriptor() { ClearLoops(); } |
| 516 | |
| 517 | void LoopDescriptor::PopulateList(IRContext* context, const Function* f) { |
| 518 | DominatorAnalysis* dom_analysis = context->GetDominatorAnalysis(f); |
| 519 | |
| 520 | ClearLoops(); |
| 521 | |
| 522 | // Post-order traversal of the dominator tree to find all the OpLoopMerge |
| 523 | // instructions. |
| 524 | DominatorTree& dom_tree = dom_analysis->GetDomTree(); |
| 525 | for (DominatorTreeNode& node : |
| 526 | make_range(dom_tree.post_begin(), dom_tree.post_end())) { |
| 527 | Instruction* merge_inst = node.bb_->GetLoopMergeInst(); |
| 528 | if (merge_inst) { |
| 529 | bool all_backedge_unreachable = true; |
| 530 | for (uint32_t pid : context->cfg()->preds(node.bb_->id())) { |
| 531 | if (dom_analysis->IsReachable(pid) && |
| 532 | dom_analysis->Dominates(node.bb_->id(), pid)) { |
| 533 | all_backedge_unreachable = false; |
| 534 | break; |
| 535 | } |
| 536 | } |
| 537 | if (all_backedge_unreachable) |
| 538 | continue; // ignore this one, we actually never branch back. |
| 539 | |
| 540 | // The id of the merge basic block of this loop. |
| 541 | uint32_t merge_bb_id = merge_inst->GetSingleWordOperand(0); |
| 542 | |
| 543 | // The id of the continue basic block of this loop. |
| 544 | uint32_t continue_bb_id = merge_inst->GetSingleWordOperand(1); |
| 545 | |
| 546 | // The merge target of this loop. |
| 547 | BasicBlock* merge_bb = context->cfg()->block(merge_bb_id); |
| 548 | |
| 549 | // The continue target of this loop. |
| 550 | BasicBlock* continue_bb = context->cfg()->block(continue_bb_id); |
| 551 | |
| 552 | // The basic block containing the merge instruction. |
| 553 | BasicBlock* header_bb = context->get_instr_block(merge_inst); |
| 554 | |
| 555 | // Add the loop to the list of all the loops in the function. |
| 556 | Loop* current_loop = |
| 557 | new Loop(context, dom_analysis, header_bb, continue_bb, merge_bb); |
| 558 | loops_.push_back(current_loop); |
| 559 | |
| 560 | // We have a bottom-up construction, so if this loop has nested-loops, |
| 561 | // they are by construction at the tail of the loop list. |
| 562 | for (auto itr = loops_.rbegin() + 1; itr != loops_.rend(); ++itr) { |
| 563 | Loop* previous_loop = *itr; |
| 564 | |
| 565 | // If the loop already has a parent, then it has been processed. |
| 566 | if (previous_loop->HasParent()) continue; |
| 567 | |
| 568 | // If the current loop does not dominates the previous loop then it is |
| 569 | // not nested loop. |
| 570 | if (!dom_analysis->Dominates(header_bb, |
| 571 | previous_loop->GetHeaderBlock())) |
| 572 | continue; |
| 573 | // If the current loop merge dominates the previous loop then it is |
| 574 | // not nested loop. |
nothing calls this directly
no test coverage detected