/// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
/// instruction into MBB before MI. The new instruction is mapped, but
- /// liveness is not updated.
+ /// liveness is not updated. If ReplaceIndexMI is not null it will be replaced
+ /// by new MI in the index map.
/// Return the SlotIndex of the new instruction.
SlotIndex rematerializeAt(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, unsigned DestReg,
const Remat &RM, const TargetRegisterInfo &,
- bool Late = false);
+ bool Late = false, unsigned SubIdx = 0,
+ MachineInstr *ReplaceIndexMI = nullptr);
/// markRematerialized - explicitly mark a value as rematerialized after doing
/// it manually.
unsigned DestReg,
const Remat &RM,
const TargetRegisterInfo &tri,
- bool Late) {
+ bool Late,
+ unsigned SubIdx,
+ MachineInstr *ReplaceIndexMI) {
assert(RM.OrigMI && "Invalid remat");
- TII.reMaterialize(MBB, MI, DestReg, 0, *RM.OrigMI, tri);
+ TII.reMaterialize(MBB, MI, DestReg, SubIdx, *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);
+ if (ReplaceIndexMI)
+ return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI).getRegSlot();
return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot();
}
DenseMap<Register, unsigned long> LargeLIVisitCounter;
/// Recursively eliminate dead defs in DeadDefs.
- void eliminateDeadDefs();
-
- /// allUsesAvailableAt - Return true if all registers used by OrigMI at
- /// OrigIdx are also available with the same value at UseIdx.
- bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx,
- SlotIndex UseIdx);
+ void eliminateDeadDefs(LiveRangeEdit *Edit = nullptr);
/// LiveRangeEdit callback for eliminateDeadDefs().
void LRE_WillEraseInstruction(MachineInstr *MI) override;
MachineFunctionPass::getAnalysisUsage(AU);
}
-void RegisterCoalescer::eliminateDeadDefs() {
+void RegisterCoalescer::eliminateDeadDefs(LiveRangeEdit *Edit) {
+ if (Edit) {
+ Edit->eliminateDeadDefs(DeadDefs);
+ return;
+ }
SmallVector<Register, 8> NewRegs;
LiveRangeEdit(nullptr, NewRegs, *MF, *LIS,
nullptr, this).eliminateDeadDefs(DeadDefs);
}
-bool RegisterCoalescer::allUsesAvailableAt(const MachineInstr *OrigMI,
- SlotIndex OrigIdx,
- SlotIndex UseIdx) {
- SmallVector<Register, 8> NewRegs;
- return LiveRangeEdit(nullptr, NewRegs, *MF, *LIS, nullptr, this)
- .allUsesAvailableAt(OrigMI, OrigIdx, UseIdx);
-}
-
void RegisterCoalescer::LRE_WillEraseInstruction(MachineInstr *MI) {
// MI may be in WorkList. Make sure we don't visit it.
ErasedInstrs.insert(MI);
}
if (!TII->isAsCheapAsAMove(*DefMI))
return false;
- if (!TII->isTriviallyReMaterializable(*DefMI))
+
+ SmallVector<Register, 8> NewRegs;
+ LiveRangeEdit Edit(&SrcInt, NewRegs, *MF, *LIS, nullptr, this);
+ if (!Edit.checkRematerializable(ValNo, DefMI))
return false;
+
if (!definesFullReg(*DefMI, SrcReg))
return false;
bool SawStore = false;
}
}
- if (!allUsesAvailableAt(DefMI, ValNo->def, CopyIdx))
+ LiveRangeEdit::Remat RM(ValNo);
+ RM.OrigMI = DefMI;
+ if (!Edit.canRematerializeAt(RM, ValNo, CopyIdx, true))
return false;
DebugLoc DL = CopyMI->getDebugLoc();
MachineBasicBlock *MBB = CopyMI->getParent();
MachineBasicBlock::iterator MII =
std::next(MachineBasicBlock::iterator(CopyMI));
- TII->reMaterialize(*MBB, MII, DstReg, SrcIdx, *DefMI, *TRI);
+ Edit.rematerializeAt(*MBB, MII, DstReg, RM, *TRI, false, SrcIdx, CopyMI);
MachineInstr &NewMI = *std::prev(MII);
NewMI.setDebugLoc(DL);
}
}
- LIS->ReplaceMachineInstrInMaps(*CopyMI, NewMI);
CopyMI->eraseFromParent();
ErasedInstrs.insert(CopyMI);
// The source interval can become smaller because we removed a use.
shrinkToUses(&SrcInt, &DeadDefs);
if (!DeadDefs.empty())
- eliminateDeadDefs();
+ eliminateDeadDefs(&Edit);
} else {
ToBeUpdated.insert(SrcReg);
}