blob: 14b9e4fe0e3f348bddb6c968567bc3f96f260e2f [file] [log] [blame]
Tom Stellardc0b0c672013-02-06 17:32:29 +00001//===-- AMDGPUIndirectAddressing.cpp - Indirect Adressing Support ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10/// \file
11///
12/// Instructions can use indirect addressing to index the register file as if it
13/// were memory. This pass lowers RegisterLoad and RegisterStore instructions
14/// to either a COPY or a MOV that uses indirect addressing.
15//
16//===----------------------------------------------------------------------===//
17
18#include "AMDGPU.h"
19#include "R600InstrInfo.h"
20#include "R600MachineFunctionInfo.h"
21#include "llvm/CodeGen/MachineFunction.h"
22#include "llvm/CodeGen/MachineFunctionPass.h"
23#include "llvm/CodeGen/MachineInstrBuilder.h"
24#include "llvm/CodeGen/MachineRegisterInfo.h"
25#include "llvm/Support/Debug.h"
26
27using namespace llvm;
28
29namespace {
30
31class AMDGPUIndirectAddressingPass : public MachineFunctionPass {
32
33private:
34 static char ID;
35 const AMDGPUInstrInfo *TII;
36
37 bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const;
38
39public:
40 AMDGPUIndirectAddressingPass(TargetMachine &tm) :
41 MachineFunctionPass(ID),
42 TII(static_cast<const AMDGPUInstrInfo*>(tm.getInstrInfo()))
43 { }
44
45 virtual bool runOnMachineFunction(MachineFunction &MF);
46
47 const char *getPassName() const { return "R600 Handle indirect addressing"; }
48
49};
50
51} // End anonymous namespace
52
53char AMDGPUIndirectAddressingPass::ID = 0;
54
55FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) {
56 return new AMDGPUIndirectAddressingPass(tm);
57}
58
59bool AMDGPUIndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) {
60 MachineRegisterInfo &MRI = MF.getRegInfo();
61
62 int IndirectBegin = TII->getIndirectIndexBegin(MF);
63 int IndirectEnd = TII->getIndirectIndexEnd(MF);
64
65 if (IndirectBegin == -1) {
66 // No indirect addressing, we can skip this pass
67 assert(IndirectEnd == -1);
68 return false;
69 }
70
71 // The map keeps track of the indirect address that is represented by
72 // each virtual register. The key is the register and the value is the
73 // indirect address it uses.
74 std::map<unsigned, unsigned> RegisterAddressMap;
75
76 // First pass - Lower all of the RegisterStore instructions and track which
77 // registers are live.
78 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
79 BB != BB_E; ++BB) {
80 // This map keeps track of the current live indirect registers.
81 // The key is the address and the value is the register
82 std::map<unsigned, unsigned> LiveAddressRegisterMap;
83 MachineBasicBlock &MBB = *BB;
84
85 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
86 I != MBB.end(); I = Next) {
87 Next = llvm::next(I);
88 MachineInstr &MI = *I;
89
90 if (!TII->isRegisterStore(MI)) {
91 continue;
92 }
93
94 // Lower RegisterStore
95
96 unsigned RegIndex = MI.getOperand(2).getImm();
97 unsigned Channel = MI.getOperand(3).getImm();
98 unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
99 const TargetRegisterClass *IndirectStoreRegClass =
100 TII->getIndirectAddrStoreRegClass(MI.getOperand(0).getReg());
101
102 if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
103 // Direct register access.
104 unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
105
106 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
107 .addOperand(MI.getOperand(0));
108
109 RegisterAddressMap[DstReg] = Address;
110 LiveAddressRegisterMap[Address] = DstReg;
111 } else {
112 // Indirect register access.
113 MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I,
114 MI.getOperand(0).getReg(), // Value
115 Address,
116 MI.getOperand(1).getReg()); // Offset
117 for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
118 unsigned Addr = TII->calculateIndirectAddress(i, Channel);
119 unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
120 MOV.addReg(DstReg, RegState::Define | RegState::Implicit);
121 RegisterAddressMap[DstReg] = Addr;
122 LiveAddressRegisterMap[Addr] = DstReg;
123 }
124 }
125 MI.eraseFromParent();
126 }
127
128 // Update the live-ins of the succesor blocks
129 for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(),
130 SuccEnd = MBB.succ_end();
131 SuccEnd != Succ; ++Succ) {
132 std::map<unsigned, unsigned>::const_iterator Key, KeyEnd;
133 for (Key = LiveAddressRegisterMap.begin(),
134 KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) {
135 (*Succ)->addLiveIn(Key->second);
136 }
137 }
138 }
139
140 // Second pass - Lower the RegisterLoad instructions
141 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
142 BB != BB_E; ++BB) {
143 // Key is the address and the value is the register
144 std::map<unsigned, unsigned> LiveAddressRegisterMap;
145 MachineBasicBlock &MBB = *BB;
146
147 MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
148 while (LI != MBB.livein_end()) {
149 std::vector<unsigned> PhiRegisters;
150
151 // Make sure this live in is used for indirect addressing
152 if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
153 ++LI;
154 continue;
155 }
156
157 unsigned Address = RegisterAddressMap[*LI];
158 LiveAddressRegisterMap[Address] = *LI;
159 PhiRegisters.push_back(*LI);
160
161 // Check if there are other live in registers which map to the same
162 // indirect address.
163 for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
164 LE = MBB.livein_end();
165 LJ != LE; ++LJ) {
166 unsigned Reg = *LJ;
167 if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
168 continue;
169 }
170
171 if (RegisterAddressMap[Reg] == Address) {
Tom Stellardc0b0c672013-02-06 17:32:29 +0000172 PhiRegisters.push_back(Reg);
173 }
174 }
175
176 if (PhiRegisters.size() == 1) {
177 // We don't need to insert a Phi instruction, so we can just add the
178 // registers to the live list for the block.
179 LiveAddressRegisterMap[Address] = *LI;
180 MBB.removeLiveIn(*LI);
181 } else {
182 // We need to insert a PHI, because we have the same address being
183 // written in multiple predecessor blocks.
184 const TargetRegisterClass *PhiDstClass =
185 TII->getIndirectAddrStoreRegClass(*(PhiRegisters.begin()));
186 unsigned PhiDstReg = MRI.createVirtualRegister(PhiDstClass);
187 MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(),
188 MBB.findDebugLoc(MBB.begin()),
189 TII->get(AMDGPU::PHI), PhiDstReg);
190
191 for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(),
192 RE = PhiRegisters.end();
193 RI != RE; ++RI) {
194 unsigned Reg = *RI;
195 MachineInstr *DefInst = MRI.getVRegDef(Reg);
196 assert(DefInst);
197 MachineBasicBlock *RegBlock = DefInst->getParent();
198 Phi.addReg(Reg);
199 Phi.addMBB(RegBlock);
200 MBB.removeLiveIn(Reg);
201 }
202 RegisterAddressMap[PhiDstReg] = Address;
203 LiveAddressRegisterMap[Address] = PhiDstReg;
204 }
205 LI = MBB.livein_begin();
206 }
207
208 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
209 I != MBB.end(); I = Next) {
210 Next = llvm::next(I);
211 MachineInstr &MI = *I;
212
213 if (!TII->isRegisterLoad(MI)) {
214 if (MI.getOpcode() == AMDGPU::PHI) {
215 continue;
216 }
217 // Check for indirect register defs
218 for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands();
219 OpIdx < NumOperands; ++OpIdx) {
220 MachineOperand &MO = MI.getOperand(OpIdx);
221 if (MO.isReg() && MO.isDef() &&
222 RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) {
223 unsigned Reg = MO.getReg();
224 unsigned LiveAddress = RegisterAddressMap[Reg];
225 // Chain the live-ins
226 if (LiveAddressRegisterMap.find(LiveAddress) !=
Benjamin Kramer1983a4c2013-06-07 19:59:34 +0000227 LiveAddressRegisterMap.end()) {
Tom Stellardc0b0c672013-02-06 17:32:29 +0000228 MI.addOperand(MachineOperand::CreateReg(
229 LiveAddressRegisterMap[LiveAddress],
230 false, // isDef
231 true, // isImp
232 true)); // isKill
233 }
234 LiveAddressRegisterMap[LiveAddress] = Reg;
235 }
236 }
237 continue;
238 }
239
240 const TargetRegisterClass *SuperIndirectRegClass =
241 TII->getSuperIndirectRegClass();
242 const TargetRegisterClass *IndirectLoadRegClass =
243 TII->getIndirectAddrLoadRegClass();
244 unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass);
245
246 unsigned RegIndex = MI.getOperand(2).getImm();
247 unsigned Channel = MI.getOperand(3).getImm();
248 unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
249
250 if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
251 // Direct register access
252 unsigned Reg = LiveAddressRegisterMap[Address];
253 unsigned AddrReg = IndirectLoadRegClass->getRegister(Address);
254
255 if (regHasExplicitDef(MRI, Reg)) {
256 // If the register we are reading from has an explicit def, then that
257 // means it was written via a direct register access (i.e. COPY
258 // or other instruction that doesn't use indirect addressing). In
259 // this case we know where the value has been stored, so we can just
260 // issue a copy.
261 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
262 MI.getOperand(0).getReg())
263 .addReg(Reg);
264 } else {
265 // If the register we are reading has an implicit def, then that
266 // means it was written by an indirect register access (i.e. An
267 // instruction that uses indirect addressing.
268 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
269 MI.getOperand(0).getReg())
Tom Stellard403554c2013-02-19 15:22:42 +0000270 .addReg(AddrReg)
271 .addReg(Reg, RegState::Implicit);
Tom Stellardc0b0c672013-02-06 17:32:29 +0000272 }
273 } else {
274 // Indirect register access
275
276 // Note on REQ_SEQUENCE instructons: You can't actually use the register
277 // it defines unless you have an instruction that takes the defined
278 // register class as an operand.
279
280 MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
281 TII->get(AMDGPU::REG_SEQUENCE),
282 IndirectReg);
283 for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
284 unsigned Addr = TII->calculateIndirectAddress(i, Channel);
285 if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) {
286 continue;
287 }
288 unsigned Reg = LiveAddressRegisterMap[Addr];
289
290 // We only need to use REG_SEQUENCE for explicit defs, since the
291 // register coalescer won't do anything with the implicit defs.
Tom Stellard403554c2013-02-19 15:22:42 +0000292 if (!regHasExplicitDef(MRI, Reg)) {
Tom Stellardc0b0c672013-02-06 17:32:29 +0000293 continue;
294 }
295
296 // Insert a REQ_SEQUENCE instruction to force the register allocator
297 // to allocate the virtual register to the correct physical register.
298 Sequence.addReg(LiveAddressRegisterMap[Addr]);
299 Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(Addr));
300 }
301 MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I,
302 MI.getOperand(0).getReg(), // Value
303 Address,
304 MI.getOperand(1).getReg()); // Offset
305
306
307
308 Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
Tom Stellard403554c2013-02-19 15:22:42 +0000309 Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);
Tom Stellardc0b0c672013-02-06 17:32:29 +0000310
311 }
312 MI.eraseFromParent();
313 }
314 }
315 return false;
316}
317
318bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
319 unsigned Reg) const {
320 MachineInstr *DefInstr = MRI.getVRegDef(Reg);
Tom Stellard403554c2013-02-19 15:22:42 +0000321
322 if (!DefInstr) {
323 return false;
324 }
325
326 if (DefInstr->getOpcode() == AMDGPU::PHI) {
327 bool Explicit = false;
328 for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(),
329 E = DefInstr->operands_end();
330 I != E; ++I) {
331 const MachineOperand &MO = *I;
332 if (!MO.isReg() || MO.isDef()) {
333 continue;
334 }
335
336 Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
337 }
338 return Explicit;
339 }
340
341 return DefInstr->getOperand(0).isReg() &&
Tom Stellardc0b0c672013-02-06 17:32:29 +0000342 DefInstr->getOperand(0).getReg() == Reg;
343}