mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
[RegisterCoalescer] Make sure each live-range has only one component, as
demanded by the machine verifier. After shrinking a live-range to its uses, it is possible to create several smaller live-ranges. When this happens, shrinkToUses returns true and we need to split the different components into their own live-ranges. The problem does not reproduce on any in-tree target but Jonas Paulsson <jonas.paulsson@ericsson.com>, who reported the problem, checked that this patch fixes the issue. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236658 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b350776f03
commit
d15319f75f
@ -224,6 +224,32 @@ namespace {
|
|||||||
/// Dst, we can drop \p Copy.
|
/// Dst, we can drop \p Copy.
|
||||||
bool applyTerminalRule(const MachineInstr &Copy) const;
|
bool applyTerminalRule(const MachineInstr &Copy) const;
|
||||||
|
|
||||||
|
/// Check whether or not \p LI is composed by multiple connected
|
||||||
|
/// components and if that is the case, fix that.
|
||||||
|
void splitNewRanges(LiveInterval *LI) {
|
||||||
|
ConnectedVNInfoEqClasses ConEQ(*LIS);
|
||||||
|
unsigned NumComps = ConEQ.Classify(LI);
|
||||||
|
if (NumComps <= 1)
|
||||||
|
return;
|
||||||
|
SmallVector<LiveInterval*, 8> NewComps(1, LI);
|
||||||
|
for (unsigned i = 1; i != NumComps; ++i) {
|
||||||
|
unsigned VReg = MRI->createVirtualRegister(MRI->getRegClass(LI->reg));
|
||||||
|
NewComps.push_back(&LIS->createEmptyInterval(VReg));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConEQ.Distribute(&NewComps[0], *MRI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Wrapper method for \see LiveIntervals::shrinkToUses.
|
||||||
|
/// This method does the proper fixing of the live-ranges when the afore
|
||||||
|
/// mentioned method returns true.
|
||||||
|
void shrinkToUses(LiveInterval *LI,
|
||||||
|
SmallVectorImpl<MachineInstr * > *Dead = nullptr) {
|
||||||
|
if (LIS->shrinkToUses(LI, Dead))
|
||||||
|
// We may have created multiple connected components, split them.
|
||||||
|
splitNewRanges(LI);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID; ///< Class identification, replacement for typeinfo
|
static char ID; ///< Class identification, replacement for typeinfo
|
||||||
RegisterCoalescer() : MachineFunctionPass(ID) {
|
RegisterCoalescer() : MachineFunctionPass(ID) {
|
||||||
@ -556,7 +582,7 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
|
|||||||
// will also add the isKill marker.
|
// will also add the isKill marker.
|
||||||
CopyMI->substituteRegister(IntA.reg, IntB.reg, 0, *TRI);
|
CopyMI->substituteRegister(IntA.reg, IntB.reg, 0, *TRI);
|
||||||
if (AS->end == CopyIdx)
|
if (AS->end == CopyIdx)
|
||||||
LIS->shrinkToUses(&IntA);
|
shrinkToUses(&IntA);
|
||||||
|
|
||||||
++numExtends;
|
++numExtends;
|
||||||
return true;
|
return true;
|
||||||
@ -1046,7 +1072,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
|
|||||||
++NumReMats;
|
++NumReMats;
|
||||||
|
|
||||||
// The source interval can become smaller because we removed a use.
|
// The source interval can become smaller because we removed a use.
|
||||||
LIS->shrinkToUses(&SrcInt, &DeadDefs);
|
shrinkToUses(&SrcInt, &DeadDefs);
|
||||||
if (!DeadDefs.empty()) {
|
if (!DeadDefs.empty()) {
|
||||||
// If the virtual SrcReg is completely eliminated, update all DBG_VALUEs
|
// If the virtual SrcReg is completely eliminated, update all DBG_VALUEs
|
||||||
// to describe DstReg instead.
|
// to describe DstReg instead.
|
||||||
@ -1427,7 +1453,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
|
|||||||
}
|
}
|
||||||
if (ShrinkMainRange) {
|
if (ShrinkMainRange) {
|
||||||
LiveInterval &LI = LIS->getInterval(CP.getDstReg());
|
LiveInterval &LI = LIS->getInterval(CP.getDstReg());
|
||||||
LIS->shrinkToUses(&LI);
|
shrinkToUses(&LI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SrcReg is guaranteed to be the register whose live interval that is
|
// SrcReg is guaranteed to be the register whose live interval that is
|
||||||
@ -2635,7 +2661,7 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
|
|||||||
LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
|
LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
|
||||||
RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
|
RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
|
||||||
while (!ShrinkRegs.empty())
|
while (!ShrinkRegs.empty())
|
||||||
LIS->shrinkToUses(&LIS->getInterval(ShrinkRegs.pop_back_val()));
|
shrinkToUses(&LIS->getInterval(ShrinkRegs.pop_back_val()));
|
||||||
|
|
||||||
// Join RHS into LHS.
|
// Join RHS into LHS.
|
||||||
LHS.join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
|
LHS.join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);
|
||||||
|
Loading…
Reference in New Issue
Block a user