]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/llvm/lib/Target/R600/AMDGPUIndirectAddressing.cpp
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / llvm / lib / Target / R600 / AMDGPUIndirectAddressing.cpp
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
27 using namespace llvm;
28
29 namespace {
30
31 class AMDGPUIndirectAddressingPass : public MachineFunctionPass {
32
33 private:
34   static char ID;
35   const AMDGPUInstrInfo *TII;
36
37   bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const;
38
39 public:
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
53 char AMDGPUIndirectAddressingPass::ID = 0;
54
55 FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) {
56   return new AMDGPUIndirectAddressingPass(tm);
57 }
58
59 bool 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
318 bool 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 }