47 #define DEBUG_TYPE "si-annotate-control-flow" 52 using StackEntry = std::pair<BasicBlock *, Value *>;
91 void eraseIfUnused(
PHINode *Phi);
112 StringRef getPassName()
const override {
return "SI annotate control flow"; }
127 "Annotate SI Control Flow",
false,
false)
134 char SIAnnotateControlFlow::
ID = 0;
153 { IntMask, IntMask });
155 { IntMask, IntMask });
162 bool SIAnnotateControlFlow::isUniform(
BranchInst *
T) {
163 return DA->isUniform(T) ||
164 T->
getMetadata(
"structurizecfg.uniform") !=
nullptr;
168 bool SIAnnotateControlFlow::isTopOfStack(
BasicBlock *BB) {
169 return !Stack.empty() && Stack.back().first == BB;
173 Value *SIAnnotateControlFlow::popSaved() {
174 return Stack.pop_back_val().second;
179 Stack.push_back(std::make_pair(BB, Saved));
184 bool SIAnnotateControlFlow::isElse(
PHINode *Phi) {
202 void SIAnnotateControlFlow::eraseIfUnused(
PHINode *Phi) {
209 void SIAnnotateControlFlow::openIf(
BranchInst *Term) {
219 void SIAnnotateControlFlow::insertElse(
BranchInst *Term) {
220 if (isUniform(Term)) {
229 Value *SIAnnotateControlFlow::handleLoopCondition(
231 if (
Instruction *Inst = dyn_cast<Instruction>(Cond)) {
245 if (isa<Constant>(Cond)) {
257 void SIAnnotateControlFlow::handleLoop(
BranchInst *Term) {
271 Value *
Arg = handleLoopCondition(Cond, Broken, L, Term);
274 Value *PHIValue = IntMaskZero;
280 else if (L->
contains(Pred) && DT->dominates(Pred, BB))
291 void SIAnnotateControlFlow::closeControlFlow(
BasicBlock *BB) {
294 assert(Stack.back().first == BB);
313 Value *Exec = popSaved();
315 if (!isa<UndefValue>(Exec) && !isa<UnreachableInst>(FirstInsertionPt))
322 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
323 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
324 DA = &getAnalysis<LegacyDivergenceAnalysis>();
336 if (isTopOfStack(BB))
337 closeControlFlow(BB);
343 if (isTopOfStack(BB))
344 closeControlFlow(BB);
350 if (isTopOfStack(BB)) {
352 if (Phi && Phi->
getParent() == BB && isElse(Phi)) {
358 closeControlFlow(BB);
364 if (!Stack.empty()) {
374 return new SIAnnotateControlFlow();
static ConstantInt * getFalse(LLVMContext &Context)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static IntegerType * getInt1Ty(LLVMContext &C)
FunctionPass * createSIAnnotateControlFlowPass()
Create the annotation pass.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
AMDGPU specific subclass of TargetSubtarget.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE, "Annotate SI Control Flow", false, false) INITIALIZE_PASS_END(SIAnnotateControlFlow
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
void push_back(const T &Elt)
BasicBlock * getSuccessor(unsigned i) const
static IntegerType * getInt64Ty(LLVMContext &C)
Value * getCondition() const
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...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
'undef' values are things that do not have specified contents.
void getLoopLatches(SmallVectorImpl< BlockT *> &LoopLatches) const
Return all loop latch blocks of this loop.
Target-Independent Code Generator Pass Configuration Options.
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
BlockT * getHeader() const
const Instruction * getFirstNonPHIOrDbgOrLifetime() const
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
const BasicBlock & getEntryBlock() const
static bool runOnFunction(Function &F, bool PostInlining)
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock *> Preds, const char *Suffix, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
Conditional or Unconditional Branch instruction.
df_iterator< T > df_end(const T &G)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const Instruction & front() const
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
FunctionPass class - This class is used to implement most global optimizations.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
This is the shared class of boolean and integer constants.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=nullptr)
If the specified value is an effectively dead PHI node, due to being a def-use chain of single-use no...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
pred_range predecessors(BasicBlock *BB)
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static ConstantInt * getTrue(LLVMContext &Context)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
df_iterator< T > df_begin(const T &G)
Target - Wrapper for Target specific information.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
static IntegerType * getInt32Ty(LLVMContext &C)
Represents a single loop in the control flow graph.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isUnconditional() const
void setCondition(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
Primary interface to the complete machine description for the target machine.
The legacy pass manager's analysis pass to compute loop information.
StringRef - Represent a constant reference to a string, i.e.
Legacy analysis pass which computes a DominatorTree.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const BasicBlock * getParent() const
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.