MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / PopulateList

Method PopulateList

source/opt/loop_descriptor.cpp:517–594  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

515LoopDescriptor::~LoopDescriptor() { ClearLoops(); }
516
517void 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.

Callers

nothing calls this directly

Calls 15

make_rangeFunction · 0.85
GetDominatorAnalysisMethod · 0.80
GetLoopMergeInstMethod · 0.80
GetSingleWordOperandMethod · 0.80
get_instr_blockMethod · 0.80
rbeginMethod · 0.80
rendMethod · 0.80
HasParentMethod · 0.80
AddNestedLoopMethod · 0.80
GetTreeNodeMethod · 0.80
df_beginMethod · 0.80
df_endMethod · 0.80

Tested by

no test coverage detected