1 //===-- AMDGPUIndirectAddressing.cpp - Indirect Adressing Support ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
16 //===----------------------------------------------------------------------===//
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"
31 class AMDGPUIndirectAddressingPass : public MachineFunctionPass {
35 const AMDGPUInstrInfo *TII;
37 bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const;
40 AMDGPUIndirectAddressingPass(TargetMachine &tm) :
41 MachineFunctionPass(ID),
45 virtual bool runOnMachineFunction(MachineFunction &MF);
47 const char *getPassName() const { return "R600 Handle indirect addressing"; }
51 } // End anonymous namespace
53 char AMDGPUIndirectAddressingPass::ID = 0;
55 FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) {
56 return new AMDGPUIndirectAddressingPass(tm);
59 bool AMDGPUIndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) {
60 MachineRegisterInfo &MRI = MF.getRegInfo();
62 TII = static_cast<const AMDGPUInstrInfo*>(MF.getTarget().getInstrInfo());
64 int IndirectBegin = TII->getIndirectIndexBegin(MF);
65 int IndirectEnd = TII->getIndirectIndexEnd(MF);
67 if (IndirectBegin == -1) {
68 // No indirect addressing, we can skip this pass
69 assert(IndirectEnd == -1);
73 // The map keeps track of the indirect address that is represented by
74 // each virtual register. The key is the register and the value is the
75 // indirect address it uses.
76 std::map<unsigned, unsigned> RegisterAddressMap;
78 // First pass - Lower all of the RegisterStore instructions and track which
79 // registers are live.
80 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
82 // This map keeps track of the current live indirect registers.
83 // The key is the address and the value is the register
84 std::map<unsigned, unsigned> LiveAddressRegisterMap;
85 MachineBasicBlock &MBB = *BB;
87 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
88 I != MBB.end(); I = Next) {
90 MachineInstr &MI = *I;
92 if (!TII->isRegisterStore(MI)) {
96 // Lower RegisterStore
98 unsigned RegIndex = MI.getOperand(2).getImm();
99 unsigned Channel = MI.getOperand(3).getImm();
100 unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
101 const TargetRegisterClass *IndirectStoreRegClass =
102 TII->getIndirectAddrStoreRegClass(MI.getOperand(0).getReg());
104 if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
105 // Direct register access.
106 unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
108 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
109 .addOperand(MI.getOperand(0));
111 RegisterAddressMap[DstReg] = Address;
112 LiveAddressRegisterMap[Address] = DstReg;
114 // Indirect register access.
115 MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I,
116 MI.getOperand(0).getReg(), // Value
118 MI.getOperand(1).getReg()); // Offset
119 for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
120 unsigned Addr = TII->calculateIndirectAddress(i, Channel);
121 unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
122 MOV.addReg(DstReg, RegState::Define | RegState::Implicit);
123 RegisterAddressMap[DstReg] = Addr;
124 LiveAddressRegisterMap[Addr] = DstReg;
127 MI.eraseFromParent();
130 // Update the live-ins of the succesor blocks
131 for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(),
132 SuccEnd = MBB.succ_end();
133 SuccEnd != Succ; ++Succ) {
134 std::map<unsigned, unsigned>::const_iterator Key, KeyEnd;
135 for (Key = LiveAddressRegisterMap.begin(),
136 KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) {
137 (*Succ)->addLiveIn(Key->second);
142 // Second pass - Lower the RegisterLoad instructions
143 for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
145 // Key is the address and the value is the register
146 std::map<unsigned, unsigned> LiveAddressRegisterMap;
147 MachineBasicBlock &MBB = *BB;
149 MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
150 while (LI != MBB.livein_end()) {
151 std::vector<unsigned> PhiRegisters;
153 // Make sure this live in is used for indirect addressing
154 if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
159 unsigned Address = RegisterAddressMap[*LI];
160 LiveAddressRegisterMap[Address] = *LI;
161 PhiRegisters.push_back(*LI);
163 // Check if there are other live in registers which map to the same
165 for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
166 LE = MBB.livein_end();
169 if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
173 if (RegisterAddressMap[Reg] == Address) {
174 PhiRegisters.push_back(Reg);
178 if (PhiRegisters.size() == 1) {
179 // We don't need to insert a Phi instruction, so we can just add the
180 // registers to the live list for the block.
181 LiveAddressRegisterMap[Address] = *LI;
182 MBB.removeLiveIn(*LI);
184 // We need to insert a PHI, because we have the same address being
185 // written in multiple predecessor blocks.
186 const TargetRegisterClass *PhiDstClass =
187 TII->getIndirectAddrStoreRegClass(*(PhiRegisters.begin()));
188 unsigned PhiDstReg = MRI.createVirtualRegister(PhiDstClass);
189 MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(),
190 MBB.findDebugLoc(MBB.begin()),
191 TII->get(AMDGPU::PHI), PhiDstReg);
193 for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(),
194 RE = PhiRegisters.end();
197 MachineInstr *DefInst = MRI.getVRegDef(Reg);
199 MachineBasicBlock *RegBlock = DefInst->getParent();
201 Phi.addMBB(RegBlock);
202 MBB.removeLiveIn(Reg);
204 RegisterAddressMap[PhiDstReg] = Address;
205 LiveAddressRegisterMap[Address] = PhiDstReg;
207 LI = MBB.livein_begin();
210 for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
211 I != MBB.end(); I = Next) {
212 Next = llvm::next(I);
213 MachineInstr &MI = *I;
215 if (!TII->isRegisterLoad(MI)) {
216 if (MI.getOpcode() == AMDGPU::PHI) {
219 // Check for indirect register defs
220 for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands();
221 OpIdx < NumOperands; ++OpIdx) {
222 MachineOperand &MO = MI.getOperand(OpIdx);
223 if (MO.isReg() && MO.isDef() &&
224 RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) {
225 unsigned Reg = MO.getReg();
226 unsigned LiveAddress = RegisterAddressMap[Reg];
227 // Chain the live-ins
228 if (LiveAddressRegisterMap.find(LiveAddress) !=
229 LiveAddressRegisterMap.end()) {
230 MI.addOperand(MachineOperand::CreateReg(
231 LiveAddressRegisterMap[LiveAddress],
236 LiveAddressRegisterMap[LiveAddress] = Reg;
242 const TargetRegisterClass *SuperIndirectRegClass =
243 TII->getSuperIndirectRegClass();
244 const TargetRegisterClass *IndirectLoadRegClass =
245 TII->getIndirectAddrLoadRegClass();
246 unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass);
248 unsigned RegIndex = MI.getOperand(2).getImm();
249 unsigned Channel = MI.getOperand(3).getImm();
250 unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
252 if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
253 // Direct register access
254 unsigned Reg = LiveAddressRegisterMap[Address];
255 unsigned AddrReg = IndirectLoadRegClass->getRegister(Address);
257 if (regHasExplicitDef(MRI, Reg)) {
258 // If the register we are reading from has an explicit def, then that
259 // means it was written via a direct register access (i.e. COPY
260 // or other instruction that doesn't use indirect addressing). In
261 // this case we know where the value has been stored, so we can just
263 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
264 MI.getOperand(0).getReg())
267 // If the register we are reading has an implicit def, then that
268 // means it was written by an indirect register access (i.e. An
269 // instruction that uses indirect addressing.
270 BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
271 MI.getOperand(0).getReg())
273 .addReg(Reg, RegState::Implicit);
276 // Indirect register access
278 // Note on REQ_SEQUENCE instructons: You can't actually use the register
279 // it defines unless you have an instruction that takes the defined
280 // register class as an operand.
282 MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
283 TII->get(AMDGPU::REG_SEQUENCE),
285 for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
286 unsigned Addr = TII->calculateIndirectAddress(i, Channel);
287 if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) {
290 unsigned Reg = LiveAddressRegisterMap[Addr];
292 // We only need to use REG_SEQUENCE for explicit defs, since the
293 // register coalescer won't do anything with the implicit defs.
294 if (!regHasExplicitDef(MRI, Reg)) {
298 // Insert a REQ_SEQUENCE instruction to force the register allocator
299 // to allocate the virtual register to the correct physical register.
300 Sequence.addReg(LiveAddressRegisterMap[Addr]);
301 Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(Addr));
303 MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I,
304 MI.getOperand(0).getReg(), // Value
306 MI.getOperand(1).getReg()); // Offset
310 Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
311 Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);
314 MI.eraseFromParent();
320 bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
321 unsigned Reg) const {
322 MachineInstr *DefInstr = MRI.getVRegDef(Reg);
328 if (DefInstr->getOpcode() == AMDGPU::PHI) {
329 bool Explicit = false;
330 for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(),
331 E = DefInstr->operands_end();
333 const MachineOperand &MO = *I;
334 if (!MO.isReg() || MO.isDef()) {
338 Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
343 return DefInstr->getOperand(0).isReg() &&
344 DefInstr->getOperand(0).getReg() == Reg;