25#define DEBUG_TYPE "si-late-branch-lowering"
29class SILateBranchLowering {
45 : ST(ST),
TII(ST.getInstrInfo()),
TRI(&
TII->getRegisterInfo()), MDT(MDT),
58 auto *MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
59 auto *MLIWP = getAnalysisIfAvailable<MachineLoopInfoWrapperPass>();
61 return SILateBranchLowering(ST, MDT, MLI).run(MF);
65 return "SI Final Branch Preparation";
78char SILateBranchLoweringLegacy::ID = 0;
81 "SI insert s_cbranch_execz instructions",
false,
false)
97 bool HasExports = HasColorExports || HasDepthExports;
102 if (IsPS && (HasExports || MustExport)) {
106 ST.hasNullExportTarget()
132 DTUpdates.
push_back({DomTreeT::Insert, SplitBB, Succ});
159 AMDGPU::getNamedOperandIdx(
MI.getOpcode(), AMDGPU::OpName::exec);
160 assert(ExecIdx != -1 &&
"Missing EXEC operand");
173 *
TII->getNamedOperand(
MI, AMDGPU::OpName::numvgprs));
177 .
addDef(
TII->getNamedOperand(
MI, AMDGPU::OpName::src0)->getReg());
179 *
TII->getNamedOperand(
MI, AMDGPU::OpName::src0));
181 *
TII->getNamedOperand(
MI, AMDGPU::OpName::fbcallee));
187 *
TII->getNamedOperand(
MI, AMDGPU::OpName::exec));
189 *
TII->getNamedOperand(
MI, AMDGPU::OpName::fbexec));
194 *
TII->getNamedOperand(
MI, AMDGPU::OpName::exec));
197 for (
int OpIdx =
MI.getNumExplicitOperands() - 1; OpIdx >= ExecIdx; --OpIdx)
198 MI.removeOperand(OpIdx);
200 MI.setDesc(
TII->get(AMDGPU::SI_TCRETURN_CHAIN));
203void SILateBranchLowering::earlyTerm(MachineInstr &
MI,
204 MachineBasicBlock *EarlyExitBlock) {
210 auto Next = std::next(
MI.getIterator());
225 if (!SILateBranchLowering(ST, MDT, MLI).
run(MF))
237 bool MadeChange =
false;
241 switch (
MI.getOpcode()) {
242 case AMDGPU::S_BRANCH:
245 if (
MBB.isLayoutSuccessor(
MI.getOperand(0).getMBB())) {
247 MI.eraseFromParent();
252 case AMDGPU::SI_CS_CHAIN_TC_W32:
253 case AMDGPU::SI_CS_CHAIN_TC_W64:
254 expandChainCall(
MI, ST,
false);
257 case AMDGPU::SI_CS_CHAIN_TC_W32_DVGPR:
258 case AMDGPU::SI_CS_CHAIN_TC_W64_DVGPR:
259 expandChainCall(
MI, ST,
true);
263 case AMDGPU::SI_EARLY_TERMINATE_SCC0:
267 case AMDGPU::SI_RETURN_TO_EPILOG:
278 if (!EarlyTermInstrs.
empty()) {
279 MachineBasicBlock *EarlyExitBlock = MF.CreateMachineBasicBlock();
282 MF.
insert(MF.end(), EarlyExitBlock);
288 for (MachineInstr *Instr : EarlyTermInstrs) {
290 if (MF.getFunction().getCallingConv() != CallingConv::AMDGPU_GS)
291 earlyTerm(*Instr, EarlyExitBlock);
292 Instr->eraseFromParent();
295 EarlyTermInstrs.clear();
300 if (!EpilogInstrs.
empty()) {
301 MachineBasicBlock *EmptyMBBAtEnd =
nullptr;
302 assert(!MF.getInfo<SIMachineFunctionInfo>()->returnsVoid());
306 if (EpilogInstrs.
size() > 1) {
307 EmptyMBBAtEnd = MF.CreateMachineBasicBlock();
308 MF.
insert(MF.end(), EmptyMBBAtEnd);
311 for (
auto *
MI : EpilogInstrs) {
318 if (!EmptyMBBAtEnd) {
319 EmptyMBBAtEnd = MF.CreateMachineBasicBlock();
320 MF.
insert(MF.end(), EmptyMBBAtEnd);
331 EpilogInstrs.clear();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
AMD GCN specific subclass of TargetSubtarget.
const HexagonInstrInfo * TII
Register 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, MachineLoopInfo *MLI)
static void copyOpWithoutRegFlags(MachineInstrBuilder &MIB, MachineOperand &Op)
const unsigned CSelectOpc
static const LaneMaskConstants & get(const GCNSubtarget &ST)
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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.
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
void insertEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge insertion and update the tree.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Represents a single loop in the control flow graph.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< succ_iterator > successors()
Analysis pass which computes a MachineDominatorTree.
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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_PS
Used for Mesa/AMDPAL pixel shaders.
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.
@ Undef
Value of the register doesn't matter.
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
char & SILateBranchLoweringPassID
DominatorTreeBase< T, false > DomTreeBase
DWARFExpression::Operation Op
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next