28 #define DEBUG_TYPE "si-insert-skips"
33 "amdgpu-skip-threshold",
34 cl::desc(
"Number of instructions before jumping over divergent control flow"),
41 unsigned SkipThreshold;
64 return "SI insert s_cbranch_execz instructions";
77 "SI insert s_cbranch_execz instructions",
false,
false)
83 case TargetOpcode::IMPLICIT_DEF:
85 case TargetOpcode::BUNDLE:
86 case TargetOpcode::CFI_INSTRUCTION:
88 case TargetOpcode::GC_LABEL:
89 case TargetOpcode::DBG_VALUE:
101 unsigned NumInstr = 0;
105 MBBI !=
End && MBBI != ToI; ++MBBI) {
109 NumInstr < SkipThreshold &&
I !=
E; ++
I) {
119 if (
I->getOpcode() == AMDGPU::S_CBRANCH_VCCNZ ||
120 I->getOpcode() == AMDGPU::S_CBRANCH_VCCZ)
123 if (
I->isInlineAsm()) {
125 const char *AsmStr =
I->getOperand(0).getSymbolName();
135 if (NumInstr >= SkipThreshold)
156 BuildMI(&MBB, DL,
TII->get(AMDGPU::S_CBRANCH_EXECNZ))
162 BuildMI(*SkipBB, Insert, DL,
TII->get(AMDGPU::EXP_DONE))
173 BuildMI(*SkipBB, Insert, DL,
TII->get(AMDGPU::S_ENDPGM));
192 if (Op.
getImm() & 0x80000000) {
193 BuildMI(MBB, &MI, DL,
TII->get(AMDGPU::S_MOV_B64), AMDGPU::EXEC)
197 BuildMI(MBB, &MI, DL,
TII->get(AMDGPU::V_CMPX_LE_F32_e32))
222 if (!shouldSkip(**SrcMBB.
succ_begin(), *DestBB))
228 BuildMI(SrcMBB, InsPt, DL,
TII->get(AMDGPU::S_CBRANCH_EXECZ))
238 SkipThreshold = SkipThresholdFlag;
240 bool HaveKill =
false;
241 bool MadeChange =
false;
251 BI != BE; BI = NextBB) {
252 NextBB = std::next(BI);
255 if (!ExecBranchStack.
empty() && ExecBranchStack.
back() == &
MBB) {
260 if (HaveKill && ExecBranchStack.
empty()) {
267 for (I = MBB.
begin(); I != MBB.
end(); I = Next) {
273 case AMDGPU::SI_MASK_BRANCH: {
275 MadeChange |= skipMaskBranch(MI, MBB);
278 case AMDGPU::S_BRANCH: {
285 case AMDGPU::SI_KILL_TERMINATOR: {
289 if (ExecBranchStack.
empty()) {
290 if (skipIfDead(MI, *NextBB)) {
291 NextBB = std::next(BI);
302 case AMDGPU::SI_RETURN: {
311 if (!EmptyMBBAtEnd) {
318 .addMBB(EmptyMBBAtEnd);
319 I->eraseFromParent();
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
AMDGPU specific subclass of TargetSubtarget.
MachineBasicBlock * getMBB() const
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
const SIInstrInfo * getInstrInfo() const override
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
LLVM_NODISCARD bool empty() const
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
initializer< Ty > init(const Ty &Val)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
char & SIInsertSkipsPassID
const MachineOperand & getOperand(unsigned i) const
Represent the analysis usage information of a pass.
static const unsigned End
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
self_iterator getIterator()
succ_iterator succ_begin()
Calling convention used for Mesa pixel shaders.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Calling convention used for Mesa geometry shaders.
const SIRegisterInfo * getRegisterInfo() const override
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned getInlineAsmLength(const char *Str, const MCAsmInfo &MAI) const override
Measure the specified inline asm to determine an approximation of its length.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Representation of each machine instruction.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void insert(iterator MBBI, MachineBasicBlock *MBB)
unsigned getMaxInstLength() const
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
const MachineBasicBlock & back() const
StringRef - Represent a constant reference to a string, i.e.
static INITIALIZE_PASS(SIInsertSkips, DEBUG_TYPE,"SI insert s_cbranch_execz instructions", false, false) char &llvm bool opcodeEmitsNoInsts(unsigned Opc)
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.