LLVM  16.0.0git
SIPreAllocateWWMRegs.cpp
Go to the documentation of this file.
1 //===- SIPreAllocateWWMRegs.cpp - WWM Register Pre-allocation -------------===//
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 /// Pass to pre-allocated WWM registers
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AMDGPU.h"
15 #include "GCNSubtarget.h"
17 #include "SIMachineFunctionInfo.h"
25 #include "llvm/InitializePasses.h"
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "si-pre-allocate-wwm-regs"
30 
31 namespace {
32 
33 class SIPreAllocateWWMRegs : public MachineFunctionPass {
34 private:
35  const SIInstrInfo *TII;
36  const SIRegisterInfo *TRI;
38  LiveIntervals *LIS;
40  VirtRegMap *VRM;
41  RegisterClassInfo RegClassInfo;
42 
43  std::vector<unsigned> RegsToRewrite;
44 #ifndef NDEBUG
45  void printWWMInfo(const MachineInstr &MI);
46 #endif
47 
48 public:
49  static char ID;
50 
51  SIPreAllocateWWMRegs() : MachineFunctionPass(ID) {
53  }
54 
55  bool runOnMachineFunction(MachineFunction &MF) override;
56 
57  void getAnalysisUsage(AnalysisUsage &AU) const override {
60  AU.addRequired<VirtRegMap>();
63  AU.setPreservesCFG();
65  }
66 
67 private:
68  bool processDef(MachineOperand &MO);
69  void rewriteRegs(MachineFunction &MF);
70 };
71 
72 } // End anonymous namespace.
73 
74 INITIALIZE_PASS_BEGIN(SIPreAllocateWWMRegs, DEBUG_TYPE,
75  "SI Pre-allocate WWM Registers", false, false)
79 INITIALIZE_PASS_END(SIPreAllocateWWMRegs, DEBUG_TYPE,
80  "SI Pre-allocate WWM Registers", false, false)
81 
82 char SIPreAllocateWWMRegs::ID = 0;
83 
84 char &llvm::SIPreAllocateWWMRegsID = SIPreAllocateWWMRegs::ID;
85 
87  return new SIPreAllocateWWMRegs();
88 }
89 
90 bool SIPreAllocateWWMRegs::processDef(MachineOperand &MO) {
91  Register Reg = MO.getReg();
92  if (Reg.isPhysical())
93  return false;
94 
95  if (!TRI->isVGPR(*MRI, Reg))
96  return false;
97 
98  if (VRM->hasPhys(Reg))
99  return false;
100 
101  LiveInterval &LI = LIS->getInterval(Reg);
102 
103  for (MCRegister PhysReg : RegClassInfo.getOrder(MRI->getRegClass(Reg))) {
104  if (!MRI->isPhysRegUsed(PhysReg) &&
105  Matrix->checkInterference(LI, PhysReg) == LiveRegMatrix::IK_Free) {
106  Matrix->assign(LI, PhysReg);
107  assert(PhysReg != 0);
108  RegsToRewrite.push_back(Reg);
109  return true;
110  }
111  }
112 
113  llvm_unreachable("physreg not found for WWM expression");
114 }
115 
116 void SIPreAllocateWWMRegs::rewriteRegs(MachineFunction &MF) {
117  for (MachineBasicBlock &MBB : MF) {
118  for (MachineInstr &MI : MBB) {
119  for (MachineOperand &MO : MI.operands()) {
120  if (!MO.isReg())
121  continue;
122 
123  const Register VirtReg = MO.getReg();
124  if (VirtReg.isPhysical())
125  continue;
126 
127  if (!VRM->hasPhys(VirtReg))
128  continue;
129 
130  Register PhysReg = VRM->getPhys(VirtReg);
131  const unsigned SubReg = MO.getSubReg();
132  if (SubReg != 0) {
133  PhysReg = TRI->getSubReg(PhysReg, SubReg);
134  MO.setSubReg(0);
135  }
136 
137  MO.setReg(PhysReg);
138  MO.setIsRenamable(false);
139  }
140  }
141  }
142 
143  SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
144 
145  for (unsigned Reg : RegsToRewrite) {
146  LIS->removeInterval(Reg);
147 
148  const Register PhysReg = VRM->getPhys(Reg);
149  assert(PhysReg != 0);
150 
151  MFI->reserveWWMRegister(PhysReg);
152  }
153 
154  RegsToRewrite.clear();
155 
156  // Update the set of reserved registers to include WWM ones.
157  MRI->freezeReservedRegs(MF);
158 }
159 
160 #ifndef NDEBUG
161 LLVM_DUMP_METHOD void
162 SIPreAllocateWWMRegs::printWWMInfo(const MachineInstr &MI) {
163 
164  unsigned Opc = MI.getOpcode();
165 
166  if (Opc == AMDGPU::ENTER_STRICT_WWM || Opc == AMDGPU::ENTER_STRICT_WQM ||
167  Opc == AMDGPU::ENTER_PSEUDO_WM) {
168  dbgs() << "Entering ";
169  } else {
170  assert(Opc == AMDGPU::EXIT_STRICT_WWM || Opc == AMDGPU::EXIT_STRICT_WQM ||
171  Opc == AMDGPU::EXIT_PSEUDO_WM);
172  dbgs() << "Exiting ";
173  }
174 
175  if (Opc == AMDGPU::ENTER_STRICT_WWM || Opc == AMDGPU::EXIT_STRICT_WWM) {
176  dbgs() << "Strict WWM ";
177  } else if (Opc == AMDGPU::ENTER_PSEUDO_WM || Opc == AMDGPU::EXIT_PSEUDO_WM) {
178  dbgs() << "Pseudo WWM/WQM ";
179  } else {
180  assert(Opc == AMDGPU::ENTER_STRICT_WQM || Opc == AMDGPU::EXIT_STRICT_WQM);
181  dbgs() << "Strict WQM ";
182  }
183 
184  dbgs() << "region: " << MI;
185 }
186 
187 #endif
188 
189 bool SIPreAllocateWWMRegs::runOnMachineFunction(MachineFunction &MF) {
190  LLVM_DEBUG(dbgs() << "SIPreAllocateWWMRegs: function " << MF.getName() << "\n");
191 
192  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
193 
194  TII = ST.getInstrInfo();
195  TRI = &TII->getRegisterInfo();
196  MRI = &MF.getRegInfo();
197 
198  LIS = &getAnalysis<LiveIntervals>();
199  Matrix = &getAnalysis<LiveRegMatrix>();
200  VRM = &getAnalysis<VirtRegMap>();
201 
202  RegClassInfo.runOnMachineFunction(MF);
203 
204  bool RegsAssigned = false;
205 
206  // We use a reverse post-order traversal of the control-flow graph to
207  // guarantee that we visit definitions in dominance order. Since WWM
208  // expressions are guaranteed to never involve phi nodes, and we can only
209  // escape WWM through the special WWM instruction, this means that this is a
210  // perfect elimination order, so we can never do any better.
212 
213  for (MachineBasicBlock *MBB : RPOT) {
214  bool InWWM = false;
215  for (MachineInstr &MI : *MBB) {
216  if (MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B32 ||
217  MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B64)
218  RegsAssigned |= processDef(MI.getOperand(0));
219 
220  if (MI.getOpcode() == AMDGPU::ENTER_STRICT_WWM ||
221  MI.getOpcode() == AMDGPU::ENTER_STRICT_WQM ||
222  MI.getOpcode() == AMDGPU::ENTER_PSEUDO_WM) {
223  LLVM_DEBUG(printWWMInfo(MI));
224  InWWM = true;
225  continue;
226  }
227 
228  if (MI.getOpcode() == AMDGPU::EXIT_STRICT_WWM ||
229  MI.getOpcode() == AMDGPU::EXIT_STRICT_WQM ||
230  MI.getOpcode() == AMDGPU::EXIT_PSEUDO_WM) {
231  LLVM_DEBUG(printWWMInfo(MI));
232  InWWM = false;
233  }
234 
235  if (!InWWM)
236  continue;
237 
238  LLVM_DEBUG(dbgs() << "Processing " << MI);
239 
240  for (MachineOperand &DefOpnd : MI.defs()) {
241  RegsAssigned |= processDef(DefOpnd);
242  }
243  }
244  }
245 
246  if (!RegsAssigned)
247  return false;
248 
249  rewriteRegs(MF);
250  return true;
251 }
LiveRegMatrix.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:492
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MachineRegisterInfo::isPhysRegUsed
bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Definition: MachineRegisterInfo.cpp:587
SIMachineFunctionInfo.h
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:50
llvm::initializeSIPreAllocateWWMRegsPass
void initializeSIPreAllocateWWMRegsPass(PassRegistry &)
llvm::VirtRegMap
Definition: VirtRegMap.h:33
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
Registers
SI Pre allocate WWM Registers
Definition: SIPreAllocateWWMRegs.cpp:80
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
RegisterClassInfo.h
llvm::GCNSubtarget
Definition: GCNSubtarget.h:31
llvm::createSIPreAllocateWWMRegsPass
FunctionPass * createSIPreAllocateWWMRegsPass()
Definition: SIPreAllocateWWMRegs.cpp:86
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(SIPreAllocateWWMRegs, DEBUG_TYPE, "SI Pre-allocate WWM Registers", false, false) INITIALIZE_PASS_END(SIPreAllocateWWMRegs
llvm::SIPreAllocateWWMRegsID
char & SIPreAllocateWWMRegsID
Definition: SIPreAllocateWWMRegs.cpp:84
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:167
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::Register::isPhysical
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:97
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:670
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:24
llvm::LiveRegMatrix::IK_Free
@ IK_Free
No interference, go ahead and assign.
Definition: LiveRegMatrix.h:85
GCNSubtarget.h
llvm::MachineOperand::setSubReg
void setSubReg(unsigned subReg)
Definition: MachineOperand.h:480
SI
@ SI
Definition: SIInstrInfo.cpp:7985
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:141
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::SlotIndexes
SlotIndexes pass.
Definition: SlotIndexes.h:319
llvm::MachineRegisterInfo::freezeReservedRegs
void freezeReservedRegs(const MachineFunction &)
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
Definition: MachineRegisterInfo.cpp:509
llvm::SIRegisterInfo
Definition: SIRegisterInfo.h:30
llvm::LiveInterval
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:686
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:647
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:660
AMDGPUMCTargetDesc.h
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
LiveIntervals.h
VirtRegMap.h
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
llvm::SIMachineFunctionInfo::reserveWWMRegister
void reserveWWMRegister(Register Reg)
Definition: SIMachineFunctionInfo.h:527
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
MachineFunctionPass.h
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:575
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::RegisterClassInfo
Definition: RegisterClassInfo.h:29
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::MachineFunction
Definition: MachineFunction.h:257
Matrix
Live Register Matrix
Definition: LiveRegMatrix.cpp:44
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:265
AMDGPU.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::AnalysisUsage::addPreserved
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Definition: PassAnalysisSupport.h:98
llvm::MachineOperand::setIsRenamable
void setIsRenamable(bool Val=true)
Definition: MachineOperand.cpp:137
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
DEBUG_TYPE
#define DEBUG_TYPE
Definition: SIPreAllocateWWMRegs.cpp:29
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:364
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
MachineFrameInfo.h
llvm::LiveIntervals
Definition: LiveIntervals.h:53
llvm::ReversePostOrderTraversal
Definition: PostOrderIterator.h:291
llvm::SIInstrInfo
Definition: SIInstrInfo.h:44
PostOrderIterator.h
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:56
llvm::SIMachineFunctionInfo
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Definition: SIMachineFunctionInfo.h:326
llvm::TargetRegisterInfo::getSubReg
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Definition: TargetRegisterInfo.h:1141
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition: PassAnalysisSupport.h:75
InitializePasses.h
SubReg
unsigned SubReg
Definition: AArch64AdvSIMDScalarPass.cpp:104
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:24
llvm::LiveRegMatrix
Definition: LiveRegMatrix.h:40