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

Method GetOrCreateSimpleLoopPreheader

source/fuzz/fuzzer_pass.cpp:619–678  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

617}
618
619opt::BasicBlock* FuzzerPass::GetOrCreateSimpleLoopPreheader(
620 uint32_t header_id) {
621 auto header_block = fuzzerutil::MaybeFindBlock(GetIRContext(), header_id);
622
623 assert(header_block && header_block->IsLoopHeader() &&
624 "|header_id| should be the label id of a loop header");
625
626 auto predecessors = GetIRContext()->cfg()->preds(header_id);
627
628 assert(predecessors.size() >= 2 &&
629 "The block |header_id| should be reachable.");
630
631 auto function = header_block->GetParent();
632
633 if (predecessors.size() == 2) {
634 // The header has a single out-of-loop predecessor, which could be a
635 // preheader.
636
637 opt::BasicBlock* maybe_preheader;
638
639 if (GetIRContext()->GetDominatorAnalysis(function)->Dominates(
640 header_id, predecessors[0])) {
641 // The first predecessor is the back-edge block, because the header
642 // dominates it, so the second one is out of the loop.
643 maybe_preheader = &*function->FindBlock(predecessors[1]);
644 } else {
645 // The first predecessor is out of the loop.
646 maybe_preheader = &*function->FindBlock(predecessors[0]);
647 }
648
649 // |maybe_preheader| is a preheader if it branches unconditionally to
650 // the header. We also require it not to be a loop header.
651 if (maybe_preheader->terminator()->opcode() == spv::Op::OpBranch &&
652 !maybe_preheader->IsLoopHeader()) {
653 return maybe_preheader;
654 }
655 }
656
657 // We need to add a preheader.
658
659 // Get a fresh id for the preheader.
660 uint32_t preheader_id = GetFuzzerContext()->GetFreshId();
661
662 // Get a fresh id for each OpPhi instruction, if there is more than one
663 // out-of-loop predecessor.
664 std::vector<uint32_t> phi_ids;
665 if (predecessors.size() > 2) {
666 header_block->ForEachPhiInst(
667 [this, &phi_ids](opt::Instruction* /* unused */) {
668 phi_ids.push_back(GetFuzzerContext()->GetFreshId());
669 });
670 }
671
672 // Add the preheader.
673 ApplyTransformation(
674 TransformationAddLoopPreheader(header_id, preheader_id, phi_ids));
675
676 // Make the newly-created preheader the new entry block.

Callers

nothing calls this directly

Calls 14

MaybeFindBlockFunction · 0.85
IsLoopHeaderMethod · 0.80
GetDominatorAnalysisMethod · 0.80
FindBlockMethod · 0.80
GetFreshIdMethod · 0.80
ForEachPhiInstMethod · 0.80
cfgMethod · 0.45
sizeMethod · 0.45
GetParentMethod · 0.45
DominatesMethod · 0.45
opcodeMethod · 0.45

Tested by

no test coverage detected