mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-07 12:18:32 +00:00
Handle implicit_defs in the register coalescer. I am still trying to produce
a reduced testcase, but this fixes pr13209. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159479 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1172,14 +1172,11 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li,
|
|||||||
|
|
||||||
MachineInstr *MI = li.getInstructionFromIndex(VNI->def);
|
MachineInstr *MI = li.getInstructionFromIndex(VNI->def);
|
||||||
|
|
||||||
if (!MI || !MI->isFullCopy() || CP.isPartial() || CP.isPhys())
|
if (!MI || CP.isPartial() || CP.isPhys())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned Dst = MI->getOperand(0).getReg();
|
unsigned Dst = MI->getOperand(0).getReg();
|
||||||
unsigned Src = MI->getOperand(1).getReg();
|
if (!TargetRegisterInfo::isVirtualRegister(Dst))
|
||||||
|
|
||||||
if (!TargetRegisterInfo::isVirtualRegister(Src) ||
|
|
||||||
!TargetRegisterInfo::isVirtualRegister(Dst))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned A = CP.getDstReg();
|
unsigned A = CP.getDstReg();
|
||||||
@@ -1189,34 +1186,47 @@ static bool RegistersDefinedFromSameValue(LiveIntervals &li,
|
|||||||
std::swap(A, B);
|
std::swap(A, B);
|
||||||
assert(Dst == A);
|
assert(Dst == A);
|
||||||
|
|
||||||
const MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def);
|
MachineInstr *OtherMI = li.getInstructionFromIndex(OtherVNI->def);
|
||||||
|
|
||||||
if (!OtherMI || !OtherMI->isFullCopy())
|
if (!OtherMI)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned OtherDst = OtherMI->getOperand(0).getReg();
|
unsigned OtherDst = OtherMI->getOperand(0).getReg();
|
||||||
unsigned OtherSrc = OtherMI->getOperand(1).getReg();
|
if (!TargetRegisterInfo::isVirtualRegister(OtherDst))
|
||||||
|
|
||||||
if (!TargetRegisterInfo::isVirtualRegister(OtherSrc) ||
|
|
||||||
!TargetRegisterInfo::isVirtualRegister(OtherDst))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(OtherDst == B);
|
assert(OtherDst == B);
|
||||||
|
|
||||||
if (Src != OtherSrc)
|
if (MI->isImplicitDef()) {
|
||||||
return false;
|
DupCopies.push_back(MI);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (!MI->isFullCopy())
|
||||||
|
return false;
|
||||||
|
unsigned Src = MI->getOperand(1).getReg();
|
||||||
|
if (!TargetRegisterInfo::isVirtualRegister(Src))
|
||||||
|
return false;
|
||||||
|
if (!OtherMI->isFullCopy())
|
||||||
|
return false;
|
||||||
|
unsigned OtherSrc = OtherMI->getOperand(1).getReg();
|
||||||
|
if (!TargetRegisterInfo::isVirtualRegister(OtherSrc))
|
||||||
|
return false;
|
||||||
|
|
||||||
// If the copies use two different value numbers of X, we cannot merge
|
if (Src != OtherSrc)
|
||||||
// A and B.
|
return false;
|
||||||
LiveInterval &SrcInt = li.getInterval(Src);
|
|
||||||
// getVNInfoBefore returns NULL for undef copies. In this case, the
|
|
||||||
// optimization is still safe.
|
|
||||||
if (SrcInt.getVNInfoBefore(OtherVNI->def) != SrcInt.getVNInfoBefore(VNI->def))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DupCopies.push_back(MI);
|
// If the copies use two different value numbers of X, we cannot merge
|
||||||
|
// A and B.
|
||||||
|
LiveInterval &SrcInt = li.getInterval(Src);
|
||||||
|
// getVNInfoBefore returns NULL for undef copies. In this case, the
|
||||||
|
// optimization is still safe.
|
||||||
|
if (SrcInt.getVNInfoBefore(OtherVNI->def) !=
|
||||||
|
SrcInt.getVNInfoBefore(VNI->def))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
DupCopies.push_back(MI);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// joinIntervals - Attempt to join these two intervals. On failure, this
|
/// joinIntervals - Attempt to join these two intervals. On failure, this
|
||||||
@@ -1254,7 +1264,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
|
|||||||
continue;
|
continue;
|
||||||
MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
|
MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
|
||||||
assert(MI && "Missing def");
|
assert(MI && "Missing def");
|
||||||
if (!MI->isCopyLike()) // Src not defined by a copy?
|
if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Figure out the value # from the RHS.
|
// Figure out the value # from the RHS.
|
||||||
@@ -1283,7 +1293,7 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
|
|||||||
continue;
|
continue;
|
||||||
MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
|
MachineInstr *MI = LIS->getInstructionFromIndex(VNI->def);
|
||||||
assert(MI && "Missing def");
|
assert(MI && "Missing def");
|
||||||
if (!MI->isCopyLike()) // Src not defined by a copy?
|
if (!MI->isCopyLike() && !MI->isImplicitDef()) // Src not defined by a copy?
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Figure out the value # from the LHS.
|
// Figure out the value # from the LHS.
|
||||||
@@ -1429,14 +1439,17 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
|
|||||||
if (!ErasedInstrs.insert(MI))
|
if (!ErasedInstrs.insert(MI))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// We have pretended that the assignment to B in
|
// If MI is a copy, then we have pretended that the assignment to B in
|
||||||
// A = X
|
// A = X
|
||||||
// B = X
|
// B = X
|
||||||
// was actually a copy from A. Now that we decided to coalesce A and B,
|
// was actually a copy from A. Now that we decided to coalesce A and B,
|
||||||
// transform the code into
|
// transform the code into
|
||||||
// A = X
|
// A = X
|
||||||
unsigned Src = MI->getOperand(1).getReg();
|
// In the case of the implicit_def, we just have to remove it.
|
||||||
SourceRegisters.push_back(Src);
|
if (!MI->isImplicitDef()) {
|
||||||
|
unsigned Src = MI->getOperand(1).getReg();
|
||||||
|
SourceRegisters.push_back(Src);
|
||||||
|
}
|
||||||
LIS->RemoveMachineInstrFromMaps(MI);
|
LIS->RemoveMachineInstrFromMaps(MI);
|
||||||
MI->eraseFromParent();
|
MI->eraseFromParent();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user