LLVM: lib/Target/AMDGPU/GCNPreRAOptimizations.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
41
42using namespace llvm;
43
44#define DEBUG_TYPE "amdgpu-pre-ra-optimizations"
45
46namespace {
47
48class GCNPreRAOptimizationsImpl {
49private:
54
56
57public:
58 GCNPreRAOptimizationsImpl(LiveIntervals *LS) : LIS(LS) {}
60};
61
63public:
64 static char ID;
65
68 }
69
71
72 StringRef getPassName() const override {
73 return "AMDGPU Pre-RA optimizations";
74 }
75
76 void getAnalysisUsage(AnalysisUsage &AU) const override {
80 }
81};
82}
83
85 "AMDGPU Pre-RA optimizations", false, false)
89
90char GCNPreRAOptimizationsLegacy::ID = 0;
91
93
95 return new GCNPreRAOptimizationsLegacy();
96}
97
98bool GCNPreRAOptimizationsImpl::processReg(Register Reg) {
104 bool IsAGPRDst = TRI->isAGPRClass(MRI->getRegClass(Reg));
105
107 switch (I.getOpcode()) {
108 default:
109 return false;
110 case AMDGPU::V_ACCVGPR_WRITE_B32_e64:
111 break;
112 case AMDGPU::COPY: {
113
114
115
116
117 if (!IsAGPRDst)
118 return false;
119
120 Register SrcReg = I.getOperand(1).getReg();
121
123 break;
124
125
126 bool IsAGPRSrc = TRI->isAGPRClass(MRI->getRegClass(SrcReg));
127 if (!IsAGPRSrc)
128 break;
129
130
131
132
133 Register SrcSubReg = I.getOperand(1).getSubReg();
134 for (auto &Def : MRI->def_instructions(SrcReg)) {
135 if (SrcSubReg != Def.getOperand(0).getSubReg())
136 continue;
137
138 if (Def.getOpcode() == AMDGPU::V_ACCVGPR_WRITE_B32_e64) {
140
141
142
143
145
146 I.getOperand(1).setReg(DefSrcMO.getReg());
147 I.getOperand(1).setSubReg(DefSrcMO.getSubReg());
148
149
150
152 ModifiedRegs.insert(SrcReg);
153
155 }
156
157
158 break;
159 }
160 }
161 break;
162 }
163 case AMDGPU::S_MOV_B32:
164 if (I.getOperand(0).getReg() != Reg || .getOperand(1).isImm() ||
165 I.getNumOperands() != 2)
166 return false;
167
168 switch (I.getOperand(0).getSubReg()) {
169 default:
170 return false;
171 case AMDGPU::sub0:
172 if (Def0)
173 return false;
174 Def0 = &I;
175 Init |= Lo_32(I.getOperand(1).getImm());
176 break;
177 case AMDGPU::sub1:
178 if (Def1)
179 return false;
180 Def1 = &I;
181 Init |= static_cast<uint64_t>(I.getOperand(1).getImm()) << 32;
182 break;
183 }
184 break;
185 }
186 }
187
188
189 if (IsAGPRDst) {
191 for (Register RegToUpdate : ModifiedRegs) {
194 }
195 }
196
198 }
199
200
203
204 LLVM_DEBUG(dbgs() << "Combining:\n " << *Def0 << " " << *Def1
205 << " =>\n");
206
210
214 TII->get(AMDGPU::S_MOV_B64_IMM_PSEUDO), Reg)
216
222
224
225 return true;
226}
227
228bool GCNPreRAOptimizationsLegacy::runOnMachineFunction(MachineFunction &MF) {
230 return false;
231 LiveIntervals *LIS = &getAnalysis().getLIS();
232 return GCNPreRAOptimizationsImpl(LIS).run(MF);
233}
234
235PreservedAnalyses
239 GCNPreRAOptimizationsImpl(LIS).run(MF);
241}
242
243bool GCNPreRAOptimizationsImpl::run(MachineFunction &MF) {
245 TII = ST.getInstrInfo();
247 TRI = ST.getRegisterInfo();
248
250
251 for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
254 continue;
257 (ST.hasGFX90AInsts() || ->isAGPRClass(RC)))
258 continue;
259
260 Changed |= processReg(Reg);
261 }
262
263 if (!ST.useRealTrue16Insts())
265
266
269 if (MI.getOpcode() != AMDGPU::COPY)
270 continue;
271 Register Dst = MI.getOperand(0).getReg();
272 Register Src = MI.getOperand(1).getReg();
273 if (Dst.isVirtual() &&
274 MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass &&
275 Src.isPhysical() &&
276 TRI->getRegClassForReg(*MRI, Src) == &AMDGPU::VGPR_32RegClass)
277 MRI->setRegAllocationHint(Dst, 0, TRI->getSubReg(Src, AMDGPU::lo16));
278 if (Src.isVirtual() &&
279 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass &&
280 Dst.isPhysical() &&
281 TRI->getRegClassForReg(*MRI, Dst) == &AMDGPU::VGPR_32RegClass)
282 MRI->setRegAllocationHint(Src, 0, TRI->getSubReg(Dst, AMDGPU::lo16));
283 if (!Dst.isVirtual() || !Src.isVirtual())
284 continue;
285 if (MRI->getRegClass(Dst) == &AMDGPU::VGPR_32RegClass &&
286 MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass) {
289 }
290 if (MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass &&
291 MRI->getRegClass(Src) == &AMDGPU::VGPR_32RegClass)
293 }
294 }
295
297}
unsigned const MachineRegisterInfo * MRI
const TargetInstrInfo & TII
Provides AMDGPU specific target descriptions.
AMD GCN specific subclass of TargetSubtarget.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Interface definition for SIRegisterInfo.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
FunctionPass class - This class is used to implement most global optimizations.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition GCNPreRAOptimizations.cpp:236
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
bool hasInterval(Register Reg) const
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
void removeInterval(Register Reg)
Interval removal.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
unsigned getSizeInBits() const
Return the size of the physical register in bits if we are able to determine it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static bool isEarlierInstr(SlotIndex A, SlotIndex B)
isEarlierInstr - Return true if A refers to an instruction earlier than B.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
StringRef - Represent a constant reference to a string, i.e.
const MCRegisterClass * MC
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
char & GCNPreRAOptimizationsID
Definition GCNPreRAOptimizations.cpp:92
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void initializeGCNPreRAOptimizationsLegacyPass(PassRegistry &)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
FunctionPass * createGCNPreRAOptimizationsLegacyPass()
Definition GCNPreRAOptimizations.cpp:94
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.