1//===-- SPIRVStructurizer.cpp ----------------------*- C++ -*-===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9//===----------------------------------------------------------------------===// 26#include "llvm/IR/IntrinsicsSPIRV.h" 36#include <unordered_set> 47usingBlockSet = std::unordered_set<BasicBlock *>;
48usingEdge = std::pair<BasicBlock *, BasicBlock *>;
50// Helper function to do a partial order visit from the block |Start|, calling 51// |Op| on each visited node. 55V.partialOrderVisit(Start,
Op);
58// Returns the exact convergence region in the tree defined by `Node` for which 59// `BB` is the header, nullptr otherwise. 65for (
auto *Child :
Node->Children) {
66constauto *CR = getRegionForHeader(Child, BB);
73// Returns the single BasicBlock exiting the convergence region `CR`, 74// nullptr if no such exit exists. 76 std::unordered_set<BasicBlock *> ExitTargets;
84assert(ExitTargets.size() <= 1);
85if (ExitTargets.size() == 0)
88return *ExitTargets.begin();
91// Returns the merge block designated by I if I is a merge instruction, nullptr 98if (
II->getIntrinsicID() != Intrinsic::spv_loop_merge &&
99II->getIntrinsicID() != Intrinsic::spv_selection_merge)
106// Returns the continue block designated by I if I is an OpLoopMerge, nullptr 113if (
II->getIntrinsicID() != Intrinsic::spv_loop_merge)
120// Returns true if Header has one merge instruction which designated Merge as 123for (
auto &
I : Header) {
131// Returns true if the BB has one OpLoopMerge instruction. 134if (getDesignatedContinueBlock(&
I))
139// Returns true is I is an OpSelectionMerge or OpLoopMerge instruction, false 142return getDesignatedMergeBlock(
I) !=
nullptr;
145// Returns all blocks in F having at least one OpLoopMerge or OpSelectionMerge 151if (getDesignatedMergeBlock(&
I) !=
nullptr)
158// Returns all basic blocks in |F| referenced by at least 1 159// OpSelectionMerge/OpLoopMerge instruction. 172// Return all the merge instructions contained in BB. 173// Note: the SPIR-V spec doesn't allow a single BB to contain more than 1 merge 174// instruction, but this can happen while we structurize the CFG. 175std::vector<Instruction *> getMergeInstructions(
BasicBlock &BB) {
176 std::vector<Instruction *> Output;
178if (isMergeInstruction(&
I))
179 Output.push_back(&
I);
183// Returns all basic blocks in |F| referenced as continue target by at least 1 184// OpLoopMerge instruction. 197// Do a preorder traversal of the CFG starting from the BB |Start|. 198// point. Calls |op| on each basic block encountered during the traversal. 200 std::stack<BasicBlock *> ToVisit;
203 ToVisit.push(&Start);
204 Seen.
insert(ToVisit.top());
205while (ToVisit.size() != 0) {
221// Replaces the conditional and unconditional branch targets of |BB| by 222// |NewTarget| if the target was |OldTarget|. This function also makes sure the 223// associated merge instruction gets updated accordingly. 228// 1. Replace all matching successors. 229for (
size_t i = 0; i < BI->getNumSuccessors(); i++) {
230if (BI->getSuccessor(i) == OldTarget)
231 BI->setSuccessor(i, NewTarget);
234// Branch was unconditional, no fixup required. 235if (BI->isUnconditional())
238// Branch had 2 successors, maybe now both are the same? 239if (BI->getSuccessor(0) != BI->getSuccessor(1))
242// Note: we may end up here because the original IR had such branches. 243// This means Target is not necessarily equal to NewTarget. 245 Builder.SetInsertPoint(BI);
246 Builder.CreateBr(BI->getSuccessor(0));
247 BI->eraseFromParent();
249// The branch was the only instruction, nothing else to do. 253// Otherwise, we need to check: was there an OpSelectionMerge before this 254// branch? If we removed the OpBranchConditional, we must also remove the 255// OpSelectionMerge. This is not valid for OpLoopMerge: 258if (!
II ||
II->getIntrinsicID() != Intrinsic::spv_selection_merge)
262II->eraseFromParent();
263if (!
C->isConstantUsed())
267// Replaces the target of branch instruction in |BB| with |NewTarget| if it 268// was |OldTarget|. This function also fixes the associated merge instruction. 269// Note: this function does not simplify branching instructions, it only updates 270// targets. See also: simplifyBranches. 274if (isa<ReturnInst>(
T))
277if (isa<BranchInst>(
T))
278return replaceIfBranchTargets(BB, OldTarget, NewTarget);
280if (
auto *SI = dyn_cast<SwitchInst>(
T)) {
281for (
size_t i = 0; i <
SI->getNumSuccessors(); i++) {
282if (
SI->getSuccessor(i) == OldTarget)
283SI->setSuccessor(i, NewTarget);
288assert(
false &&
"Unhandled terminator type.");
291}
// anonymous namespace 293// Given a reducible CFG, produces a structurized CFG in the SPIR-V sense, 294// adding merge instructions when required. 297structDivergentConstruct;
298// Represents a list of condition/loops/switch constructs. 299// See SPIR-V 2.11.2. Structured Control-flow Constructs for the list of 301usingConstructList = std::vector<std::unique_ptr<DivergentConstruct>>;
303// Represents a divergent construct in the SPIR-V sense. 304// Such constructs are represented by a header (entry), a merge block (exit), 305// and possibly a continue block (back-edge). A construct can contain other 306// constructs, but their boundaries do not cross. 307structDivergentConstruct {
312 DivergentConstruct *Parent =
nullptr;
313 ConstructList Children;
316// An helper class to clean the construct boundaries. 317// It is used to gather the list of blocks that should belong to each 318// divergent construct, and possibly modify CFG edges when exits would cross 319// the boundary of multiple constructs. 333// Returns the list of blocks that belong to a SPIR-V loop construct, 334// including the continue construct. 335 std::vector<BasicBlock *> getLoopConstructBlocks(
BasicBlock *Header,
338 std::vector<BasicBlock *> Output;
339 partialOrderVisit(*Header, [&](
BasicBlock *BB) {
344 Output.push_back(BB);
350// Returns the list of blocks that belong to a SPIR-V selection construct. 351 std::vector<BasicBlock *>
352 getSelectionConstructBlocks(DivergentConstruct *Node) {
354 BlockSet OutsideBlocks;
355 OutsideBlocks.insert(Node->Merge);
357for (DivergentConstruct *It = Node->Parent; It !=
nullptr;
359 OutsideBlocks.insert(It->Merge);
361 OutsideBlocks.insert(It->Continue);
364 std::vector<BasicBlock *> Output;
365 partialOrderVisit(*Node->Header, [&](
BasicBlock *BB) {
366 if (OutsideBlocks.count(BB) != 0)
368 if (DT.dominates(Node->Merge, BB) || !DT.dominates(Node->Header, BB))
370 Output.push_back(BB);
376// Returns the list of blocks that belong to a SPIR-V switch construct. 377 std::vector<BasicBlock *> getSwitchConstructBlocks(
BasicBlock *Header,
381 std::vector<BasicBlock *> Output;
382 partialOrderVisit(*Header, [&](
BasicBlock *BB) {
383// the blocks structurally dominated by a switch header, 386// excluding blocks structurally dominated by the switch header’s merge 390 Output.push_back(BB);
396// Returns the list of blocks that belong to a SPIR-V case construct. 401 std::vector<BasicBlock *> Output;
403// the blocks structurally dominated by an OpSwitch Target or Default 407// excluding the blocks structurally dominated by the OpSwitch 408// construct’s corresponding merge block. 411 Output.push_back(BB);
417// Splits the given edges by recreating proxy nodes so that the destination 418// has unique incoming edges from this region. 422// In SPIR-V, constructs must have a single exit/merge. 423// Given nodes A and B in the construct, a node C outside, and the following edges. 427// In such cases, we must create a new exit node D, that belong to the construct to make is viable: 431// This is fine (assuming C has no PHI nodes), but requires handling the merge instruction here. 432// By adding a proxy node, we create a regular divergent shape which can easily be regularized later on. 436// A, B, D belongs to the construct. D is the exit. D1 and D2 are empty. 440 createAliasBlocksForComplexEdges(std::vector<Edge> Edges) {
441 std::unordered_set<BasicBlock *> Seen;
442 std::vector<Edge> Output;
445for (
auto &[Src, Dst] : Edges) {
446auto [Iterator, Inserted] = Seen.insert(Src);
448// Src already a source node. Cannot have 2 edges from A to B. 449// Creating alias source block. 451F.getContext(), Src->getName() +
".new.src", &
F);
452 replaceBranchTargets(Src, Dst, NewSrc);
458 Output.emplace_back(Src, Dst);
471// Given a construct defined by |Header|, and a list of exiting edges 472// |Edges|, creates a new single exit node, fixing up those edges. 474 std::vector<Edge> &Edges) {
476 std::vector<Edge> FixedEdges = createAliasBlocksForComplexEdges(Edges);
478 std::vector<BasicBlock *> Dsts;
479 std::unordered_map<BasicBlock *, ConstantInt *> DstToIndex;
481 Header->getName() +
".new.exit", &
F);
483for (
auto &[Src, Dst] : FixedEdges) {
484if (DstToIndex.count(Dst) != 0)
486 DstToIndex.emplace(Dst, ExitBuilder.
getInt32(DstToIndex.size()));
490if (Dsts.size() == 1) {
491for (
auto &[Src, Dst] : FixedEdges) {
492 replaceBranchTargets(Src, Dst, NewExit);
499F.begin()->getFirstInsertionPt());
500for (
auto &[Src, Dst] : FixedEdges) {
504 replaceBranchTargets(Src, Dst, NewExit);
510// If we can avoid an OpSwitch, generate an OpBranch. Reason is some 511// OpBranch are allowed to exist without a new OpSelectionMerge if one of 512// the branch is the parent's merge node, while OpSwitches are not. 513if (Dsts.size() == 2) {
521for (
auto It = Dsts.begin() + 1; It != Dsts.end(); ++It) {
522 Sw->
addCase(DstToIndex[*It], *It);
528 /// Create a value in BB set to the value associated with the branch the block 529 /// terminator will take. 530Value *createExitVariable(
534if (isa<ReturnInst>(
T))
540if (
auto *BI = dyn_cast<BranchInst>(
T)) {
544 BI->isConditional() ? BI->getSuccessor(1) :
nullptr;
547 ? TargetToValue.
at(LHSTarget)
550 ? TargetToValue.
at(RHSTarget)
553if (
LHS ==
nullptr ||
RHS ==
nullptr)
558// TODO: add support for switch cases. 562// Creates a new basic block in F with a single OpUnreachable instruction. 570// Add OpLoopMerge instruction on cycles. 572LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
573auto *TopLevelRegion =
574 getAnalysis<SPIRVConvergenceRegionAnalysisWrapperPass>()
576 .getTopLevelRegion();
580// Not a loop header. Ignoring for now. 585// This loop header is not the entrance of a convergence region. Ignoring 587auto *CR = getRegionForHeader(TopLevelRegion, &BB);
593auto *
Merge = getExitFor(CR);
594// We are indeed in a loop, but there are no exits (infinite loop). 595// This could be caused by a bad shader, but also could be an artifact 596// from an earlier optimization. It is not always clear if structurally 597// reachable means runtime reachable, so we cannot error-out. What we must 598// do however is to make is legal on the SPIR-V point of view, hence 599// adding an unreachable merge block. 600if (
Merge ==
nullptr) {
603"This assumes the branch is not a switch. Maybe that's wrong?");
606Merge = CreateUnreachable(
F);
626// Adds an OpSelectionMerge to the immediate dominator or each node with an 627// in-degree of 2 or more which is not already the merge target of an 628// OpLoopMerge/OpSelectionMerge. 629bool addMergeForNodesWithMultiplePredecessors(
Function &
F) {
638if (hasLoopMergeInstruction(BB) &&
pred_size(&BB) <= 2)
644if (isDefinedAsSelectionMergeBy(*Header, BB))
659// When a block has multiple OpSelectionMerge/OpLoopMerge instructions, sorts 660// them to put the "largest" first. A merge instruction is defined as larger 661// than another when its target merge block post-dominates the other target's 662// merge block. (This ordering should match the nesting ordering of the source 665 std::vector<Instruction *> MergeInstructions;
667if (isMergeInstruction(&
I))
668 MergeInstructions.push_back(&
I);
670if (MergeInstructions.size() <= 1)
676 std::sort(MergeInstructions.begin(), MergeInstructions.end(),
680 BasicBlock *RightMerge = getDesignatedMergeBlock(Right);
681 BasicBlock *LeftMerge = getDesignatedMergeBlock(Left);
682 return !Visitor.compare(RightMerge, LeftMerge);
693// Sorts selection merge headers in |F|. 694// A is sorted before B if the merge block designated by B is an ancestor of 695// the one designated by A. 696bool sortSelectionMergeHeaders(
Function &
F) {
704// Split basic blocks containing multiple OpLoopMerge/OpSelectionMerge 705// instructions so each basic block contains only a single merge instruction. 706bool splitBlocksWithMultipleHeaders(
Function &
F) {
707 std::stack<BasicBlock *> Work;
709 std::vector<Instruction *> MergeInstructions = getMergeInstructions(BB);
710if (MergeInstructions.size() <= 1)
716while (Work.size() > 0) {
720 std::vector<Instruction *> MergeInstructions =
721 getMergeInstructions(*Header);
722for (
unsigned i = 1; i < MergeInstructions.size(); i++) {
724 Header->splitBasicBlock(MergeInstructions[i],
"new.header");
726if (getDesignatedContinueBlock(MergeInstructions[0]) ==
nullptr) {
729BranchInst *BI = cast<BranchInst>(Header->getTerminator());
743// Adds an OpSelectionMerge to each block with an out-degree >= 2 which 744// doesn't already have an OpSelectionMerge. 745bool addMergeForDivergentBlocks(
Function &
F) {
750auto MergeBlocks = getMergeBlocks(
F);
751auto ContinueBlocks = getContinueBlocks(
F);
754if (getMergeInstructions(BB).
size() != 0)
757 std::vector<BasicBlock *> Candidates;
766if (Candidates.size() <= 1)
781// Gather all the exit nodes for the construct header by |Header| and 782// containing the blocks |Construct|. 783 std::vector<Edge> getExitsFrom(
const BlockSet &Construct,
785 std::vector<Edge> Output;
787if (Construct.count(Item) == 0)
800// Build a divergent construct tree searching from |BB|. 801// If |Parent| is not null, this tree is attached to the parent's tree. 802void constructDivergentConstruct(BlockSet &Visited, Splitter &S,
804if (Visited.count(BB) != 0)
808auto MIS = getMergeInstructions(*BB);
809if (MIS.size() == 0) {
811 constructDivergentConstruct(Visited, S,
Successor, Parent);
821auto Output = std::make_unique<DivergentConstruct>();
823 Output->Merge =
Merge;
825 Output->Parent = Parent;
827 constructDivergentConstruct(Visited, S,
Merge, Parent);
829 constructDivergentConstruct(Visited, S,
Continue, Output.get());
832 constructDivergentConstruct(Visited, S,
Successor, Output.get());
835 Parent->Children.emplace_back(std::move(Output));
838// Returns the blocks belonging to the divergent construct |Node|. 839 BlockSet getConstructBlocks(Splitter &S, DivergentConstruct *Node) {
840assert(Node->Header && Node->Merge);
843auto LoopBlocks = S.getLoopConstructBlocks(Node->Header, Node->Merge);
844return BlockSet(LoopBlocks.begin(), LoopBlocks.end());
847auto SelectionBlocks = S.getSelectionConstructBlocks(Node);
848return BlockSet(SelectionBlocks.begin(), SelectionBlocks.end());
851// Fixup the construct |Node| to respect a set of rules defined by the SPIR-V 853bool fixupConstruct(Splitter &S, DivergentConstruct *Node) {
855for (
auto &Child : Node->Children)
856Modified |= fixupConstruct(S, Child.get());
858// This construct is the root construct. Does not represent any real 859// construct, just a way to access the first level of the forest. 860if (Node->Parent ==
nullptr)
863// This node's parent is the root. Meaning this is a top-level construct. 864// There can be multiple exists, but all are guaranteed to exit at most 1 865// construct since we are at first level. 866if (Node->Parent->Header ==
nullptr)
869// Health check for the structure. 870assert(Node->Header && Node->Merge);
871assert(Node->Parent->Header && Node->Parent->Merge);
873 BlockSet ConstructBlocks = getConstructBlocks(S, Node);
874auto Edges = getExitsFrom(ConstructBlocks, *Node->Header);
876// No edges exiting the construct. 880bool HasBadEdge = Node->Merge == Node->Parent->Merge ||
881 Node->Merge == Node->Parent->Continue;
882// BasicBlock *Target = Edges[0].second; 883for (
auto &[Src, Dst] : Edges) {
884// - Breaking from a selection construct: S is a selection construct, S is 885// the innermost structured 886// control-flow construct containing A, and B is the merge block for S 887// - Breaking from the innermost loop: S is the innermost loop construct 889// and B is the merge block for S 890if (Node->Merge == Dst)
893// Entering the innermost loop’s continue construct: S is the innermost 894// loop construct containing A, and B is the continue target for S 895if (Node->Continue == Dst)
898// TODO: what about cases branching to another case in the switch? Seems 899// to work, but need to double check. 906// Create a single exit node gathering all exit edges. 907BasicBlock *NewExit = S.createSingleExitNode(Node->Header, Edges);
909// Fixup this construct's merge node to point to the new exit. 910// Note: this algorithm fixes inner-most divergence construct first. So 911// recursive structures sharing a single merge node are fixed from the 912// inside toward the outside. 913auto MergeInstructions = getMergeInstructions(*Node->Header);
914assert(MergeInstructions.size() == 1);
919I->setOperand(0, MergeAddress);
922// Clean up of the possible dangling BockAddr operands to prevent MIR 923// comments about "address of removed block taken". 927 Node->Merge = NewExit;
928// Regenerate the dom trees. 934LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
937 DivergentConstruct Root;
939 constructDivergentConstruct(Visited, S, &*
F.begin(), &Root);
940return fixupConstruct(S, &Root);
943// Simplify branches when possible: 944// - if the 2 sides of a conditional branch are the same, transforms it to an 945// unconditional branch. 946// - if a switch has only 2 distinct successors, converts it to a conditional 955if (SI->getNumCases() > 1)
962if (SI->getNumCases() == 0) {
963 Builder.
CreateBr(SI->getDefaultDest());
967 SI->case_begin()->getCaseValue());
968 Builder.
CreateCondBr(Condition, SI->case_begin()->getCaseSuccessor(),
969 SI->getDefaultDest());
971 SI->eraseFromParent();
977// Makes sure every case target in |F| is unique. If 2 cases branch to the 978// same basic block, one of the targets is updated so it jumps to a new basic 979// block ending with a single unconditional branch to the original target. 989 Seen.
insert(SI->getDefaultDest());
991auto It = SI->case_begin();
992while (It != SI->case_end()) {
994if (Seen.count(
Target) == 0) {
1005 SI->addCase(It->getCaseValue(), NewTarget);
1006 It = SI->removeCase(It);
1013// Removes blocks not contributing to any structured CFG. This assumes there 1018auto MergeBlocks = getMergeBlocks(
F);
1019auto ContinueBlocks = getContinueBlocks(
F);
1028if (MergeBlocks.count(&BB) != 0 || ContinueBlocks.count(&BB) != 0)
1035 std::vector<BasicBlock *> Predecessors(
predecessors(&BB).begin(),
1038 replaceBranchTargets(Predecessor, &BB,
Successor);
1048bool addHeaderToRemainingDivergentDAG(
Function &
F) {
1051auto MergeBlocks = getMergeBlocks(
F);
1052auto ContinueBlocks = getContinueBlocks(
F);
1053auto HeaderBlocks = getHeaderBlocks(
F);
1061if (HeaderBlocks.count(&BB) != 0)
1066size_t CandidateEdges = 0;
1073 CandidateEdges += 1;
1076if (CandidateEdges <= 1)
1082bool HasBadBlock =
false;
1088if (Node == Header || Node ==
Merge)
1091 HasBadBlock |= MergeBlocks.count(Node) != 0 ||
1092 ContinueBlocks.count(Node) != 0 ||
1093 HeaderBlocks.count(Node) != 0;
1102if (
Merge ==
nullptr) {
1113if (isMergeInstruction(SplitInstruction->
getPrevNode()))
1114 SplitInstruction = SplitInstruction->
getPrevNode();
1116Merge->splitBasicBlockBefore(SplitInstruction,
"new.merge");
1138// In LLVM, Switches are allowed to have several cases branching to the same 1139// basic block. This is allowed in SPIR-V, but can make structurizing SPIR-V 1140// harder, so first remove edge cases. 1143// LLVM allows conditional branches to have both side jumping to the same 1144// block. It also allows switched to have a single default, or just one 1145// case. Cleaning this up now. 1148// At this state, we should have a reducible CFG with cycles. 1149// STEP 1: Adding OpLoopMerge instructions to loop headers. 1152// STEP 2: adding OpSelectionMerge to each node with an in-degree >= 2. 1153Modified |= addMergeForNodesWithMultiplePredecessors(
F);
1156// Sort selection merge, the largest construct goes first. 1157// This simplifies the next step. 1158Modified |= sortSelectionMergeHeaders(
F);
1160// STEP 4: As this stage, we can have a single basic block with multiple 1161// OpLoopMerge/OpSelectionMerge instructions. Splitting this block so each 1162// BB has a single merge instruction. 1163Modified |= splitBlocksWithMultipleHeaders(
F);
1165// STEP 5: In the previous steps, we added merge blocks the loops and 1166// natural merge blocks (in-degree >= 2). What remains are conditions with 1167// an exiting branch (return, unreachable). In such case, we must start from 1168// the header, and add headers to divergent construct with no headers. 1169Modified |= addMergeForDivergentBlocks(
F);
1171// STEP 6: At this stage, we have several divergent construct defines by a 1172// header and a merge block. But their boundaries have no constraints: a 1173// construct exit could be outside of the parents' construct exit. Such 1174// edges are called critical edges. What we need is to split those edges 1175// into several parts. Each part exiting the parent's construct by its merge 1179// STEP 7: The previous steps possibly created a lot of "proxy" blocks. 1180// Blocks with a single unconditional branch, used to create a valid 1181// divergent construct tree. Some nodes are still requires (e.g: nodes 1182// allowing a valid exit through the parent's merge block). But some are 1183// left-overs of past transformations, and could cause actual validation 1184// issues. E.g: the SPIR-V spec allows a construct to break to the parents 1185// loop construct without an OpSelectionMerge, but this requires a straight 1186// jump. If a proxy block lies between the conditional branch and the 1187// parent's merge, the CFG is not valid. 1190// STEP 8: Final fix-up steps: our tree boundaries are correct, but some 1191// blocks are branching with no header. Those are often simple conditional 1192// branches with 1 or 2 returning edges. Adding a header for those. 1193Modified |= addHeaderToRemainingDivergentDAG(
F);
1195// STEP 9: sort basic blocks to match both the LLVM & SPIR-V requirements. 1219"invalid metadata hlsl.controlflow.hint");
1222assert(BranchHint &&
"invalid metadata value for hlsl.controlflow.hint");
1228 {MergeAddress->
getType()}, {Args});
1236"structurize SPIRV",
false,
false)
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the DenseMap class.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
This file defines the SmallPtrSet class.
an instruction to allocate memory on the stack
A container for analyses that lazily runs them and caches their results.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
const Function * getParent() const
Return the enclosing method, or null if none.
SymbolTableList< BasicBlock >::iterator eraseFromParent()
Unlink 'this' from the containing function and delete it.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
The address of a basic block.
BasicBlock * getBasicBlock() const
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
Conditional or Unconditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
Represents analyses that only rely on functions' control flow.
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
bool isConstantUsed() const
Return true if the constant has users other than constant expressions and other dangling things.
void destroyConstant()
Called if some element of this constant is no longer valid.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
DomTreeNodeBase * getIDom() const
Core dominator tree base class.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Legacy analysis pass which computes a DominatorTree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
UnreachableInst * CreateUnreachable()
ConstantInt * getTrue()
Get the constant value for i1 true.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
BasicBlock * GetInsertBlock() const
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
SwitchInst * CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases=10, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a switch instruction with the specified value, default dest, and with a hint for the number of...
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
ConstantInt * getFalse()
Get the constant value for i1 false.
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
A wrapper class for inspecting calls to intrinsic functions.
bool isLoopHeader(const BlockT *BB) const
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
const MDOperand & getOperand(unsigned I) const
unsigned getNumOperands() const
Return number of MDNode operands.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses run(Function &M, FunctionAnalysisManager &AM)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
void createOpSelectMerge(IRBuilder<> *Builder, BlockAddress *MergeAddress)
virtual bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
SmallPtrSet< BasicBlock *, 2 > Exits
SmallPtrSet< BasicBlock *, 8 > Blocks
void reserve(size_type NumEntries)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void addCase(ConstantInt *OnVal, BasicBlock *Dest)
Add an entry to the switch instruction.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
FunctionPassManager manages FunctionPasses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createSPIRVStructurizerPass()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
auto successors(const MachineBasicBlock *BB)
bool sortBlocks(Function &F)
auto pred_size(const MachineBasicBlock *BB)
auto succ_size(const MachineBasicBlock *BB)
void initializeSPIRVStructurizerPass(PassRegistry &)
auto predecessors(const MachineBasicBlock *BB)