29#include "llvm/IR/IntrinsicsSPIRV.h"
51 std::unordered_set<BasicBlock *> output;
54 if (
auto *BI = dyn_cast<BranchInst>(
T)) {
55 output.insert(BI->getSuccessor(0));
56 if (BI->isConditional())
57 output.insert(BI->getSuccessor(1));
61 if (
auto *SI = dyn_cast<SwitchInst>(
T)) {
62 output.insert(SI->getDefaultDest());
63 for (
auto &Case : SI->cases())
64 output.insert(Case.getCaseSuccessor());
68 assert(isa<ReturnInst>(
T) &&
"Unhandled terminator type.");
78 if (isa<ReturnInst>(
T))
84 if (
auto *BI = dyn_cast<BranchInst>(
T)) {
88 BI->isConditional() ? BI->getSuccessor(1) :
nullptr;
91 ? TargetToValue.
at(LHSTarget)
94 ? TargetToValue.
at(RHSTarget)
97 if (
LHS ==
nullptr ||
RHS ==
nullptr)
111 if (isa<ReturnInst>(
T))
114 if (
auto *BI = dyn_cast<BranchInst>(
T)) {
115 for (
size_t i = 0; i < BI->getNumSuccessors(); i++) {
116 if (ToReplace.
count(BI->getSuccessor(i)) != 0)
122 if (
auto *SI = dyn_cast<SwitchInst>(
T)) {
123 for (
size_t i = 0; i < SI->getNumSuccessors(); i++) {
124 if (ToReplace.
count(SI->getSuccessor(i)) != 0)
125 SI->setSuccessor(i, NewTarget);
130 assert(
false &&
"Unhandled terminator type.");
154 if (ExitTargets.
size() <= 1)
163 F->begin()->getFirstInsertionPt());
168 std::vector<BasicBlock *> SortedExitTargets;
169 std::vector<BasicBlock *> SortedExits;
171 if (ExitTargets.
count(&BB) != 0)
172 SortedExitTargets.push_back(&BB);
173 if (CR->
Exits.count(&BB) != 0)
174 SortedExits.push_back(&BB);
186 std::vector<std::pair<BasicBlock *, Value *>> ExitToVariable;
187 for (
auto Exit : SortedExits) {
192 ExitToVariable.emplace_back(std::make_pair(Exit,
Value));
199 SortedExitTargets.size() - 1);
200 for (
size_t i = 1; i < SortedExitTargets.size(); i++) {
202 Sw->
addCase(TargetToValue[BB], BB);
206 for (
auto Exit : CR->
Exits)
211 CR->
Blocks.insert(NewExitTarget);
236 std::unordered_set<BasicBlock *> ExitTargets;
237 for (
auto *Exit : CR->
Exits) {
239 for (
auto *BB : Set) {
240 if (CR->
Blocks.count(BB) == 0)
241 ExitTargets.insert(BB);
245 assert(ExitTargets.size() <= 1);
250 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
251 auto *TopLevelRegion =
252 getAnalysis<SPIRVConvergenceRegionAnalysisWrapperPass>()
254 .getWritableTopLevelRegion();
260 bool modified =
false;
265#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
285 "SPIRV split region exit blocks",
false,
false)
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...
#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())
This file defines the SmallPtrSet class.
an instruction to allocate memory on the stack
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 Function * getParent() const
Return the enclosing method, or null if none.
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...
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.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
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...
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)
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...
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
The legacy pass manager's analysis pass to compute loop information.
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...
std::unordered_set< BasicBlock * > gatherSuccessors(BasicBlock *BB)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
void replaceBranchTargets(BasicBlock *BB, const SmallPtrSet< BasicBlock *, 4 > &ToReplace, BasicBlock *NewTarget)
Replaces |BB|'s branch targets present in |ToReplace| with |NewTarget|.
bool runOnConvergenceRegion(LoopInfo &LI, SPIRV::ConvergenceRegion *CR)
Run the pass on the given convergence region and sub-regions (DFS).
SPIRVMergeRegionExitTargets()
llvm::Value * createExitVariable(BasicBlock *BB, const DenseMap< BasicBlock *, ConstantInt * > &TargetToValue)
Create a value in BB set to the value associated with the branch the block terminator will take.
bool runOnConvergenceRegionNoRecurse(LoopInfo &LI, SPIRV::ConvergenceRegion *CR)
void validateRegionExits(const SPIRV::ConvergenceRegion *CR)
Validates each edge exiting the region has the same destination basic block.
virtual bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
AllocaInst * CreateVariable(Function &F, Type *Type, BasicBlock::iterator Position)
SmallVector< ConvergenceRegion * > Children
SmallPtrSet< BasicBlock *, 2 > Exits
ConvergenceRegion * Parent
SmallPtrSet< BasicBlock *, 8 > Blocks
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
void initializeSPIRVMergeRegionExitTargetsPass(PassRegistry &)
FunctionPass * createSPIRVMergeRegionExitTargetsPass()