Skip to content

Commit 0ddd315

Browse files
author
Quentin Colombet
committed
[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. llvm-svn: 236658
1 parent a86398e commit 0ddd315

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

llvm/lib/CodeGen/RegisterCoalescer.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,32 @@ namespace {
224224
/// Dst, we can drop \p Copy.
225225
bool applyTerminalRule(const MachineInstr &Copy) const;
226226

227+
/// Check whether or not \p LI is composed by multiple connected
228+
/// components and if that is the case, fix that.
229+
void splitNewRanges(LiveInterval *LI) {
230+
ConnectedVNInfoEqClasses ConEQ(*LIS);
231+
unsigned NumComps = ConEQ.Classify(LI);
232+
if (NumComps <= 1)
233+
return;
234+
SmallVector<LiveInterval*, 8> NewComps(1, LI);
235+
for (unsigned i = 1; i != NumComps; ++i) {
236+
unsigned VReg = MRI->createVirtualRegister(MRI->getRegClass(LI->reg));
237+
NewComps.push_back(&LIS->createEmptyInterval(VReg));
238+
}
239+
240+
ConEQ.Distribute(&NewComps[0], *MRI);
241+
}
242+
243+
/// Wrapper method for \see LiveIntervals::shrinkToUses.
244+
/// This method does the proper fixing of the live-ranges when the afore
245+
/// mentioned method returns true.
246+
void shrinkToUses(LiveInterval *LI,
247+
SmallVectorImpl<MachineInstr * > *Dead = nullptr) {
248+
if (LIS->shrinkToUses(LI, Dead))
249+
// We may have created multiple connected components, split them.
250+
splitNewRanges(LI);
251+
}
252+
227253
public:
228254
static char ID; ///< Class identification, replacement for typeinfo
229255
RegisterCoalescer() : MachineFunctionPass(ID) {
@@ -556,7 +582,7 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP,
556582
// will also add the isKill marker.
557583
CopyMI->substituteRegister(IntA.reg, IntB.reg, 0, *TRI);
558584
if (AS->end == CopyIdx)
559-
LIS->shrinkToUses(&IntA);
585+
shrinkToUses(&IntA);
560586

561587
++numExtends;
562588
return true;
@@ -1046,7 +1072,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
10461072
++NumReMats;
10471073

10481074
// The source interval can become smaller because we removed a use.
1049-
LIS->shrinkToUses(&SrcInt, &DeadDefs);
1075+
shrinkToUses(&SrcInt, &DeadDefs);
10501076
if (!DeadDefs.empty()) {
10511077
// If the virtual SrcReg is completely eliminated, update all DBG_VALUEs
10521078
// to describe DstReg instead.
@@ -1427,7 +1453,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
14271453
}
14281454
if (ShrinkMainRange) {
14291455
LiveInterval &LI = LIS->getInterval(CP.getDstReg());
1430-
LIS->shrinkToUses(&LI);
1456+
shrinkToUses(&LI);
14311457
}
14321458

14331459
// SrcReg is guaranteed to be the register whose live interval that is
@@ -2635,7 +2661,7 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
26352661
LHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
26362662
RHSVals.eraseInstrs(ErasedInstrs, ShrinkRegs);
26372663
while (!ShrinkRegs.empty())
2638-
LIS->shrinkToUses(&LIS->getInterval(ShrinkRegs.pop_back_val()));
2664+
shrinkToUses(&LIS->getInterval(ShrinkRegs.pop_back_val()));
26392665

26402666
// Join RHS into LHS.
26412667
LHS.join(RHS, LHSVals.getAssignments(), RHSVals.getAssignments(), NewVNInfo);

0 commit comments

Comments
 (0)