Make X86's copyRegToReg able to handle copies to and from subclasses.

This makes the extra copyRegToReg calls in ScheduleDAGSDNodesEmit.cpp
unnecessary. Derived from a patch by Jakob Stoklund Olesen.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@69635 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2009-04-20 22:54:34 +00:00
parent bd209ab9bc
commit 70bc17dbf5
2 changed files with 29 additions and 45 deletions

View File

@ -131,12 +131,6 @@ void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
VRBase = MRI.createVirtualRegister(DstRC);
bool Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
DstRC, SrcRC);
// If the target didn't handle the copy with different register
// classes and the destination is a subset of the source,
// try a normal same-RC copy.
if (!Emitted && DstRC->hasSuperClass(SrcRC))
Emitted = TII->copyRegToReg(*BB, InsertPos, VRBase, SrcReg,
SrcRC, SrcRC);
assert(Emitted && "Unable to issue a copy instruction!\n");
}
@ -273,12 +267,6 @@ ScheduleDAGSDNodes::AddRegisterOperand(MachineInstr *MI, SDValue Op,
unsigned NewVReg = MRI.createVirtualRegister(DstRC);
bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
DstRC, SrcRC);
// If the target didn't handle the copy with different register
// classes and the destination is a subset of the source,
// try a normal same-RC copy.
if (!Emitted && DstRC->hasSuperClass(SrcRC))
Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
SrcRC, SrcRC);
assert(Emitted && "Unable to issue a copy instruction!\n");
VReg = NewVReg;
}
@ -480,12 +468,6 @@ ScheduleDAGSDNodes::EmitCopyToRegClassNode(SDNode *Node,
unsigned NewVReg = MRI.createVirtualRegister(DstRC);
bool Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
DstRC, SrcRC);
// If the target didn't handle the copy with different register
// classes and the destination is a subset of the source,
// try a normal same-RC copy.
if (!Emitted && SrcRC->hasSubClass(DstRC))
Emitted = TII->copyRegToReg(*BB, InsertPos, NewVReg, VReg,
SrcRC, SrcRC);
assert(Emitted &&
"Unable to issue a copy instruction for a COPY_TO_REGCLASS node!\n");
@ -610,13 +592,6 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
bool Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg,
DstTRC, SrcTRC);
// If the target didn't handle the copy with different register
// classes and the destination is a subset of the source,
// try a normal same-RC copy.
if (!Emitted && DstTRC->hasSubClass(SrcTRC))
Emitted = TII->copyRegToReg(*BB, InsertPos, DestReg, SrcReg,
DstTRC, DstTRC);
assert(Emitted && "Unable to issue a copy instruction!\n");
break;
}

View File

@ -1656,15 +1656,24 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MI != MBB.end()) DL = MI->getDebugLoc();
if (DestRC == SrcRC) {
// Determine if DstRC and SrcRC have a common superclass in common.
const TargetRegisterClass *CommonRC = DestRC;
if (DestRC == SrcRC)
/* Source and destination have the same register class. */;
else if (CommonRC->hasSuperClass(SrcRC))
CommonRC = SrcRC;
else if (!DestRC->hasSubClass(SrcRC))
CommonRC = 0;
if (CommonRC) {
unsigned Opc;
if (DestRC == &X86::GR64RegClass) {
if (CommonRC == &X86::GR64RegClass) {
Opc = X86::MOV64rr;
} else if (DestRC == &X86::GR32RegClass) {
} else if (CommonRC == &X86::GR32RegClass) {
Opc = X86::MOV32rr;
} else if (DestRC == &X86::GR16RegClass) {
} else if (CommonRC == &X86::GR16RegClass) {
Opc = X86::MOV16rr;
} else if (DestRC == &X86::GR8RegClass) {
} else if (CommonRC == &X86::GR8RegClass) {
// Copying two or from a physical H register on x86-64 requires a NOREX
// move. Otherwise use a normal move.
if ((isHReg(DestReg) || isHReg(SrcReg)) &&
@ -1672,35 +1681,35 @@ bool X86InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
Opc = X86::MOV8rr_NOREX;
else
Opc = X86::MOV8rr;
} else if (DestRC == &X86::GR64_RegClass) {
} else if (CommonRC == &X86::GR64_RegClass) {
Opc = X86::MOV64rr;
} else if (DestRC == &X86::GR32_RegClass) {
} else if (CommonRC == &X86::GR32_RegClass) {
Opc = X86::MOV32rr;
} else if (DestRC == &X86::GR16_RegClass) {
} else if (CommonRC == &X86::GR16_RegClass) {
Opc = X86::MOV16rr;
} else if (DestRC == &X86::GR8_RegClass) {
} else if (CommonRC == &X86::GR8_RegClass) {
Opc = X86::MOV8rr;
} else if (DestRC == &X86::GR64_NOREXRegClass) {
} else if (CommonRC == &X86::GR64_NOREXRegClass) {
Opc = X86::MOV64rr;
} else if (DestRC == &X86::GR32_NOREXRegClass) {
} else if (CommonRC == &X86::GR32_NOREXRegClass) {
Opc = X86::MOV32rr;
} else if (DestRC == &X86::GR16_NOREXRegClass) {
} else if (CommonRC == &X86::GR16_NOREXRegClass) {
Opc = X86::MOV16rr;
} else if (DestRC == &X86::GR8_NOREXRegClass) {
} else if (CommonRC == &X86::GR8_NOREXRegClass) {
Opc = X86::MOV8rr;
} else if (DestRC == &X86::RFP32RegClass) {
} else if (CommonRC == &X86::RFP32RegClass) {
Opc = X86::MOV_Fp3232;
} else if (DestRC == &X86::RFP64RegClass || DestRC == &X86::RSTRegClass) {
} else if (CommonRC == &X86::RFP64RegClass || CommonRC == &X86::RSTRegClass) {
Opc = X86::MOV_Fp6464;
} else if (DestRC == &X86::RFP80RegClass) {
} else if (CommonRC == &X86::RFP80RegClass) {
Opc = X86::MOV_Fp8080;
} else if (DestRC == &X86::FR32RegClass) {
} else if (CommonRC == &X86::FR32RegClass) {
Opc = X86::FsMOVAPSrr;
} else if (DestRC == &X86::FR64RegClass) {
} else if (CommonRC == &X86::FR64RegClass) {
Opc = X86::FsMOVAPDrr;
} else if (DestRC == &X86::VR128RegClass) {
} else if (CommonRC == &X86::VR128RegClass) {
Opc = X86::MOVAPSrr;
} else if (DestRC == &X86::VR64RegClass) {
} else if (CommonRC == &X86::VR64RegClass) {
Opc = X86::MMX_MOVQ64rr;
} else {
return false;