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 Error split(StringRef Str, char Separator, std::pair< StringRef, StringRef > &Split)
Checked version of split, to ensure mandatory subparts.
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()