aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/GCNPreRAOptimizations.cpp85
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;
}