mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-20 09:24:58 +00:00
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:
parent
f94474161f
commit
1cd332725f
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user