diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp | 85 |
1 files changed, 71 insertions, 14 deletions
diff --git a/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp b/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp index a6112b39325e..4deb2a9485e4 100644 --- a/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp +++ b/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp @@ -22,11 +22,19 @@ /// although the same shall be possible with other register classes and /// instructions if necessary. /// +/// This pass also adds register allocation hints to COPY. +/// The hints will be post-processed by SIRegisterInfo::getRegAllocationHints. +/// When using True16, we often see COPY moving a 16-bit value between a VGPR_32 +/// and a VGPR_16. If we use the VGPR_16 that corresponds to the lo16 bits of +/// the VGPR_32, the COPY can be completely eliminated. +/// //===----------------------------------------------------------------------===// +#include "GCNPreRAOptimizations.h" #include "AMDGPU.h" #include "GCNSubtarget.h" #include "MCTargetDesc/AMDGPUMCTargetDesc.h" +#include "SIRegisterInfo.h" #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/InitializePasses.h" @@ -37,7 +45,7 @@ using namespace llvm; namespace { -class GCNPreRAOptimizations : public MachineFunctionPass { +class GCNPreRAOptimizationsImpl { private: const SIInstrInfo *TII; const SIRegisterInfo *TRI; @@ -47,10 +55,16 @@ private: bool processReg(Register Reg); public: + GCNPreRAOptimizationsImpl(LiveIntervals *LS) : LIS(LS) {} + bool run(MachineFunction &MF); +}; + +class GCNPreRAOptimizationsLegacy : public MachineFunctionPass { +public: static char ID; - GCNPreRAOptimizations() : MachineFunctionPass(ID) { - initializeGCNPreRAOptimizationsPass(*PassRegistry::getPassRegistry()); + GCNPreRAOptimizationsLegacy() : MachineFunctionPass(ID) { + initializeGCNPreRAOptimizationsLegacyPass(*PassRegistry::getPassRegistry()); } bool runOnMachineFunction(MachineFunction &MF) override; @@ -65,24 +79,23 @@ public: MachineFunctionPass::getAnalysisUsage(AU); } }; - } // End anonymous namespace. -INITIALIZE_PASS_BEGIN(GCNPreRAOptimizations, DEBUG_TYPE, +INITIALIZE_PASS_BEGIN(GCNPreRAOptimizationsLegacy, DEBUG_TYPE, "AMDGPU Pre-RA optimizations", false, false) INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) -INITIALIZE_PASS_END(GCNPreRAOptimizations, DEBUG_TYPE, "Pre-RA optimizations", - false, false) +INITIALIZE_PASS_END(GCNPreRAOptimizationsLegacy, DEBUG_TYPE, + "Pre-RA optimizations", false, false) -char GCNPreRAOptimizations::ID = 0; +char GCNPreRAOptimizationsLegacy::ID = 0; -char &llvm::GCNPreRAOptimizationsID = GCNPreRAOptimizations::ID; +char &llvm::GCNPreRAOptimizationsID = GCNPreRAOptimizationsLegacy::ID; -FunctionPass *llvm::createGCNPreRAOptimizationsPass() { - return new GCNPreRAOptimizations(); +FunctionPass *llvm::createGCNPreRAOptimizationsLegacyPass() { + return new GCNPreRAOptimizationsLegacy(); } -bool GCNPreRAOptimizations::processReg(Register Reg) { +bool GCNPreRAOptimizationsImpl::processReg(Register Reg) { MachineInstr *Def0 = nullptr; MachineInstr *Def1 = nullptr; uint64_t Init = 0; @@ -212,14 +225,25 @@ bool GCNPreRAOptimizations::processReg(Register Reg) { return true; } -bool GCNPreRAOptimizations::runOnMachineFunction(MachineFunction &MF) { +bool GCNPreRAOptimizationsLegacy::runOnMachineFunction(MachineFunction &MF) { if (skipFunction(MF.getFunction())) return false; + LiveIntervals *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS(); + return GCNPreRAOptimizationsImpl(LIS).run(MF); +} + +PreservedAnalyses +GCNPreRAOptimizationsPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + LiveIntervals *LIS = &MFAM.getResult<LiveIntervalsAnalysis>(MF); + GCNPreRAOptimizationsImpl(LIS).run(MF); + return PreservedAnalyses::all(); +} +bool GCNPreRAOptimizationsImpl::run(MachineFunction &MF) { const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); TII = ST.getInstrInfo(); MRI = &MF.getRegInfo(); - LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS(); TRI = ST.getRegisterInfo(); bool Changed = false; @@ -236,5 +260,38 @@ bool GCNPreRAOptimizations::runOnMachineFunction(MachineFunction &MF) { Changed |= processReg(Reg); } + if (!ST.useRealTrue16Insts()) + return Changed; + + // Add RA hints to improve True16 COPY elimination. + for (const MachineBasicBlock &MBB : MF) { + for (const MachineInstr &MI : MBB) { + if (MI.getOpcode() != AMDGPU::COPY) + continue; + Register Dst = MI.getOperand(0).getReg(); + Register Src = MI.getOperand(1).getReg(); + if (Dst.isVirtual() && + MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass && + Src.isPhysical() && + TRI->getRegClassForReg(*MRI, Src) == &AMDGPU::VGPR_32RegClass) + MRI->setRegAllocationHint(Dst, 0, TRI->getSubReg(Src, AMDGPU::lo16)); + if (Src.isVirtual() && + MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass && + Dst.isPhysical() && + TRI->getRegClassForReg(*MRI, Dst) == &AMDGPU::VGPR_32RegClass) + MRI->setRegAllocationHint(Src, 0, TRI->getSubReg(Dst, AMDGPU::lo16)); + if (!Dst.isVirtual() || !Src.isVirtual()) + continue; + if (MRI->getRegClass(Dst) == &AMDGPU::VGPR_32RegClass && + MRI->getRegClass(Src) == &AMDGPU::VGPR_16RegClass) { + MRI->setRegAllocationHint(Dst, AMDGPURI::Size32, Src); + MRI->setRegAllocationHint(Src, AMDGPURI::Size16, Dst); + } + if (MRI->getRegClass(Dst) == &AMDGPU::VGPR_16RegClass && + MRI->getRegClass(Src) == &AMDGPU::VGPR_32RegClass) + MRI->setRegAllocationHint(Dst, AMDGPURI::Size16, Src); + } + } + return Changed; } |
