LLVM  12.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 "AMDGPUSubtarget.h"
17 #include "SIInstrInfo.h"
18 #include "SIMachineFunctionInfo.h"
19 #include "SIRegisterInfo.h"
28 #include "llvm/InitializePasses.h"
29 
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "si-pre-allocate-wwm-regs"
33 
34 namespace {
35 
36 class SIPreAllocateWWMRegs : public MachineFunctionPass {
37 private:
38  const SIInstrInfo *TII;
39  const SIRegisterInfo *TRI;
41  LiveIntervals *LIS;
43  VirtRegMap *VRM;
44  RegisterClassInfo RegClassInfo;
45 
46  std::vector<unsigned> RegsToRewrite;
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  if (!MO.isReg())
92  return false;
93 
94  Register Reg = MO.getReg();
95 
96  if (!TRI->isVGPR(*MRI, Reg))
97  return false;
98 
100  return false;
101 
102  if (VRM->hasPhys(Reg))
103  return false;
104 
105  LiveInterval &LI = LIS->getInterval(Reg);
106 
107  for (unsigned PhysReg : RegClassInfo.getOrder(MRI->getRegClass(Reg))) {
108  if (!MRI->isPhysRegUsed(PhysReg) &&
109  Matrix->checkInterference(LI, PhysReg) == LiveRegMatrix::IK_Free) {
110  Matrix->assign(LI, PhysReg);
111  assert(PhysReg != 0);
112  RegsToRewrite.push_back(Reg);
113  return true;
114  }
115  }
116 
117  llvm_unreachable("physreg not found for WWM expression");
118  return false;
119 }
120 
121 void SIPreAllocateWWMRegs::rewriteRegs(MachineFunction &MF) {
122  for (MachineBasicBlock &MBB : MF) {
123  for (MachineInstr &MI : MBB) {
124  for (MachineOperand &MO : MI.operands()) {
125  if (!MO.isReg())
126  continue;
127 
128  const Register VirtReg = MO.getReg();
129  if (Register::isPhysicalRegister(VirtReg))
130  continue;
131 
132  if (!VRM->hasPhys(VirtReg))
133  continue;
134 
135  Register PhysReg = VRM->getPhys(VirtReg);
136  const unsigned SubReg = MO.getSubReg();
137  if (SubReg != 0) {
138  PhysReg = TRI->getSubReg(PhysReg, SubReg);
139  MO.setSubReg(0);
140  }
141 
142  MO.setReg(PhysReg);
143  MO.setIsRenamable(false);
144  }
145  }
146  }
147 
148  SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>();
149 
150  for (unsigned Reg : RegsToRewrite) {
151  LIS->removeInterval(Reg);
152 
153  const Register PhysReg = VRM->getPhys(Reg);
154  assert(PhysReg != 0);
155  MFI->ReserveWWMRegister(PhysReg);
156  }
157 
158  RegsToRewrite.clear();
159 
160  // Update the set of reserved registers to include WWM ones.
161  MRI->freezeReservedRegs(MF);
162 }
163 
164 bool SIPreAllocateWWMRegs::runOnMachineFunction(MachineFunction &MF) {
165  LLVM_DEBUG(dbgs() << "SIPreAllocateWWMRegs: function " << MF.getName() << "\n");
166 
167  const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
168 
169  TII = ST.getInstrInfo();
170  TRI = &TII->getRegisterInfo();
171  MRI = &MF.getRegInfo();
172 
173  LIS = &getAnalysis<LiveIntervals>();
174  Matrix = &getAnalysis<LiveRegMatrix>();
175  VRM = &getAnalysis<VirtRegMap>();
176 
177  RegClassInfo.runOnMachineFunction(MF);
178 
179  bool RegsAssigned = false;
180 
181  // We use a reverse post-order traversal of the control-flow graph to
182  // guarantee that we visit definitions in dominance order. Since WWM
183  // expressions are guaranteed to never involve phi nodes, and we can only
184  // escape WWM through the special WWM instruction, this means that this is a
185  // perfect elimination order, so we can never do any better.
187 
188  for (MachineBasicBlock *MBB : RPOT) {
189  bool InWWM = false;
190  for (MachineInstr &MI : *MBB) {
191  if (MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B32 ||
192  MI.getOpcode() == AMDGPU::V_SET_INACTIVE_B64)
193  RegsAssigned |= processDef(MI.getOperand(0));
194 
195  if (MI.getOpcode() == AMDGPU::ENTER_WWM) {
196  LLVM_DEBUG(dbgs() << "entering WWM region: " << MI << "\n");
197  InWWM = true;
198  continue;
199  }
200 
201  if (MI.getOpcode() == AMDGPU::EXIT_WWM) {
202  LLVM_DEBUG(dbgs() << "exiting WWM region: " << MI << "\n");
203  InWWM = false;
204  }
205 
206  if (!InWWM)
207  continue;
208 
209  LLVM_DEBUG(dbgs() << "processing " << MI << "\n");
210 
211  for (MachineOperand &DefOpnd : MI.defs()) {
212  RegsAssigned |= processDef(DefOpnd);
213  }
214  }
215  }
216 
217  if (!RegsAssigned)
218  return false;
219 
220  rewriteRegs(MF);
221  return true;
222 }
Interface definition for SIRegisterInfo.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
No interference, go ahead and assign.
Definition: LiveRegMatrix.h:85
AMDGPU specific subclass of TargetSubtarget.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
LiveInterval - This class represents the liveness of a register, or stack slot.
Definition: LiveInterval.h:680
unsigned Reg
unsigned getSubReg() const
unsigned const TargetRegisterInfo * TRI
void setIsRenamable(bool Val=true)
Live Register Matrix
MachineBasicBlock & MBB
AnalysisUsage & addRequired()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned SubReg
SlotIndexes pass.
Definition: SlotIndexes.h:314
INITIALIZE_PASS_BEGIN(SIPreAllocateWWMRegs, DEBUG_TYPE, "SI Pre-allocate WWM Registers", false, false) INITIALIZE_PASS_END(SIPreAllocateWWMRegs
void setReg(Register Reg)
Change the register this operand corresponds to.
SI Pre allocate WWM Registers
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define DEBUG_TYPE
FunctionPass * createSIPreAllocateWWMRegsPass()
MachineOperand class - Representation of each machine instruction operand.
char & SIPreAllocateWWMRegsID
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Provides AMDGPU specific target descriptions.
Representation of each machine instruction.
Definition: MachineInstr.h:62
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void setSubReg(unsigned subReg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
Register getReg() const
getReg - Returns the register number.
#define LLVM_DEBUG(X)
Definition: Debug.h:122
void initializeSIPreAllocateWWMRegsPass(PassRegistry &)
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
const SIRegisterInfo * getRegisterInfo() const override