diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
| commit | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch) | |
| tree | f42add1021b9f2ac6a69ac7cf6c4499962739a45 /llvm/lib/CodeGen/LiveRangeEdit.cpp | |
| parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
Diffstat (limited to 'llvm/lib/CodeGen/LiveRangeEdit.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/LiveRangeEdit.cpp | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp index 64a2dd275643..d91ff734ad8f 100644 --- a/llvm/lib/CodeGen/LiveRangeEdit.cpp +++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -107,7 +107,7 @@ bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, SlotIndex UseIdx) const { OrigIdx = OrigIdx.getRegSlot(true); - UseIdx = UseIdx.getRegSlot(true); + UseIdx = std::max(UseIdx, UseIdx.getRegSlot(true)); for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = OrigMI->getOperand(i); if (!MO.isReg() || !MO.getReg() || !MO.readsReg()) @@ -305,17 +305,18 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink, isOrigDef = SlotIndex::isSameInstr(OrigVNI->def, Idx); } + bool HasLiveVRegUses = false; + // Check for live intervals that may shrink - for (MachineInstr::mop_iterator MOI = MI->operands_begin(), - MOE = MI->operands_end(); MOI != MOE; ++MOI) { - if (!MOI->isReg()) + for (const MachineOperand &MO : MI->operands()) { + if (!MO.isReg()) continue; - Register Reg = MOI->getReg(); + Register Reg = MO.getReg(); if (!Register::isVirtualRegister(Reg)) { // Check if MI reads any unreserved physregs. - if (Reg && MOI->readsReg() && !MRI.isReserved(Reg)) + if (Reg && MO.readsReg() && !MRI.isReserved(Reg)) ReadsPhysRegs = true; - else if (MOI->isDef()) + else if (MO.isDef()) LIS.removePhysRegDefAt(Reg.asMCReg(), Idx); continue; } @@ -325,12 +326,14 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink, // unlikely to change anything. We typically don't want to shrink the // PIC base register that has lots of uses everywhere. // Always shrink COPY uses that probably come from live range splitting. - if ((MI->readsVirtualRegister(Reg) && (MI->isCopy() || MOI->isDef())) || - (MOI->readsReg() && (MRI.hasOneNonDBGUse(Reg) || useIsKill(LI, *MOI)))) + if ((MI->readsVirtualRegister(Reg) && (MI->isCopy() || MO.isDef())) || + (MO.readsReg() && (MRI.hasOneNonDBGUse(Reg) || useIsKill(LI, MO)))) ToShrink.insert(&LI); + else if (MO.readsReg()) + HasLiveVRegUses = true; // Remove defined value. - if (MOI->isDef()) { + if (MO.isDef()) { if (TheDelegate && LI.getVNInfoAt(Idx) != nullptr) TheDelegate->LRE_WillShrinkVirtReg(LI.reg()); LIS.removeVRegDefAt(LI, Idx); @@ -362,7 +365,11 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink, // the inst for remat of other siblings. The inst is saved in // LiveRangeEdit::DeadRemats and will be deleted after all the // allocations of the func are done. - if (isOrigDef && DeadRemats && TII.isTriviallyReMaterializable(*MI, AA)) { + // However, immediately delete instructions which have unshrunk virtual + // register uses. That may provoke RA to split an interval at the KILL + // and later result in an invalid live segment end. + if (isOrigDef && DeadRemats && !HasLiveVRegUses && + TII.isTriviallyReMaterializable(*MI, AA)) { LiveInterval &NewLI = createEmptyIntervalFrom(Dest, false); VNInfo *VNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator()); NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI)); @@ -405,8 +412,7 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead, break; // Shrink just one live interval. Then delete new dead defs. - LiveInterval *LI = ToShrink.back(); - ToShrink.pop_back(); + LiveInterval *LI = ToShrink.pop_back_val(); if (foldAsLoad(LI, Dead)) continue; unsigned VReg = LI->reg(); |
