summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-04-16 02:13:37 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-04-16 02:13:37 +0000
commitc10783c42d0f86d46b56c70d0eb27b577051e117 (patch)
tree9a3ad2fdced0978037ded5e4e00e69da804e7274 /llvm/lib/Target
parent6fe1ff260b0461437523ac731008a24c9b63b1bc (diff)
downloadbcm5719-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.cpp138
-rw-r--r--llvm/lib/Target/AMDGPU/SIRegisterInfo.h21
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,
OpenPOWER on IntegriCloud