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 } 344