diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/LiveRangeEdit.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/LiveRangeEdit.cpp | 99 |
1 files changed, 65 insertions, 34 deletions
diff --git a/contrib/llvm/lib/CodeGen/LiveRangeEdit.cpp b/contrib/llvm/lib/CodeGen/LiveRangeEdit.cpp index 5ce364a..b35c0ad 100644 --- a/contrib/llvm/lib/CodeGen/LiveRangeEdit.cpp +++ b/contrib/llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -53,7 +53,7 @@ bool LiveRangeEdit::checkRematerializable(VNInfo *VNI, AliasAnalysis *aa) { assert(DefMI && "Missing instruction"); ScannedRemattable = true; - if (!TII.isTriviallyReMaterializable(DefMI, aa)) + if (!TII.isTriviallyReMaterializable(*DefMI, aa)) return false; Remattable.insert(VNI); return true; @@ -63,10 +63,13 @@ void LiveRangeEdit::scanRemattable(AliasAnalysis *aa) { for (VNInfo *VNI : getParent().valnos) { if (VNI->isUnused()) continue; - MachineInstr *DefMI = LIS.getInstructionFromIndex(VNI->def); + unsigned Original = VRM->getOriginal(getReg()); + LiveInterval &OrigLI = LIS.getInterval(Original); + VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def); + MachineInstr *DefMI = LIS.getInstructionFromIndex(OrigVNI->def); if (!DefMI) continue; - checkRematerializable(VNI, DefMI, aa); + checkRematerializable(OrigVNI, DefMI, aa); } ScannedRemattable = true; } @@ -113,27 +116,21 @@ bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI, return true; } -bool LiveRangeEdit::canRematerializeAt(Remat &RM, - SlotIndex UseIdx, - bool cheapAsAMove) { +bool LiveRangeEdit::canRematerializeAt(Remat &RM, VNInfo *OrigVNI, + SlotIndex UseIdx, bool cheapAsAMove) { assert(ScannedRemattable && "Call anyRematerializable first"); // Use scanRemattable info. - if (!Remattable.count(RM.ParentVNI)) + if (!Remattable.count(OrigVNI)) return false; // No defining instruction provided. SlotIndex DefIdx; - if (RM.OrigMI) - DefIdx = LIS.getInstructionIndex(RM.OrigMI); - else { - DefIdx = RM.ParentVNI->def; - RM.OrigMI = LIS.getInstructionFromIndex(DefIdx); - assert(RM.OrigMI && "No defining instruction for remattable value"); - } + assert(RM.OrigMI && "No defining instruction for remattable value"); + DefIdx = LIS.getInstructionIndex(*RM.OrigMI); // If only cheap remats were requested, bail out early. - if (cheapAsAMove && !TII.isAsCheapAsAMove(RM.OrigMI)) + if (cheapAsAMove && !TII.isAsCheapAsAMove(*RM.OrigMI)) return false; // Verify that all used registers are available with the same values. @@ -150,10 +147,13 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB, const TargetRegisterInfo &tri, bool Late) { assert(RM.OrigMI && "Invalid remat"); - TII.reMaterialize(MBB, MI, DestReg, 0, RM.OrigMI, tri); + TII.reMaterialize(MBB, MI, DestReg, 0, *RM.OrigMI, tri); + // DestReg of the cloned instruction cannot be Dead. Set isDead of DestReg + // to false anyway in case the isDead flag of RM.OrigMI's dest register + // is true. + (*--MI).getOperand(0).setIsDead(false); Rematted.insert(RM.ParentVNI); - return LIS.getSlotIndexes()->insertMachineInstrInMaps(--MI, Late) - .getRegSlot(); + return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot(); } void LiveRangeEdit::eraseVirtReg(unsigned Reg) { @@ -188,9 +188,8 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, // Since we're moving the DefMI load, make sure we're not extending any live // ranges. - if (!allUsesAvailableAt(DefMI, - LIS.getInstructionIndex(DefMI), - LIS.getInstructionIndex(UseMI))) + if (!allUsesAvailableAt(DefMI, LIS.getInstructionIndex(*DefMI), + LIS.getInstructionIndex(*UseMI))) return false; // We also need to make sure it is safe to move the load. @@ -206,11 +205,11 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, if (UseMI->readsWritesVirtualRegister(LI->reg, &Ops).second) return false; - MachineInstr *FoldMI = TII.foldMemoryOperand(UseMI, Ops, DefMI); + MachineInstr *FoldMI = TII.foldMemoryOperand(*UseMI, Ops, *DefMI, &LIS); if (!FoldMI) return false; DEBUG(dbgs() << " folded: " << *FoldMI); - LIS.ReplaceMachineInstrInMaps(UseMI, FoldMI); + LIS.ReplaceMachineInstrInMaps(*UseMI, *FoldMI); UseMI->eraseFromParent(); DefMI->addRegisterDead(LI->reg, nullptr); Dead.push_back(DefMI); @@ -220,7 +219,7 @@ bool LiveRangeEdit::foldAsLoad(LiveInterval *LI, bool LiveRangeEdit::useIsKill(const LiveInterval &LI, const MachineOperand &MO) const { - const MachineInstr *MI = MO.getParent(); + const MachineInstr &MI = *MO.getParent(); SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot(); if (LI.Query(Idx).isKill()) return true; @@ -235,9 +234,10 @@ bool LiveRangeEdit::useIsKill(const LiveInterval &LI, } /// Find all live intervals that need to shrink, then remove the instruction. -void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { +void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink, + AliasAnalysis *AA) { assert(MI->allDefsAreDead() && "Def isn't really dead"); - SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot(); + SlotIndex Idx = LIS.getInstructionIndex(*MI).getRegSlot(); // Never delete a bundled instruction. if (MI->isBundled()) { @@ -261,6 +261,20 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { // Collect virtual registers to be erased after MI is gone. SmallVector<unsigned, 8> RegsToErase; bool ReadsPhysRegs = false; + bool isOrigDef = false; + unsigned Dest; + if (VRM && MI->getOperand(0).isReg()) { + Dest = MI->getOperand(0).getReg(); + unsigned Original = VRM->getOriginal(Dest); + LiveInterval &OrigLI = LIS.getInterval(Original); + VNInfo *OrigVNI = OrigLI.getVNInfoAt(Idx); + // The original live-range may have been shrunk to + // an empty live-range. It happens when it is dead, but + // we still keep it around to be able to rematerialize + // other values that depend on it. + if (OrigVNI) + isOrigDef = SlotIndex::isSameInstr(OrigVNI->def, Idx); + } // Check for live intervals that may shrink for (MachineInstr::mop_iterator MOI = MI->operands_begin(), @@ -314,11 +328,27 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { } DEBUG(dbgs() << "Converted physregs to:\t" << *MI); } else { - if (TheDelegate) - TheDelegate->LRE_WillEraseInstruction(MI); - LIS.RemoveMachineInstrFromMaps(MI); - MI->eraseFromParent(); - ++NumDCEDeleted; + // If the dest of MI is an original reg and MI is reMaterializable, + // don't delete the inst. Replace the dest with a new reg, and keep + // 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)) { + LiveInterval &NewLI = createEmptyIntervalFrom(Dest); + VNInfo *VNI = NewLI.getNextValue(Idx, LIS.getVNInfoAllocator()); + NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI)); + pop_back(); + markDeadRemat(MI); + const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo(); + MI->substituteRegister(Dest, NewLI.reg, 0, TRI); + MI->getOperand(0).setIsDead(true); + } else { + if (TheDelegate) + TheDelegate->LRE_WillEraseInstruction(MI); + LIS.RemoveMachineInstrFromMaps(*MI); + MI->eraseFromParent(); + ++NumDCEDeleted; + } } // Erase any virtregs that are now empty and unused. There may be <undef> @@ -332,14 +362,15 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) { } } -void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead, - ArrayRef<unsigned> RegsBeingSpilled) { +void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead, + ArrayRef<unsigned> RegsBeingSpilled, + AliasAnalysis *AA) { ToShrinkSet ToShrink; for (;;) { // Erase all dead defs. while (!Dead.empty()) - eliminateDeadDef(Dead.pop_back_val(), ToShrink); + eliminateDeadDef(Dead.pop_back_val(), ToShrink, AA); if (ToShrink.empty()) break; |