LLVM  13.0.0git
SILateBranchLowering.cpp
Go to the documentation of this file.
1 //===-- SILateBranchLowering.cpp - Final preparation of branches ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This pass mainly lowers early terminate pseudo instructions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AMDGPU.h"
15 #include "GCNSubtarget.h"
17 #include "SIMachineFunctionInfo.h"
19 #include "llvm/InitializePasses.h"
20 
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "si-late-branch-lowering"
24 
25 namespace {
26 
27 class SILateBranchLowering : public MachineFunctionPass {
28 private:
29  const SIRegisterInfo *TRI = nullptr;
30  const SIInstrInfo *TII = nullptr;
31  MachineDominatorTree *MDT = nullptr;
32 
33  void earlyTerm(MachineInstr &MI, MachineBasicBlock *EarlyExitBlock);
34 
35 public:
36  static char ID;
37 
38  unsigned MovOpc;
39  Register ExecReg;
40 
41  SILateBranchLowering() : MachineFunctionPass(ID) {}
42 
43  bool runOnMachineFunction(MachineFunction &MF) override;
44 
45  StringRef getPassName() const override {
46  return "SI Final Branch Preparation";
47  }
48 
49  void getAnalysisUsage(AnalysisUsage &AU) const override {
53  }
54 };
55 
56 } // end anonymous namespace
57 
59 
60 INITIALIZE_PASS_BEGIN(SILateBranchLowering, DEBUG_TYPE,
61  "SI insert s_cbranch_execz instructions", false, false)
63 INITIALIZE_PASS_END(SILateBranchLowering, DEBUG_TYPE,
64  "SI insert s_cbranch_execz instructions", false, false)
65 
66 char &llvm::SILateBranchLoweringPassID = SILateBranchLowering::ID;
67 
69  MachineBasicBlock::iterator I, DebugLoc DL,
70  const SIInstrInfo *TII, bool IsPS) {
71  // "null export"
72  if (IsPS) {
73  BuildMI(MBB, I, DL, TII->get(AMDGPU::EXP_DONE))
75  .addReg(AMDGPU::VGPR0, RegState::Undef)
76  .addReg(AMDGPU::VGPR0, RegState::Undef)
77  .addReg(AMDGPU::VGPR0, RegState::Undef)
78  .addReg(AMDGPU::VGPR0, RegState::Undef)
79  .addImm(1) // vm
80  .addImm(0) // compr
81  .addImm(0); // en
82  }
83  // s_endpgm
84  BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ENDPGM)).addImm(0);
85 }
86 
88  MachineDominatorTree *MDT) {
89  MachineBasicBlock *SplitBB = MBB.splitAt(MI, /*UpdateLiveIns*/ true);
90 
91  // Update dominator tree
92  using DomTreeT = DomTreeBase<MachineBasicBlock>;
94  for (MachineBasicBlock *Succ : SplitBB->successors()) {
95  DTUpdates.push_back({DomTreeT::Insert, SplitBB, Succ});
96  DTUpdates.push_back({DomTreeT::Delete, &MBB, Succ});
97  }
98  DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB});
99  MDT->getBase().applyUpdates(DTUpdates);
100 }
101 
102 void SILateBranchLowering::earlyTerm(MachineInstr &MI,
103  MachineBasicBlock *EarlyExitBlock) {
104  MachineBasicBlock &MBB = *MI.getParent();
105  const DebugLoc DL = MI.getDebugLoc();
106 
107  auto BranchMI = BuildMI(MBB, MI, DL, TII->get(AMDGPU::S_CBRANCH_SCC0))
108  .addMBB(EarlyExitBlock);
109  auto Next = std::next(MI.getIterator());
110 
111  if (Next != MBB.end() && !Next->isTerminator())
112  splitBlock(MBB, *BranchMI, MDT);
113 
114  MBB.addSuccessor(EarlyExitBlock);
115  MDT->getBase().insertEdge(&MBB, EarlyExitBlock);
116 }
117 
118 bool SILateBranchLowering::runOnMachineFunction(MachineFunction &MF) {
119  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
120  TII = ST.getInstrInfo();
121  TRI = &TII->getRegisterInfo();
122  MDT = &getAnalysis<MachineDominatorTree>();
123 
124  MovOpc = ST.isWave32() ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
125  ExecReg = ST.isWave32() ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
126 
127  SmallVector<MachineInstr *, 4> EarlyTermInstrs;
128  SmallVector<MachineInstr *, 1> EpilogInstrs;
129  bool MadeChange = false;
130 
131  for (MachineBasicBlock &MBB : MF) {
133  for (I = MBB.begin(); I != MBB.end(); I = Next) {
134  Next = std::next(I);
135  MachineInstr &MI = *I;
136 
137  switch (MI.getOpcode()) {
138  case AMDGPU::S_BRANCH:
139  // Optimize out branches to the next block.
140  // This only occurs in -O0 when BranchFolding is not executed.
141  if (MBB.isLayoutSuccessor(MI.getOperand(0).getMBB())) {
142  assert(&MI == &MBB.back());
143  MI.eraseFromParent();
144  MadeChange = true;
145  }
146  break;
147 
148  case AMDGPU::SI_EARLY_TERMINATE_SCC0:
149  EarlyTermInstrs.push_back(&MI);
150  break;
151 
152  case AMDGPU::SI_RETURN_TO_EPILOG:
153  EpilogInstrs.push_back(&MI);
154  break;
155 
156  default:
157  break;
158  }
159  }
160  }
161 
162  // Lower any early exit branches first
163  if (!EarlyTermInstrs.empty()) {
164  MachineBasicBlock *EarlyExitBlock = MF.CreateMachineBasicBlock();
165  DebugLoc DL;
166 
167  MF.insert(MF.end(), EarlyExitBlock);
168  BuildMI(*EarlyExitBlock, EarlyExitBlock->end(), DL, TII->get(MovOpc),
169  ExecReg)
170  .addImm(0);
171  generateEndPgm(*EarlyExitBlock, EarlyExitBlock->end(), DL, TII,
172  MF.getFunction().getCallingConv() == CallingConv::AMDGPU_PS);
173 
174  for (MachineInstr *Instr : EarlyTermInstrs) {
175  // Early termination in GS does nothing
176  if (MF.getFunction().getCallingConv() != CallingConv::AMDGPU_GS)
177  earlyTerm(*Instr, EarlyExitBlock);
178  Instr->eraseFromParent();
179  }
180 
181  EarlyTermInstrs.clear();
182  MadeChange = true;
183  }
184 
185  // Now check return to epilog instructions occur at function end
186  if (!EpilogInstrs.empty()) {
187  MachineBasicBlock *EmptyMBBAtEnd = nullptr;
188  assert(!MF.getInfo<SIMachineFunctionInfo>()->returnsVoid());
189 
190  // If there are multiple returns to epilog then all will
191  // become jumps to new empty end block.
192  if (EpilogInstrs.size() > 1) {
193  EmptyMBBAtEnd = MF.CreateMachineBasicBlock();
194  MF.insert(MF.end(), EmptyMBBAtEnd);
195  }
196 
197  for (auto MI : EpilogInstrs) {
198  auto MBB = MI->getParent();
199  if (MBB == &MF.back() && MI == &MBB->back())
200  continue;
201 
202  // SI_RETURN_TO_EPILOG is not the last instruction.
203  // Jump to empty block at function end.
204  if (!EmptyMBBAtEnd) {
205  EmptyMBBAtEnd = MF.CreateMachineBasicBlock();
206  MF.insert(MF.end(), EmptyMBBAtEnd);
207  }
208 
209  MBB->addSuccessor(EmptyMBBAtEnd);
210  MDT->getBase().insertEdge(MBB, EmptyMBBAtEnd);
211  BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_BRANCH))
212  .addMBB(EmptyMBBAtEnd);
213  MI->eraseFromParent();
214  MadeChange = true;
215  }
216 
217  EpilogInstrs.clear();
218  }
219 
220  return MadeChange;
221 }
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
Definition: AllocatorList.h:23
Insert
Vector Rotate Left Mask Mask Insert
Definition: README_P9.txt:112
SIMachineFunctionInfo.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::AMDGPU::Exp::ET_NULL
@ ET_NULL
Definition: SIDefines.h:736
splitBlock
static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI, MachineDominatorTree *MDT)
Definition: SILateBranchLowering.cpp:87
llvm::GCNSubtarget
Definition: GCNSubtarget.h:38
llvm::MachineBasicBlock::back
MachineInstr & back()
Definition: MachineBasicBlock.h:248
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::DominatorTreeBase::applyUpdates
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
Definition: GenericDomTree.h:544
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:745
llvm::SIMachineFunctionInfo::returnsVoid
bool returnsVoid() const
Definition: SIMachineFunctionInfo.h:844
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
GCNSubtarget.h
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::CallingConv::AMDGPU_GS
@ AMDGPU_GS
Calling convention used for Mesa/AMDPAL geometry shaders.
Definition: CallingConv.h:207
false
Definition: StackSlotColoring.cpp:142
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::CallingConv::AMDGPU_PS
@ AMDGPU_PS
Calling convention used for Mesa/AMDPAL pixel shaders.
Definition: CallingConv.h:210
llvm::MachineBasicBlock::splitAt
MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
Definition: MachineBasicBlock.cpp:990
llvm::SIRegisterInfo
Definition: SIRegisterInfo.h:29
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
DEBUG_TYPE
#define DEBUG_TYPE
Definition: SILateBranchLowering.cpp:23
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:558
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
AMDGPUMCTargetDesc.h
llvm::MachineDominatorTree::getBase
DomTreeT & getBase()
Definition: MachineDominators.h:87
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
I
#define I(x, y, z)
Definition: MD5.cpp:59
generateEndPgm
static void generateEndPgm(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, const SIInstrInfo *TII, bool IsPS)
Definition: SILateBranchLowering.cpp:68
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::RegState::Undef
@ Undef
Value of the register doesn't matter.
Definition: MachineInstrBuilder.h:52
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::MachineBasicBlock::successors
iterator_range< succ_iterator > successors()
Definition: MachineBasicBlock.h:355
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
AMDGPU.h
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::DominatorTreeBase
Core dominator tree base class.
Definition: LoopInfo.h:65
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineBasicBlock::insert
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Definition: MachineBasicBlock.cpp:1337
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(SILateBranchLowering, DEBUG_TYPE, "SI insert s_cbranch_execz instructions", false, false) INITIALIZE_PASS_END(SILateBranchLowering
llvm::MachineBasicBlock::isLayoutSuccessor
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
Definition: MachineBasicBlock.cpp:937
llvm::SIInstrInfo
Definition: SIInstrInfo.h:38
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
llvm::SIMachineFunctionInfo
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Definition: SIMachineFunctionInfo.h:335
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineDominatorTree
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Definition: MachineDominators.h:45
llvm::MachineInstrBundleIterator< MachineInstr >
InitializePasses.h
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
llvm::SILateBranchLoweringPassID
char & SILateBranchLoweringPassID
Definition: SILateBranchLowering.cpp:66
MachineDominators.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38