22#define DEBUG_TYPE "si-late-branch-lowering"
46 return "SI Final Branch Preparation";
58char SILateBranchLowering::ID = 0;
61 "SI insert s_cbranch_execz instructions",
false,
false)
77 bool HasExports = HasColorExports || HasDepthExports;
82 if (IsPS && (HasExports || MustExport)) {
86 ST.hasNullExportTarget()
112 DTUpdates.
push_back({DomTreeT::Insert, SplitBB, Succ});
122 constexpr unsigned ExecIdx = 3;
126 MI.removeOperand(ExecIdx);
128 MI.setDesc(
TII->get(AMDGPU::SI_TCRETURN));
138 auto Next = std::next(
MI.getIterator());
140 if (Next !=
MBB.
end() && !Next->isTerminator())
144 MDT->insertEdge(&
MBB, EarlyExitBlock);
149 TII =
ST.getInstrInfo();
150 TRI = &
TII->getRegisterInfo();
151 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
153 MovOpc =
ST.isWave32() ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
154 ExecReg =
ST.isWave32() ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
158 bool MadeChange =
false;
162 switch (
MI.getOpcode()) {
163 case AMDGPU::S_BRANCH:
168 MI.eraseFromParent();
173 case AMDGPU::SI_CS_CHAIN_TC_W32:
174 case AMDGPU::SI_CS_CHAIN_TC_W64:
179 case AMDGPU::SI_EARLY_TERMINATE_SCC0:
183 case AMDGPU::SI_RETURN_TO_EPILOG:
194 if (!EarlyTermInstrs.
empty()) {
198 MF.
insert(MF.end(), EarlyExitBlock);
207 earlyTerm(*Instr, EarlyExitBlock);
208 Instr->eraseFromParent();
211 EarlyTermInstrs.clear();
216 if (!EpilogInstrs.
empty()) {
222 if (EpilogInstrs.
size() > 1) {
223 EmptyMBBAtEnd = MF.CreateMachineBasicBlock();
224 MF.
insert(MF.end(), EmptyMBBAtEnd);
227 for (
auto *
MI : EpilogInstrs) {
228 auto *
MBB =
MI->getParent();
234 if (!EmptyMBBAtEnd) {
235 EmptyMBBAtEnd = MF.CreateMachineBasicBlock();
236 MF.
insert(MF.end(), EmptyMBBAtEnd);
240 MDT->insertEdge(
MBB, EmptyMBBAtEnd);
243 MI->eraseFromParent();
247 EpilogInstrs.clear();
Provides AMDGPU specific target descriptions.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static void generateEndPgm(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, const SIInstrInfo *TII, MachineFunction &MF)
static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI, MachineDominatorTree *MDT)
SI insert s_cbranch_execz instructions
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Core dominator tree base class.
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
bool getHasColorExport(const Function &F)
bool getHasDepthExport(const Function &F)
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ AMDGPU_GS
Used for Mesa/AMDPAL geometry shaders.
@ AMDGPU_PS
Used for Mesa/AMDPAL pixel shaders.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Undef
Value of the register doesn't matter.
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
char & SILateBranchLoweringPassID