AMDGPU: Refactor isVGPRToSGPRCopy

It should now correctly handle physical registers and make
it easier to identify the other direction.

llvm-svn: 250132
This commit is contained in:
Matt Arsenault 2015-10-13 00:07:54 +00:00
parent da38894497
commit f0d9e47da2
1 changed files with 48 additions and 19 deletions

View File

@ -85,8 +85,18 @@ class SIFixSGPRCopies : public MachineFunctionPass {
private:
static char ID;
bool isVGPRToSGPRCopy(const MachineInstr &Copy, const SIRegisterInfo *TRI,
const MachineRegisterInfo &MRI) const;
std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
getCopyRegClasses(const MachineInstr &Copy,
const SIRegisterInfo &TRI,
const MachineRegisterInfo &MRI) const;
bool isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
const TargetRegisterClass *DstRC,
const SIRegisterInfo &TRI) const;
bool isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
const TargetRegisterClass *DstRC,
const SIRegisterInfo &TRI) const;
public:
SIFixSGPRCopies(TargetMachine &tm) : MachineFunctionPass(ID) { }
@ -124,27 +134,39 @@ static bool hasVGPROperands(const MachineInstr &MI, const SIRegisterInfo *TRI) {
return false;
}
bool SIFixSGPRCopies::isVGPRToSGPRCopy(const MachineInstr &Copy,
const SIRegisterInfo *TRI,
const MachineRegisterInfo &MRI) const {
std::pair<const TargetRegisterClass *, const TargetRegisterClass *>
SIFixSGPRCopies::getCopyRegClasses(const MachineInstr &Copy,
const SIRegisterInfo &TRI,
const MachineRegisterInfo &MRI) const {
unsigned DstReg = Copy.getOperand(0).getReg();
unsigned SrcReg = Copy.getOperand(1).getReg();
unsigned SrcSubReg = Copy.getOperand(1).getSubReg();
if (!TargetRegisterInfo::isVirtualRegister(DstReg)) {
// If the destination register is a physical register there isn't really
// much we can do to fix this.
return false;
}
const TargetRegisterClass *SrcRC =
TargetRegisterInfo::isVirtualRegister(SrcReg) ?
MRI.getRegClass(SrcReg) :
TRI.getPhysRegClass(SrcReg);
if (!TargetRegisterInfo::isVirtualRegister(SrcReg))
return false;
// We don't really care about the subregister here.
// SrcRC = TRI.getSubRegClass(SrcRC, Copy.getOperand(1).getSubReg());
const TargetRegisterClass *DstRC = MRI.getRegClass(DstReg);
const TargetRegisterClass *SrcRC
= TRI->getSubRegClass(MRI.getRegClass(SrcReg), SrcSubReg);
return TRI->isSGPRClass(DstRC) && TRI->hasVGPRs(SrcRC);
const TargetRegisterClass *DstRC =
TargetRegisterInfo::isVirtualRegister(DstReg) ?
MRI.getRegClass(DstReg) :
TRI.getPhysRegClass(DstReg);
return std::make_pair(SrcRC, DstRC);
}
bool SIFixSGPRCopies::isVGPRToSGPRCopy(const TargetRegisterClass *SrcRC,
const TargetRegisterClass *DstRC,
const SIRegisterInfo &TRI) const {
return TRI.isSGPRClass(DstRC) && TRI.hasVGPRs(SrcRC);
}
bool SIFixSGPRCopies::isSGPRToVGPRCopy(const TargetRegisterClass *SrcRC,
const TargetRegisterClass *DstRC,
const SIRegisterInfo &TRI) const {
return TRI.isSGPRClass(SrcRC) && TRI.hasVGPRs(DstRC);
}
bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
@ -165,7 +187,14 @@ bool SIFixSGPRCopies::runOnMachineFunction(MachineFunction &MF) {
default:
continue;
case AMDGPU::COPY: {
if (isVGPRToSGPRCopy(MI, TRI, MRI)) {
// If the destination register is a physical register there isn't really
// much we can do to fix this.
if (!TargetRegisterInfo::isVirtualRegister(MI.getOperand(0).getReg()))
continue;
const TargetRegisterClass *SrcRC, *DstRC;
std::tie(SrcRC, DstRC) = getCopyRegClasses(MI, *TRI, MRI);
if (isVGPRToSGPRCopy(SrcRC, DstRC, *TRI)) {
DEBUG(dbgs() << "Fixing VGPR -> SGPR copy: " << MI);
TII->moveToVALU(MI);
}