Home | History | Annotate | Download | only in R600
      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(0)
     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   TII = static_cast<const AMDGPUInstrInfo*>(MF.getTarget().getInstrInfo());
     63 
     64   int IndirectBegin = TII->getIndirectIndexBegin(MF);
     65   int IndirectEnd = TII->getIndirectIndexEnd(MF);
     66 
     67   if (IndirectBegin == -1) {
     68     // No indirect addressing, we can skip this pass
     69     assert(IndirectEnd == -1);
     70     return false;
     71   }
     72 
     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;
     77 
     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();
     81                                                       BB != BB_E; ++BB) {
     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;
     86 
     87     for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I);
     88                                I != MBB.end(); I = Next) {
     89       Next = llvm::next(I);
     90       MachineInstr &MI = *I;
     91 
     92       if (!TII->isRegisterStore(MI)) {
     93         continue;
     94       }
     95 
     96       // Lower RegisterStore
     97 
     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());
    103 
    104       if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) {
    105         // Direct register access.
    106         unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass);
    107 
    108         BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg)
    109                 .addOperand(MI.getOperand(0));
    110 
    111         RegisterAddressMap[DstReg] = Address;
    112         LiveAddressRegisterMap[Address] = DstReg;
    113       } else {
    114         // Indirect register access.
    115         MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I,
    116                                            MI.getOperand(0).getReg(), // Value
    117                                            Address,
    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;
    125         }
    126       }
    127       MI.eraseFromParent();
    128     }
    129 
    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);
    138       }
    139     }
    140   }
    141 
    142   // Second pass - Lower the RegisterLoad instructions
    143   for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end();
    144                                                       BB != BB_E; ++BB) {
    145     // Key is the address and the value is the register
    146     std::map<unsigned, unsigned> LiveAddressRegisterMap;
    147     MachineBasicBlock &MBB = *BB;
    148 
    149     MachineBasicBlock::livein_iterator LI = MBB.livein_begin();
    150     while (LI != MBB.livein_end()) {
    151       std::vector<unsigned> PhiRegisters;
    152 
    153       // Make sure this live in is used for indirect addressing
    154       if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) {
    155         ++LI;
    156         continue;
    157       }
    158 
    159       unsigned Address = RegisterAddressMap[*LI];
    160       LiveAddressRegisterMap[Address] = *LI;
    161       PhiRegisters.push_back(*LI);
    162 
    163       // Check if there are other live in registers which map to the same
    164       // indirect address.
    165       for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI),
    166                                               LE = MBB.livein_end();
    167                                               LJ != LE; ++LJ) {
    168         unsigned Reg = *LJ;
    169         if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) {
    170           continue;
    171         }
    172 
    173         if (RegisterAddressMap[Reg] == Address) {
    174           PhiRegisters.push_back(Reg);
    175         }
    176       }
    177 
    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);
    183       } else {
    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);
    192 
    193         for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(),
    194                                                    RE = PhiRegisters.end();
    195                                                    RI != RE; ++RI) {
    196           unsigned Reg = *RI;
    197           MachineInstr *DefInst = MRI.getVRegDef(Reg);
    198           assert(DefInst);
    199           MachineBasicBlock *RegBlock = DefInst->getParent();
    200           Phi.addReg(Reg);
    201           Phi.addMBB(RegBlock);
    202           MBB.removeLiveIn(Reg);
    203         }
    204         RegisterAddressMap[PhiDstReg] = Address;
    205         LiveAddressRegisterMap[Address] = PhiDstReg;
    206       }
    207       LI = MBB.livein_begin();
    208     }
    209 
    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;
    214 
    215       if (!TII->isRegisterLoad(MI)) {
    216         if (MI.getOpcode() == AMDGPU::PHI) {
    217           continue;
    218         }
    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],
    232                                   false, // isDef
    233                                   true,  // isImp
    234                                   true));  // isKill
    235             }
    236             LiveAddressRegisterMap[LiveAddress] = Reg;
    237           }
    238         }
    239         continue;
    240       }
    241 
    242       const TargetRegisterClass *SuperIndirectRegClass =
    243                                                 TII->getSuperIndirectRegClass();
    244       const TargetRegisterClass *IndirectLoadRegClass =
    245                                              TII->getIndirectAddrLoadRegClass();
    246       unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass);
    247 
    248       unsigned RegIndex = MI.getOperand(2).getImm();
    249       unsigned Channel = MI.getOperand(3).getImm();
    250       unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel);
    251 
    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);
    256 
    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
    262           // issue a copy.
    263           BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY),
    264                   MI.getOperand(0).getReg())
    265                   .addReg(Reg);
    266         } else {
    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())
    272                    .addReg(AddrReg)
    273                    .addReg(Reg, RegState::Implicit);
    274         }
    275       } else {
    276         // Indirect register access
    277 
    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.
    281 
    282         MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I),
    283                                                TII->get(AMDGPU::REG_SEQUENCE),
    284                                                IndirectReg);
    285         for (int i = IndirectBegin; i <= IndirectEnd; ++i) {
    286           unsigned Addr = TII->calculateIndirectAddress(i, Channel);
    287           if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) {
    288             continue;
    289           }
    290           unsigned Reg = LiveAddressRegisterMap[Addr];
    291 
    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)) {
    295             continue;
    296           }
    297 
    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));
    302         }
    303         MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I,
    304                                            MI.getOperand(0).getReg(), // Value
    305                                            Address,
    306                                            MI.getOperand(1).getReg()); // Offset
    307 
    308 
    309 
    310         Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill);
    311         Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit);
    312 
    313       }
    314       MI.eraseFromParent();
    315     }
    316   }
    317   return false;
    318 }
    319 
    320 bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI,
    321                                                   unsigned Reg) const {
    322   MachineInstr *DefInstr = MRI.getVRegDef(Reg);
    323 
    324   if (!DefInstr) {
    325     return false;
    326   }
    327 
    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();
    332                                           I != E; ++I) {
    333       const MachineOperand &MO = *I;
    334       if (!MO.isReg() || MO.isDef()) {
    335         continue;
    336       }
    337 
    338       Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg());
    339     }
    340     return Explicit;
    341   }
    342 
    343   return DefInstr->getOperand(0).isReg() &&
    344          DefInstr->getOperand(0).getReg() == Reg;
    345 }
    346