diff options
Diffstat (limited to 'contrib/llvm/lib/Target/R600/AMDGPUIndirectAddressing.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/R600/AMDGPUIndirectAddressing.cpp | 343 |
1 files changed, 0 insertions, 343 deletions
diff --git a/contrib/llvm/lib/Target/R600/AMDGPUIndirectAddressing.cpp b/contrib/llvm/lib/Target/R600/AMDGPUIndirectAddressing.cpp deleted file mode 100644 index ed6c8ec..0000000 --- a/contrib/llvm/lib/Target/R600/AMDGPUIndirectAddressing.cpp +++ /dev/null @@ -1,343 +0,0 @@ -//===-- AMDGPUIndirectAddressing.cpp - Indirect Adressing Support ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -/// \file -/// -/// Instructions can use indirect addressing to index the register file as if it -/// were memory. This pass lowers RegisterLoad and RegisterStore instructions -/// to either a COPY or a MOV that uses indirect addressing. -// -//===----------------------------------------------------------------------===// - -#include "AMDGPU.h" -#include "R600InstrInfo.h" -#include "R600MachineFunctionInfo.h" -#include "llvm/CodeGen/MachineFunction.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/Debug.h" - -using namespace llvm; - -namespace { - -class AMDGPUIndirectAddressingPass : public MachineFunctionPass { - -private: - static char ID; - const AMDGPUInstrInfo *TII; - - bool regHasExplicitDef(MachineRegisterInfo &MRI, unsigned Reg) const; - -public: - AMDGPUIndirectAddressingPass(TargetMachine &tm) : - MachineFunctionPass(ID), - TII(static_cast<const AMDGPUInstrInfo*>(tm.getInstrInfo())) - { } - - virtual bool runOnMachineFunction(MachineFunction &MF); - - const char *getPassName() const { return "R600 Handle indirect addressing"; } - -}; - -} // End anonymous namespace - -char AMDGPUIndirectAddressingPass::ID = 0; - -FunctionPass *llvm::createAMDGPUIndirectAddressingPass(TargetMachine &tm) { - return new AMDGPUIndirectAddressingPass(tm); -} - -bool AMDGPUIndirectAddressingPass::runOnMachineFunction(MachineFunction &MF) { - MachineRegisterInfo &MRI = MF.getRegInfo(); - - int IndirectBegin = TII->getIndirectIndexBegin(MF); - int IndirectEnd = TII->getIndirectIndexEnd(MF); - - if (IndirectBegin == -1) { - // No indirect addressing, we can skip this pass - assert(IndirectEnd == -1); - return false; - } - - // The map keeps track of the indirect address that is represented by - // each virtual register. The key is the register and the value is the - // indirect address it uses. - std::map<unsigned, unsigned> RegisterAddressMap; - - // First pass - Lower all of the RegisterStore instructions and track which - // registers are live. - for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); - BB != BB_E; ++BB) { - // This map keeps track of the current live indirect registers. - // The key is the address and the value is the register - std::map<unsigned, unsigned> LiveAddressRegisterMap; - MachineBasicBlock &MBB = *BB; - - for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I); - I != MBB.end(); I = Next) { - Next = llvm::next(I); - MachineInstr &MI = *I; - - if (!TII->isRegisterStore(MI)) { - continue; - } - - // Lower RegisterStore - - unsigned RegIndex = MI.getOperand(2).getImm(); - unsigned Channel = MI.getOperand(3).getImm(); - unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel); - const TargetRegisterClass *IndirectStoreRegClass = - TII->getIndirectAddrStoreRegClass(MI.getOperand(0).getReg()); - - if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) { - // Direct register access. - unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass); - - BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), DstReg) - .addOperand(MI.getOperand(0)); - - RegisterAddressMap[DstReg] = Address; - LiveAddressRegisterMap[Address] = DstReg; - } else { - // Indirect register access. - MachineInstrBuilder MOV = TII->buildIndirectWrite(BB, I, - MI.getOperand(0).getReg(), // Value - Address, - MI.getOperand(1).getReg()); // Offset - for (int i = IndirectBegin; i <= IndirectEnd; ++i) { - unsigned Addr = TII->calculateIndirectAddress(i, Channel); - unsigned DstReg = MRI.createVirtualRegister(IndirectStoreRegClass); - MOV.addReg(DstReg, RegState::Define | RegState::Implicit); - RegisterAddressMap[DstReg] = Addr; - LiveAddressRegisterMap[Addr] = DstReg; - } - } - MI.eraseFromParent(); - } - - // Update the live-ins of the succesor blocks - for (MachineBasicBlock::succ_iterator Succ = MBB.succ_begin(), - SuccEnd = MBB.succ_end(); - SuccEnd != Succ; ++Succ) { - std::map<unsigned, unsigned>::const_iterator Key, KeyEnd; - for (Key = LiveAddressRegisterMap.begin(), - KeyEnd = LiveAddressRegisterMap.end(); KeyEnd != Key; ++Key) { - (*Succ)->addLiveIn(Key->second); - } - } - } - - // Second pass - Lower the RegisterLoad instructions - for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); - BB != BB_E; ++BB) { - // Key is the address and the value is the register - std::map<unsigned, unsigned> LiveAddressRegisterMap; - MachineBasicBlock &MBB = *BB; - - MachineBasicBlock::livein_iterator LI = MBB.livein_begin(); - while (LI != MBB.livein_end()) { - std::vector<unsigned> PhiRegisters; - - // Make sure this live in is used for indirect addressing - if (RegisterAddressMap.find(*LI) == RegisterAddressMap.end()) { - ++LI; - continue; - } - - unsigned Address = RegisterAddressMap[*LI]; - LiveAddressRegisterMap[Address] = *LI; - PhiRegisters.push_back(*LI); - - // Check if there are other live in registers which map to the same - // indirect address. - for (MachineBasicBlock::livein_iterator LJ = llvm::next(LI), - LE = MBB.livein_end(); - LJ != LE; ++LJ) { - unsigned Reg = *LJ; - if (RegisterAddressMap.find(Reg) == RegisterAddressMap.end()) { - continue; - } - - if (RegisterAddressMap[Reg] == Address) { - PhiRegisters.push_back(Reg); - } - } - - if (PhiRegisters.size() == 1) { - // We don't need to insert a Phi instruction, so we can just add the - // registers to the live list for the block. - LiveAddressRegisterMap[Address] = *LI; - MBB.removeLiveIn(*LI); - } else { - // We need to insert a PHI, because we have the same address being - // written in multiple predecessor blocks. - const TargetRegisterClass *PhiDstClass = - TII->getIndirectAddrStoreRegClass(*(PhiRegisters.begin())); - unsigned PhiDstReg = MRI.createVirtualRegister(PhiDstClass); - MachineInstrBuilder Phi = BuildMI(MBB, MBB.begin(), - MBB.findDebugLoc(MBB.begin()), - TII->get(AMDGPU::PHI), PhiDstReg); - - for (std::vector<unsigned>::const_iterator RI = PhiRegisters.begin(), - RE = PhiRegisters.end(); - RI != RE; ++RI) { - unsigned Reg = *RI; - MachineInstr *DefInst = MRI.getVRegDef(Reg); - assert(DefInst); - MachineBasicBlock *RegBlock = DefInst->getParent(); - Phi.addReg(Reg); - Phi.addMBB(RegBlock); - MBB.removeLiveIn(Reg); - } - RegisterAddressMap[PhiDstReg] = Address; - LiveAddressRegisterMap[Address] = PhiDstReg; - } - LI = MBB.livein_begin(); - } - - for (MachineBasicBlock::iterator I = MBB.begin(), Next = llvm::next(I); - I != MBB.end(); I = Next) { - Next = llvm::next(I); - MachineInstr &MI = *I; - - if (!TII->isRegisterLoad(MI)) { - if (MI.getOpcode() == AMDGPU::PHI) { - continue; - } - // Check for indirect register defs - for (unsigned OpIdx = 0, NumOperands = MI.getNumOperands(); - OpIdx < NumOperands; ++OpIdx) { - MachineOperand &MO = MI.getOperand(OpIdx); - if (MO.isReg() && MO.isDef() && - RegisterAddressMap.find(MO.getReg()) != RegisterAddressMap.end()) { - unsigned Reg = MO.getReg(); - unsigned LiveAddress = RegisterAddressMap[Reg]; - // Chain the live-ins - if (LiveAddressRegisterMap.find(LiveAddress) != - RegisterAddressMap.end()) { - MI.addOperand(MachineOperand::CreateReg( - LiveAddressRegisterMap[LiveAddress], - false, // isDef - true, // isImp - true)); // isKill - } - LiveAddressRegisterMap[LiveAddress] = Reg; - } - } - continue; - } - - const TargetRegisterClass *SuperIndirectRegClass = - TII->getSuperIndirectRegClass(); - const TargetRegisterClass *IndirectLoadRegClass = - TII->getIndirectAddrLoadRegClass(); - unsigned IndirectReg = MRI.createVirtualRegister(SuperIndirectRegClass); - - unsigned RegIndex = MI.getOperand(2).getImm(); - unsigned Channel = MI.getOperand(3).getImm(); - unsigned Address = TII->calculateIndirectAddress(RegIndex, Channel); - - if (MI.getOperand(1).getReg() == AMDGPU::INDIRECT_BASE_ADDR) { - // Direct register access - unsigned Reg = LiveAddressRegisterMap[Address]; - unsigned AddrReg = IndirectLoadRegClass->getRegister(Address); - - if (regHasExplicitDef(MRI, Reg)) { - // If the register we are reading from has an explicit def, then that - // means it was written via a direct register access (i.e. COPY - // or other instruction that doesn't use indirect addressing). In - // this case we know where the value has been stored, so we can just - // issue a copy. - BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), - MI.getOperand(0).getReg()) - .addReg(Reg); - } else { - // If the register we are reading has an implicit def, then that - // means it was written by an indirect register access (i.e. An - // instruction that uses indirect addressing. - BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDGPU::COPY), - MI.getOperand(0).getReg()) - .addReg(AddrReg) - .addReg(Reg, RegState::Implicit); - } - } else { - // Indirect register access - - // Note on REQ_SEQUENCE instructons: You can't actually use the register - // it defines unless you have an instruction that takes the defined - // register class as an operand. - - MachineInstrBuilder Sequence = BuildMI(MBB, I, MBB.findDebugLoc(I), - TII->get(AMDGPU::REG_SEQUENCE), - IndirectReg); - for (int i = IndirectBegin; i <= IndirectEnd; ++i) { - unsigned Addr = TII->calculateIndirectAddress(i, Channel); - if (LiveAddressRegisterMap.find(Addr) == LiveAddressRegisterMap.end()) { - continue; - } - unsigned Reg = LiveAddressRegisterMap[Addr]; - - // We only need to use REG_SEQUENCE for explicit defs, since the - // register coalescer won't do anything with the implicit defs. - if (!regHasExplicitDef(MRI, Reg)) { - continue; - } - - // Insert a REQ_SEQUENCE instruction to force the register allocator - // to allocate the virtual register to the correct physical register. - Sequence.addReg(LiveAddressRegisterMap[Addr]); - Sequence.addImm(TII->getRegisterInfo().getIndirectSubReg(Addr)); - } - MachineInstrBuilder Mov = TII->buildIndirectRead(BB, I, - MI.getOperand(0).getReg(), // Value - Address, - MI.getOperand(1).getReg()); // Offset - - - - Mov.addReg(IndirectReg, RegState::Implicit | RegState::Kill); - Mov.addReg(LiveAddressRegisterMap[Address], RegState::Implicit); - - } - MI.eraseFromParent(); - } - } - return false; -} - -bool AMDGPUIndirectAddressingPass::regHasExplicitDef(MachineRegisterInfo &MRI, - unsigned Reg) const { - MachineInstr *DefInstr = MRI.getVRegDef(Reg); - - if (!DefInstr) { - return false; - } - - if (DefInstr->getOpcode() == AMDGPU::PHI) { - bool Explicit = false; - for (MachineInstr::const_mop_iterator I = DefInstr->operands_begin(), - E = DefInstr->operands_end(); - I != E; ++I) { - const MachineOperand &MO = *I; - if (!MO.isReg() || MO.isDef()) { - continue; - } - - Explicit = Explicit || regHasExplicitDef(MRI, MO.getReg()); - } - return Explicit; - } - - return DefInstr->getOperand(0).isReg() && - DefInstr->getOperand(0).getReg() == Reg; -} |