LLVM  15.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  dbgs() << "Entering ";
168  } else {
169  assert(Opc == AMDGPU::EXIT_STRICT_WWM || Opc == AMDGPU::EXIT_STRICT_WQM);
170  dbgs() << "Exiting ";
171  }
172 
173  if (Opc == AMDGPU::ENTER_STRICT_WWM || Opc == AMDGPU::EXIT_STRICT_WWM) {
174  dbgs() << "Strict WWM ";
175  } else {
176  assert(Opc == AMDGPU::ENTER_STRICT_WQM || Opc == AMDGPU::EXIT_STRICT_WQM);
177  dbgs() << "Strict WQM ";
178  }
179 
180  dbgs() << "region: " << MI;
181 }
182 
183 #endif
184 
185 bool SIPreAllocateWWMRegs::runOnMachineFunction(MachineFunction &MF) {
186  LLVM_DEBUG(dbgs() << "SIPreAllocateWWMRegs: function " << MF.getName() << "\n");
187 
188  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
189 
190  TII = ST.getInstrInfo();
191  TRI = &TII->getRegisterInfo();
192  MRI = &MF.getRegInfo();
193 
194  LIS = &getAnalysis<LiveIntervals>();
195  Matrix = &getAnalysis<LiveRegMatrix>();
196  VRM = &getAnalysis<VirtRegMap>();
197 
198  RegClassInfo.runOnMachineFunction(MF);
199 
200  bool RegsAssigned = false;
201 
202  // We use a reverse post-order traversal of the control-flow graph to
203  // guarantee that we visit definitions in dominance order. Since WWM
204  // expressions are guaranteed to never involve phi nodes, and we can only
205  // escape WWM through the special WWM instruction, this means that this is a
206  // perfect elimination order, so we can never do any better.
208 
209  for (MachineBasicBlock *MBB : RPOT) {
210  bool InWWM = false;
211  for (MachineInstr &MI : *MBB) {
212  if (MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B32 ||
213  MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B64)
214  RegsAssigned |= processDef(MI.getOperand(0));
215 
216  if (MI.getOpcode() == AMDGPU::ENTER_STRICT_WWM ||
217  MI.getOpcode() == AMDGPU::ENTER_STRICT_WQM) {
218  LLVM_DEBUG(printWWMInfo(MI));
219  InWWM = true;
220  continue;
221  }
222 
223  if (MI.getOpcode() == AMDGPU::EXIT_STRICT_WWM ||
224  MI.getOpcode() == AMDGPU::EXIT_STRICT_WQM) {
225  LLVM_DEBUG(printWWMInfo(MI));
226  InWWM = false;
227  }
228 
229  if (!InWWM)
230  continue;
231 
232  LLVM_DEBUG(dbgs() << "Processing " << MI);
233 
234  for (MachineOperand &DefOpnd : MI.defs()) {
235  RegsAssigned |= processDef(DefOpnd);
236  }
237  }
238  }
239 
240  if (!RegsAssigned)
241  return false;
242 
243  rewriteRegs(MF);
244  return true;
245 }
LiveRegMatrix.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
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:494
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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:581
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:103
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:666
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
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
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:313
llvm::MachineRegisterInfo::freezeReservedRegs
void freezeReservedRegs(const MachineFunction &)
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
Definition: MachineRegisterInfo.cpp:503
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:642
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:656
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:548
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:565
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::RegisterClassInfo
Definition: RegisterClassInfo.h:29
SI
StandardInstrumentations SI(Debug, VerifyEach)
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:263
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:134
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:54
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:53
llvm::SIMachineFunctionInfo
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Definition: SIMachineFunctionInfo.h:349
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:1113
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::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
llvm::LiveRegMatrix
Definition: LiveRegMatrix.h:40