Go to the documentation of this file.
22 #include "llvm/IR/IntrinsicsAMDGPU.h"
30 #define DEBUG_TYPE "si-annotate-control-flow"
35 using StackEntry = std::pair<BasicBlock *, Value *>;
76 bool eraseIfUnused(
PHINode *Phi);
97 StringRef getPassName()
const override {
return "SI annotate control flow"; }
113 "Annotate SI Control Flow",
false,
false)
120 char SIAnnotateControlFlow::
ID = 0;
139 { IntMask, IntMask });
148 bool SIAnnotateControlFlow::isUniform(
BranchInst *
T) {
149 return DA->isUniform(
T) ||
150 T->getMetadata(
"structurizecfg.uniform") !=
nullptr;
154 bool SIAnnotateControlFlow::isTopOfStack(
BasicBlock *
BB) {
159 Value *SIAnnotateControlFlow::popSaved() {
160 return Stack.pop_back_val().second;
170 bool SIAnnotateControlFlow::isElse(
PHINode *Phi) {
187 bool SIAnnotateControlFlow::hasKill(
const BasicBlock *
BB) {
189 if (
const CallInst *CI = dyn_cast<CallInst>(&
I))
190 if (CI->getIntrinsicID() == Intrinsic::amdgcn_kill)
197 bool SIAnnotateControlFlow::eraseIfUnused(
PHINode *Phi) {
217 if (isUniform(
Term)) {
227 Value *SIAnnotateControlFlow::handleLoopCondition(
243 if (isa<Constant>(
Cond)) {
251 if (isa<Argument>(
Cond)) {
274 Term->setCondition(BoolTrue);
278 Value *PHIValue = IntMaskZero;
284 else if (L->
contains(Pred) && DT->dominates(Pred,
BB))
297 bool SIAnnotateControlFlow::closeControlFlow(
BasicBlock *
BB) {
312 Preds.push_back(Pred);
321 if (!isa<UndefValue>(Exec) && !isa<UnreachableInst>(FirstInsertionPt)) {
324 if (!DT->dominates(DefBB,
BB)) {
337 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
338 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
339 DA = &getAnalysis<LegacyDivergenceAnalysis>();
343 bool Changed =
false;
350 if (!
Term ||
Term->isUnconditional()) {
351 if (isTopOfStack(
BB))
352 Changed |= closeControlFlow(
BB);
357 if (
I.nodeVisited(
Term->getSuccessor(1))) {
358 if (isTopOfStack(
BB))
359 Changed |= closeControlFlow(
BB);
361 if (DT->dominates(
Term->getSuccessor(1),
BB))
362 Changed |= handleLoop(
Term);
366 if (isTopOfStack(
BB)) {
367 PHINode *Phi = dyn_cast<PHINode>(
Term->getCondition());
368 if (Phi && Phi->
getParent() ==
BB && isElse(Phi) && !hasKill(
BB)) {
369 Changed |= insertElse(
Term);
370 Changed |= eraseIfUnused(Phi);
374 Changed |= closeControlFlow(
BB);
377 Changed |= openIf(
Term);
380 if (!
Stack.empty()) {
390 return new SIAnnotateControlFlow();
This is an optimization pass for GlobalISel generic memory operations.
static IntegerType * getInt1Ty(LLVMContext &C)
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Vector Rotate Left Mask Mask Insert
const Function * getParent() const
Return the enclosing method, or null if none.
Represents a single loop in the control flow graph.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
Target - Wrapper for Target specific information.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
df_iterator< T > df_end(const T &G)
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Fixup Statepoint Caller Saved
The instances of the Type class are immutable: once they are created, they are never changed.
The legacy pass manager's analysis pass to compute loop information.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static IntegerType * getInt32Ty(LLVMContext &C)
bool RecursivelyDeleteDeadPHINode(PHINode *PN, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
If the specified value is an effectively dead PHI node, due to being a def-use chain of single-use no...
LLVM Basic Block Representation.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This is the shared class of boolean and integer constants.
void getLoopLatches(SmallVectorImpl< BlockT * > &LoopLatches) const
Return all loop latch blocks of this loop.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Represent the analysis usage information of a pass.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Legacy analysis pass which computes a DominatorTree.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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.
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock * > Preds, const char *Suffix, DominatorTree *DT, 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...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
INITIALIZE_PASS_BEGIN(SIAnnotateControlFlow, DEBUG_TYPE, "Annotate SI Control Flow", false, false) INITIALIZE_PASS_END(SIAnnotateControlFlow
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
auto predecessors(const MachineBasicBlock *BB)
Target-Independent Code Generator Pass Configuration Options.
This is an important base class in LLVM.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This is an important class for using LLVM in a threaded context.
'undef' values are things that do not have specified contents.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
df_iterator< T > df_begin(const T &G)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Primary interface to the complete machine description for the target machine.
A Module instance is used to store all the information related to an LLVM module.
SmallVector< MachineOperand, 4 > Cond
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
TMC & getTM() const
Get the right type of TargetMachine for this target.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
static ConstantInt * getFalse(LLVMContext &Context)
static bool runOnFunction(Function &F, bool PostInlining)
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
static IntegerType * getInt64Ty(LLVMContext &C)
static ConstantInt * getTrue(LLVMContext &Context)
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...
BlockT * getHeader() const
const Instruction * getFirstNonPHIOrDbgOrLifetime(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode, a debug intrinsic,...
static Type * getVoidTy(LLVMContext &C)
const BasicBlock * getParent() const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
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...
FunctionPass * createSIAnnotateControlFlowPass()
Create the annotation pass.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
const char LLVMTargetMachineRef TM
FunctionPass class - This class is used to implement most global optimizations.
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
AnalysisUsage & addRequired()
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Conditional or Unconditional Branch instruction.
LLVM Value Representation.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.