mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-20 02:58:10 +00:00
Don't coalesce a physical register with an incompatible virtual register.
If the physical register does not belong to the virtual register's regclass, don't coalesce. The physical register could be an invalid operand for an instruction using the vreg. The regclass matching is done after determining the actual subregisters being copied. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70298 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d3d965714b
commit
08e791fdb3
@ -1160,22 +1160,25 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
|
||||
|
||||
DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI;
|
||||
|
||||
unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
|
||||
unsigned SrcReg, DstReg, SrcSubIdx = 0, DstSubIdx = 0;
|
||||
bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG;
|
||||
bool isInsSubReg = CopyMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG;
|
||||
bool isSubRegToReg = CopyMI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG;
|
||||
unsigned SubIdx = 0;
|
||||
if (isExtSubReg) {
|
||||
DstReg = CopyMI->getOperand(0).getReg();
|
||||
SrcReg = CopyMI->getOperand(1).getReg();
|
||||
DstReg = CopyMI->getOperand(0).getReg();
|
||||
DstSubIdx = CopyMI->getOperand(0).getSubReg();
|
||||
SrcReg = CopyMI->getOperand(1).getReg();
|
||||
SrcSubIdx = CopyMI->getOperand(2).getImm();
|
||||
} else if (isInsSubReg || isSubRegToReg) {
|
||||
if (CopyMI->getOperand(2).getSubReg()) {
|
||||
DOUT << "\tSource of insert_subreg is already coalesced "
|
||||
<< "to another register.\n";
|
||||
return false; // Not coalescable.
|
||||
}
|
||||
DstReg = CopyMI->getOperand(0).getReg();
|
||||
SrcReg = CopyMI->getOperand(2).getReg();
|
||||
DstReg = CopyMI->getOperand(0).getReg();
|
||||
DstSubIdx = CopyMI->getOperand(3).getImm();
|
||||
SrcReg = CopyMI->getOperand(2).getReg();
|
||||
} else if (!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)){
|
||||
assert(0 && "Unrecognized copy instruction!");
|
||||
return false;
|
||||
@ -1206,6 +1209,40 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
|
||||
return false; // Not coalescable.
|
||||
}
|
||||
|
||||
// Check that a physical source register is compatible with dst regclass
|
||||
if (SrcIsPhys) {
|
||||
unsigned SrcSubReg = SrcSubIdx ?
|
||||
tri_->getSubReg(SrcReg, SrcSubIdx) : SrcReg;
|
||||
const TargetRegisterClass *DstRC = mri_->getRegClass(DstReg);
|
||||
const TargetRegisterClass *DstSubRC = DstRC;
|
||||
if (DstSubIdx)
|
||||
DstSubRC = DstRC->getSubRegisterRegClass(DstSubIdx);
|
||||
assert(DstSubRC && "Illegal subregister index");
|
||||
if (!DstSubRC->contains(SrcSubReg)) {
|
||||
DOUT << "\tIncompatible destination regclass: "
|
||||
<< tri_->getName(SrcSubReg) << " not in " << DstSubRC->getName()
|
||||
<< ".\n";
|
||||
return false; // Not coalescable.
|
||||
}
|
||||
}
|
||||
|
||||
// Check that a physical dst register is compatible with source regclass
|
||||
if (DstIsPhys) {
|
||||
unsigned DstSubReg = DstSubIdx ?
|
||||
tri_->getSubReg(DstReg, DstSubIdx) : DstReg;
|
||||
const TargetRegisterClass *SrcRC = mri_->getRegClass(SrcReg);
|
||||
const TargetRegisterClass *SrcSubRC = SrcRC;
|
||||
if (SrcSubIdx)
|
||||
SrcSubRC = SrcRC->getSubRegisterRegClass(SrcSubIdx);
|
||||
assert(SrcSubRC && "Illegal subregister index");
|
||||
if (!SrcSubRC->contains(DstReg)) {
|
||||
DOUT << "\tIncompatible source regclass: "
|
||||
<< tri_->getName(DstSubReg) << " not in " << SrcSubRC->getName()
|
||||
<< ".\n";
|
||||
return false; // Not coalescable.
|
||||
}
|
||||
}
|
||||
|
||||
// Should be non-null only when coalescing to a sub-register class.
|
||||
bool CrossRC = false;
|
||||
const TargetRegisterClass *NewRC = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user