LLVM  14.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"
22 #include "llvm/InitializePasses.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "si-pre-allocate-wwm-regs"
27 
28 namespace {
29 
30 class SIPreAllocateWWMRegs : public MachineFunctionPass {
31 private:
32  const SIInstrInfo *TII;
33  const SIRegisterInfo *TRI;
35  LiveIntervals *LIS;
37  VirtRegMap *VRM;
38  RegisterClassInfo RegClassInfo;
39 
40  std::vector<unsigned> RegsToRewrite;
41 #ifndef NDEBUG
42  void printWWMInfo(const MachineInstr &MI);
43 #endif
44 
45 public:
46  static char ID;
47 
48  SIPreAllocateWWMRegs() : MachineFunctionPass(ID) {
50  }
51 
52  bool runOnMachineFunction(MachineFunction &MF) override;
53 
54  void getAnalysisUsage(AnalysisUsage &AU) const override {
57  AU.addRequired<VirtRegMap>();
60  AU.setPreservesCFG();
62  }
63 
64 private:
65  bool processDef(MachineOperand &MO);
66  void rewriteRegs(MachineFunction &MF);
67 };
68 
69 } // End anonymous namespace.
70 
71 INITIALIZE_PASS_BEGIN(SIPreAllocateWWMRegs, DEBUG_TYPE,
72  "SI Pre-allocate WWM Registers", false, false)
76 INITIALIZE_PASS_END(SIPreAllocateWWMRegs, DEBUG_TYPE,
77  "SI Pre-allocate WWM Registers", false, false)
78 
79 char SIPreAllocateWWMRegs::ID = 0;
80 
81 char &llvm::SIPreAllocateWWMRegsID = SIPreAllocateWWMRegs::ID;
82 
84  return new SIPreAllocateWWMRegs();
85 }
86 
87 bool SIPreAllocateWWMRegs::processDef(MachineOperand &MO) {
88  if (!MO.isReg())
89  return false;
90 
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  return false;
115 }
116 
117 void SIPreAllocateWWMRegs::rewriteRegs(MachineFunction &MF) {
118  for (MachineBasicBlock &MBB : MF) {
119  for (MachineInstr &MI : MBB) {
120  for (MachineOperand &MO : MI.operands()) {
121  if (!MO.isReg())
122  continue;
123 
124  const Register VirtReg = MO.getReg();
125  if (VirtReg.isPhysical())
126  continue;
127 
128  if (!VRM->hasPhys(VirtReg))
129  continue;
130 
131  Register PhysReg = VRM->getPhys(VirtReg);
132  const unsigned SubReg = MO.getSubReg();
133  if (SubReg != 0) {
134  PhysReg = TRI->getSubReg(PhysReg, SubReg);
135  MO.setSubReg(0);
136  }
137 
138  MO.setReg(PhysReg);
139  MO.setIsRenamable(false);
140  }
141  }
142  }
143 
144  SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
145  MachineFrameInfo &FrameInfo = MF.getFrameInfo();
146 
147  for (unsigned Reg : RegsToRewrite) {
148  LIS->removeInterval(Reg);
149 
150  const Register PhysReg = VRM->getPhys(Reg);
151  assert(PhysReg != 0);
152 
153  // Check if PhysReg is already reserved
154  if (!MFI->WWMReservedRegs.count(PhysReg)) {
155  Optional<int> FI;
156  if (!MFI->isEntryFunction()) {
157  // Create a stack object for a possible spill in the function prologue.
158  // Note: Non-CSR VGPR also need this as we may overwrite inactive lanes.
159  const TargetRegisterClass *RC = TRI->getPhysRegClass(PhysReg);
160  FI = FrameInfo.CreateSpillStackObject(TRI->getSpillSize(*RC),
161  TRI->getSpillAlign(*RC));
162  }
163  MFI->reserveWWMRegister(PhysReg, FI);
164  }
165  }
166 
167  RegsToRewrite.clear();
168 
169  // Update the set of reserved registers to include WWM ones.
170  MRI->freezeReservedRegs(MF);
171 }
172 
173 #ifndef NDEBUG
174 LLVM_DUMP_METHOD void
175 SIPreAllocateWWMRegs::printWWMInfo(const MachineInstr &MI) {
176 
177  unsigned Opc = MI.getOpcode();
178 
179  if (Opc == AMDGPU::ENTER_STRICT_WWM || Opc == AMDGPU::ENTER_STRICT_WQM) {
180  dbgs() << "Entering ";
181  } else {
182  assert(Opc == AMDGPU::EXIT_STRICT_WWM || Opc == AMDGPU::EXIT_STRICT_WQM);
183  dbgs() << "Exiting ";
184  }
185 
186  if (Opc == AMDGPU::ENTER_STRICT_WWM || Opc == AMDGPU::EXIT_STRICT_WWM) {
187  dbgs() << "Strict WWM ";
188  } else {
189  assert(Opc == AMDGPU::ENTER_STRICT_WQM || Opc == AMDGPU::EXIT_STRICT_WQM);
190  dbgs() << "Strict WQM ";
191  }
192 
193  dbgs() << "region: " << MI;
194 }
195 
196 #endif
197 
198 bool SIPreAllocateWWMRegs::runOnMachineFunction(MachineFunction &MF) {
199  LLVM_DEBUG(dbgs() << "SIPreAllocateWWMRegs: function " << MF.getName() << "\n");
200 
201  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
202 
203  TII = ST.getInstrInfo();
204  TRI = &TII->getRegisterInfo();
205  MRI = &MF.getRegInfo();
206 
207  LIS = &getAnalysis<LiveIntervals>();
208  Matrix = &getAnalysis<LiveRegMatrix>();
209  VRM = &getAnalysis<VirtRegMap>();
210 
211  RegClassInfo.runOnMachineFunction(MF);
212 
213  bool RegsAssigned = false;
214 
215  // We use a reverse post-order traversal of the control-flow graph to
216  // guarantee that we visit definitions in dominance order. Since WWM
217  // expressions are guaranteed to never involve phi nodes, and we can only
218  // escape WWM through the special WWM instruction, this means that this is a
219  // perfect elimination order, so we can never do any better.
221 
222  for (MachineBasicBlock *MBB : RPOT) {
223  bool InWWM = false;
224  for (MachineInstr &MI : *MBB) {
225  if (MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B32 ||
226  MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B64)
227  RegsAssigned |= processDef(MI.getOperand(0));
228 
229  if (MI.getOpcode() == AMDGPU::ENTER_STRICT_WWM ||
230  MI.getOpcode() == AMDGPU::ENTER_STRICT_WQM) {
231  LLVM_DEBUG(printWWMInfo(MI));
232  InWWM = true;
233  continue;
234  }
235 
236  if (MI.getOpcode() == AMDGPU::EXIT_STRICT_WWM ||
237  MI.getOpcode() == AMDGPU::EXIT_STRICT_WQM) {
238  LLVM_DEBUG(printWWMInfo(MI));
239  InWWM = false;
240  }
241 
242  if (!InWWM)
243  continue;
244 
245  LLVM_DEBUG(dbgs() << "Processing " << MI);
246 
247  for (MachineOperand &DefOpnd : MI.defs()) {
248  RegsAssigned |= processDef(DefOpnd);
249  }
250  }
251  }
252 
253  if (!RegsAssigned)
254  return false;
255 
256  rewriteRegs(MF);
257  return true;
258 }
LiveRegMatrix.h
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
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:491
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
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:585
SIMachineFunctionInfo.h
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::initializeSIPreAllocateWWMRegsPass
void initializeSIPreAllocateWWMRegsPass(PassRegistry &)
llvm::VirtRegMap
Definition: VirtRegMap.h:33
Registers
SI Pre allocate WWM Registers
Definition: SIPreAllocateWWMRegs.cpp:77
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::Optional< int >
llvm::GCNSubtarget
Definition: GCNSubtarget.h:31
llvm::createSIPreAllocateWWMRegsPass
FunctionPass * createSIPreAllocateWWMRegsPass()
Definition: SIPreAllocateWWMRegs.cpp:83
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:81
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
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:636
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:471
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
false
Definition: StackSlotColoring.cpp:142
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::SlotIndexes
SlotIndexes pass.
Definition: SlotIndexes.h:314
llvm::MachineRegisterInfo::freezeReservedRegs
void freezeReservedRegs(const MachineFunction &)
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
Definition: MachineRegisterInfo.cpp:507
llvm::SIRegisterInfo
Definition: SIRegisterInfo.h:28
llvm::LiveInterval
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:680
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
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:634
llvm::TargetRegisterInfo::getSpillAlign
Align getSpillAlign(const TargetRegisterClass &RC) const
Return the minimum required alignment in bytes for a spill slot for a register of this class.
Definition: TargetRegisterInfo.h:288
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::SIMachineFunctionInfo::WWMReservedRegs
MapVector< Register, Optional< int > > WWMReservedRegs
Definition: SIMachineFunctionInfo.h:470
llvm::TargetRegisterInfo::getSpillSize
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
Definition: TargetRegisterInfo.h:282
AMDGPUMCTargetDesc.h
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
LiveIntervals.h
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::SIMachineFunctionInfo::reserveWWMRegister
void reserveWWMRegister(Register Reg, Optional< int > FI)
Definition: SIMachineFunctionInfo.h:513
llvm::AMDGPUMachineFunction::isEntryFunction
bool isEntryFunction() const
Definition: AMDGPUMachineFunction.h:78
MachineFunctionPass.h
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:541
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::RegisterClassInfo
Definition: RegisterClassInfo.h:30
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:230
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:253
AMDGPU.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
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:136
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
DEBUG_TYPE
#define DEBUG_TYPE
Definition: SIPreAllocateWWMRegs.cpp:26
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:365
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::LiveIntervals
Definition: LiveIntervals.h:54
llvm::ReversePostOrderTraversal
Definition: PostOrderIterator.h:290
llvm::SIInstrInfo
Definition: SIInstrInfo.h:38
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
PostOrderIterator.h
llvm::MachineOperand::setReg
void setReg(Register Reg)
Change the register this operand corresponds to.
Definition: MachineOperand.cpp:55
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::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:1094
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
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:23
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::LiveRegMatrix
Definition: LiveRegMatrix.h:40