diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-04-16 02:13:37 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-04-16 02:13:37 +0000 |
commit | c10783c42d0f86d46b56c70d0eb27b577051e117 (patch) | |
tree | 9a3ad2fdced0978037ded5e4e00e69da804e7274 /llvm/lib/Target | |
parent | 6fe1ff260b0461437523ac731008a24c9b63b1bc (diff) | |
download | bcm5719-llvm-c10783c42d0f86d46b56c70d0eb27b577051e117.tar.gz bcm5719-llvm-c10783c42d0f86d46b56c70d0eb27b577051e117.zip |
AMDGPU: Enable LocalStackSlotAllocation pass
This resolves more frame indexes early and folds
the immediate offsets into the scratch mubuf instructions.
This cleans up a lot of the mess that's currently emitted,
such as emitting add 0s and repeatedly initializing the same
register to 0 when spilling.
llvm-svn: 266508
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp | 138 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIRegisterInfo.h | 21 |
2 files changed, 159 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp index 7edd41832ec..1bcb6202c5b 100644 --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp @@ -227,6 +227,144 @@ SIRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) const { return MF.getFrameInfo()->hasStackObjects(); } +bool SIRegisterInfo::requiresVirtualBaseRegisters( + const MachineFunction &) const { + // There are no special dedicated stack or frame pointers. + return true; +} + +int64_t SIRegisterInfo::getFrameIndexInstrOffset(const MachineInstr *MI, + int Idx) const { + + const MachineFunction *MF = MI->getParent()->getParent(); + const AMDGPUSubtarget &Subtarget = MF->getSubtarget<AMDGPUSubtarget>(); + const SIInstrInfo *TII + = static_cast<const SIInstrInfo *>(Subtarget.getInstrInfo()); + + if (!TII->isMUBUF(*MI)) + return 0; + + assert(Idx == AMDGPU::getNamedOperandIdx(MI->getOpcode(), + AMDGPU::OpName::vaddr) && + "Should never see frame index on non-address operand"); + + int OffIdx = AMDGPU::getNamedOperandIdx(MI->getOpcode(), + AMDGPU::OpName::offset); + return MI->getOperand(OffIdx).getImm(); +} + +bool SIRegisterInfo::needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { + return MI->mayLoadOrStore(); +} + +void SIRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB, + unsigned BaseReg, + int FrameIdx, + int64_t Offset) const { + MachineBasicBlock::iterator Ins = MBB->begin(); + DebugLoc DL; // Defaults to "unknown" + + if (Ins != MBB->end()) + DL = Ins->getDebugLoc(); + + MachineFunction *MF = MBB->getParent(); + const AMDGPUSubtarget &Subtarget = MF->getSubtarget<AMDGPUSubtarget>(); + const TargetInstrInfo *TII = Subtarget.getInstrInfo(); + + assert(isUInt<27>(Offset) && + "Private offset should never exceed maximum private size"); + + + if (Offset == 0) { + BuildMI(*MBB, Ins, DL, TII->get(AMDGPU::V_MOV_B32_e32), BaseReg) + .addFrameIndex(FrameIdx); + return; + } + + MachineRegisterInfo &MRI = MF->getRegInfo(); + unsigned UnusedCarry = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass); + + BuildMI(*MBB, Ins, DL, TII->get(AMDGPU::V_ADD_I32_e64), BaseReg) + .addReg(UnusedCarry, RegState::Define | RegState::Dead) + .addImm(Offset) + .addFrameIndex(FrameIdx); +} + +void SIRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, + int64_t Offset) const { + + MachineBasicBlock *MBB = MI.getParent(); + MachineFunction *MF = MBB->getParent(); + const AMDGPUSubtarget &Subtarget = MF->getSubtarget<AMDGPUSubtarget>(); + const SIInstrInfo *TII + = static_cast<const SIInstrInfo *>(Subtarget.getInstrInfo()); + +#ifndef NDEBUG + // FIXME: Is it possible to be storing a frame index to itself? + bool SeenFI = false; + for (const MachineOperand &MO: MI.operands()) { + if (MO.isFI()) { + if (SeenFI) + llvm_unreachable("should not see multiple frame indices"); + + SeenFI = true; + } + } +#endif + + MachineOperand *FIOp = TII->getNamedOperand(MI, AMDGPU::OpName::vaddr); + assert(FIOp && FIOp->isFI() && "frame index must be address operand"); + + assert(TII->isMUBUF(MI)); + + MachineOperand *OffsetOp = TII->getNamedOperand(MI, AMDGPU::OpName::offset); + int64_t NewOffset = OffsetOp->getImm() + Offset; + if (isUInt<12>(NewOffset)) { + // If we have a legal offset, fold it directly into the instruction. + FIOp->ChangeToRegister(BaseReg, false); + OffsetOp->setImm(NewOffset); + return; + } + + // The offset is not legal, so we must insert an add of the offset. + MachineRegisterInfo &MRI = MF->getRegInfo(); + unsigned NewReg = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); + DebugLoc DL = MI.getDebugLoc(); + + assert(Offset != 0 && "Non-zero offset expected"); + + unsigned UnusedCarry = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass); + + // In the case the instruction already had an immediate offset, here only + // the requested new offset is added because we are leaving the original + // immediate in place. + BuildMI(*MBB, MI, DL, TII->get(AMDGPU::V_ADD_I32_e64), NewReg) + .addReg(UnusedCarry, RegState::Define | RegState::Dead) + .addImm(Offset) + .addReg(BaseReg); + + FIOp->ChangeToRegister(NewReg, false); +} + +bool SIRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI, + unsigned BaseReg, + int64_t Offset) const { + const MachineFunction *MF = MI->getParent()->getParent(); + const AMDGPUSubtarget &Subtarget = MF->getSubtarget<AMDGPUSubtarget>(); + const SIInstrInfo *TII + = static_cast<const SIInstrInfo *>(Subtarget.getInstrInfo()); + + return TII->isMUBUF(*MI) && isUInt<12>(Offset); +} + +const TargetRegisterClass *SIRegisterInfo::getPointerRegClass( + const MachineFunction &MF, unsigned Kind) const { + // This is inaccurate. It depends on the instruction and address space. The + // only place where we should hit this is for dealing with frame indexes / + // private accesses, so this is correct in that case. + return &AMDGPU::VGPR_32RegClass; +} + static unsigned getNumSubRegsForSpillOp(unsigned Op) { switch (Op) { diff --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h index fa945f20b55..f64103115c3 100644 --- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.h +++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.h @@ -51,9 +51,30 @@ public: unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const override; + bool requiresRegisterScavenging(const MachineFunction &Fn) const override; + bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; + bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override; + + int64_t getFrameIndexInstrOffset(const MachineInstr *MI, + int Idx) const override; + + bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; + + void materializeFrameBaseRegister(MachineBasicBlock *MBB, + unsigned BaseReg, int FrameIdx, + int64_t Offset) const override; + + void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, + int64_t Offset) const override; + + bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, + int64_t Offset) const override; + + const TargetRegisterClass *getPointerRegClass( + const MachineFunction &MF, unsigned Kind = 0) const override; void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, |