When converting a CopyFromReg to a copy instruction, use the register class of its uses to determine the right destination register class of the copy. This is important for targets where a physical register may belong to multiple register classes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56258 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2008-09-16 23:12:11 +00:00
parent f94474161f
commit 1cd332725f

View File

@ -65,6 +65,7 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
// If the node is only used by a CopyToReg and the dest reg is a vreg, use // If the node is only used by a CopyToReg and the dest reg is a vreg, use
// the CopyToReg'd destination register instead of creating a new vreg. // the CopyToReg'd destination register instead of creating a new vreg.
bool MatchReg = true; bool MatchReg = true;
const TargetRegisterClass *UseRC = NULL;
for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end(); for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
UI != E; ++UI) { UI != E; ++UI) {
SDNode *User = *UI; SDNode *User = *UI;
@ -84,8 +85,19 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
if (Op.getNode() != Node || Op.getResNo() != ResNo) if (Op.getNode() != Node || Op.getResNo() != ResNo)
continue; continue;
MVT VT = Node->getValueType(Op.getResNo()); MVT VT = Node->getValueType(Op.getResNo());
if (VT != MVT::Other && VT != MVT::Flag) if (VT == MVT::Other || VT == MVT::Flag)
Match = false; continue;
Match = false;
if (User->isMachineOpcode()) {
const TargetInstrDesc &II = TII->get(User->getMachineOpcode());
const TargetRegisterClass *RC =
getInstrOperandRegClass(TRI,TII,II,i+II.getNumDefs());
if (!UseRC)
UseRC = RC;
else if (RC)
assert(UseRC == RC &&
"Multiple uses expecting different register classes!");
}
} }
} }
MatchReg &= Match; MatchReg &= Match;
@ -93,14 +105,18 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
break; break;
} }
MVT VT = Node->getValueType(ResNo);
const TargetRegisterClass *SrcRC = 0, *DstRC = 0; const TargetRegisterClass *SrcRC = 0, *DstRC = 0;
SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, Node->getValueType(ResNo)); SrcRC = TRI->getPhysicalRegisterRegClass(SrcReg, VT);
// Figure out the register class to create for the destreg. // Figure out the register class to create for the destreg.
if (VRBase) { if (VRBase) {
DstRC = MRI.getRegClass(VRBase); DstRC = MRI.getRegClass(VRBase);
} else if (UseRC) {
assert(UseRC->hasType(VT) && "Incompatible phys register def and uses!");
DstRC = UseRC;
} else { } else {
DstRC = TLI->getRegClassFor(Node->getValueType(ResNo)); DstRC = TLI->getRegClassFor(VT);
} }
// If all uses are reading from the src physical register and copying the // If all uses are reading from the src physical register and copying the
@ -110,7 +126,10 @@ void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
} else { } else {
// Create the reg, emit the copy. // Create the reg, emit the copy.
VRBase = MRI.createVirtualRegister(DstRC); VRBase = MRI.createVirtualRegister(DstRC);
TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC); bool Emitted =
TII->copyRegToReg(*BB, BB->end(), VRBase, SrcReg, DstRC, SrcRC);
Emitted = Emitted; // Silence compiler warning.
assert(Emitted && "Unable to issue a copy instruction!");
} }
SDValue Op(Node, ResNo); SDValue Op(Node, ResNo);