1//===-- 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) {
172          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) !=
227                                                     RegisterAddressMap.end()) {
228              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())
270                   .addReg(AddrReg)
271                   .addReg(Reg, RegState::Implicit);
272        }
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.
292          if (!regHasExplicitDef(MRI, Reg)) {
293            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);
309        Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);
310
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);
321
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() &&
342         DefInstr->getOperand(0).getReg() == Reg;
343}
344