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.");
147 if (ExitTargets.
size() <= 1)
158 std::vector<BasicBlock *> SortedExitTargets;
159 std::vector<BasicBlock *> SortedExits;
161 if (ExitTargets.
count(&BB) != 0)
162 SortedExitTargets.push_back(&BB);
163 if (CR->
Exits.count(&BB) != 0)
164 SortedExits.push_back(&BB);
176 std::vector<std::pair<BasicBlock *, Value *>> ExitToVariable;
177 for (
auto Exit : SortedExits) {
179 ExitToVariable.emplace_back(std::make_pair(Exit,
Value));
185 for (
auto [BB,
Value] : ExitToVariable) {
191 SortedExitTargets.size() - 1);
192 for (
size_t i = 1; i < SortedExitTargets.size(); i++) {
194 Sw->
addCase(TargetToValue[BB], BB);
198 for (
auto Exit : CR->
Exits)
223 std::unordered_set<BasicBlock *> ExitTargets;
224 for (
auto *Exit : CR->
Exits) {
226 for (
auto *BB : Set) {
227 if (CR->
Blocks.count(BB) == 0)
228 ExitTargets.insert(BB);
232 assert(ExitTargets.size() <= 1);
237 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
238 const auto *TopLevelRegion =
239 getAnalysis<SPIRVConvergenceRegionAnalysisWrapperPass>()
241 .getTopLevelRegion();
247 bool modified =
false;
249 TopLevelRegion = getAnalysis<SPIRVConvergenceRegionAnalysisWrapperPass>()
251 .getTopLevelRegion();
255#if !defined(NDEBUG) || defined(EXPENSIVE_CHECKS)
273 "SPIRV split region exit blocks",
false,
false)
static MachineBasicBlock * split(MachineBasicBlock::iterator I)
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.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
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.
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...
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.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
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...
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.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
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, const SPIRV::ConvergenceRegion *CR)
Run the pass on the given convergence region and sub-regions (DFS).
SPIRVMergeRegionExitTargets()
bool runOnConvergenceRegionNoRecurse(LoopInfo &LI, const SPIRV::ConvergenceRegion *CR)
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.
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.
SmallVector< ConvergenceRegion * > Children
SmallPtrSet< BasicBlock *, 2 > Exits
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.
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()