[RegisterCoalescer] Use LiveRangeEdit to handle rematerialization
This patch uses the API provided by LiveRangeEdit to handle rematerialization. It will make future maintenance and improvement more easier. No functional change. Differential Revision: https://reviews.llvm.org/D133610
This commit is contained in:
parent
0f19c60342
commit
c39311eb40
|
@ -210,12 +210,14 @@ public:
|
||||||
|
|
||||||
/// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
|
/// rematerializeAt - Rematerialize RM.ParentVNI into DestReg by inserting an
|
||||||
/// instruction into MBB before MI. The new instruction is mapped, but
|
/// 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.
|
/// Return the SlotIndex of the new instruction.
|
||||||
SlotIndex rematerializeAt(MachineBasicBlock &MBB,
|
SlotIndex rematerializeAt(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI, unsigned DestReg,
|
MachineBasicBlock::iterator MI, unsigned DestReg,
|
||||||
const Remat &RM, const TargetRegisterInfo &,
|
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
|
/// markRematerialized - explicitly mark a value as rematerialized after doing
|
||||||
/// it manually.
|
/// it manually.
|
||||||
|
|
|
@ -183,14 +183,18 @@ SlotIndex LiveRangeEdit::rematerializeAt(MachineBasicBlock &MBB,
|
||||||
unsigned DestReg,
|
unsigned DestReg,
|
||||||
const Remat &RM,
|
const Remat &RM,
|
||||||
const TargetRegisterInfo &tri,
|
const TargetRegisterInfo &tri,
|
||||||
bool Late) {
|
bool Late,
|
||||||
|
unsigned SubIdx,
|
||||||
|
MachineInstr *ReplaceIndexMI) {
|
||||||
assert(RM.OrigMI && "Invalid remat");
|
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
|
// 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
|
// to false anyway in case the isDead flag of RM.OrigMI's dest register
|
||||||
// is true.
|
// is true.
|
||||||
(*--MI).getOperand(0).setIsDead(false);
|
(*--MI).getOperand(0).setIsDead(false);
|
||||||
Rematted.insert(RM.ParentVNI);
|
Rematted.insert(RM.ParentVNI);
|
||||||
|
if (ReplaceIndexMI)
|
||||||
|
return LIS.ReplaceMachineInstrInMaps(*ReplaceIndexMI, *MI).getRegSlot();
|
||||||
return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot();
|
return LIS.getSlotIndexes()->insertMachineInstrInMaps(*MI, Late).getRegSlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,12 +199,7 @@ namespace {
|
||||||
DenseMap<Register, unsigned long> LargeLIVisitCounter;
|
DenseMap<Register, unsigned long> LargeLIVisitCounter;
|
||||||
|
|
||||||
/// Recursively eliminate dead defs in DeadDefs.
|
/// Recursively eliminate dead defs in DeadDefs.
|
||||||
void eliminateDeadDefs();
|
void eliminateDeadDefs(LiveRangeEdit *Edit = nullptr);
|
||||||
|
|
||||||
/// 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);
|
|
||||||
|
|
||||||
/// LiveRangeEdit callback for eliminateDeadDefs().
|
/// LiveRangeEdit callback for eliminateDeadDefs().
|
||||||
void LRE_WillEraseInstruction(MachineInstr *MI) override;
|
void LRE_WillEraseInstruction(MachineInstr *MI) override;
|
||||||
|
@ -603,20 +598,16 @@ void RegisterCoalescer::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
MachineFunctionPass::getAnalysisUsage(AU);
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterCoalescer::eliminateDeadDefs() {
|
void RegisterCoalescer::eliminateDeadDefs(LiveRangeEdit *Edit) {
|
||||||
|
if (Edit) {
|
||||||
|
Edit->eliminateDeadDefs(DeadDefs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
SmallVector<Register, 8> NewRegs;
|
SmallVector<Register, 8> NewRegs;
|
||||||
LiveRangeEdit(nullptr, NewRegs, *MF, *LIS,
|
LiveRangeEdit(nullptr, NewRegs, *MF, *LIS,
|
||||||
nullptr, this).eliminateDeadDefs(DeadDefs);
|
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) {
|
void RegisterCoalescer::LRE_WillEraseInstruction(MachineInstr *MI) {
|
||||||
// MI may be in WorkList. Make sure we don't visit it.
|
// MI may be in WorkList. Make sure we don't visit it.
|
||||||
ErasedInstrs.insert(MI);
|
ErasedInstrs.insert(MI);
|
||||||
|
@ -1306,8 +1297,12 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
|
||||||
}
|
}
|
||||||
if (!TII->isAsCheapAsAMove(*DefMI))
|
if (!TII->isAsCheapAsAMove(*DefMI))
|
||||||
return false;
|
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;
|
return false;
|
||||||
|
|
||||||
if (!definesFullReg(*DefMI, SrcReg))
|
if (!definesFullReg(*DefMI, SrcReg))
|
||||||
return false;
|
return false;
|
||||||
bool SawStore = false;
|
bool SawStore = false;
|
||||||
|
@ -1352,14 +1347,16 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allUsesAvailableAt(DefMI, ValNo->def, CopyIdx))
|
LiveRangeEdit::Remat RM(ValNo);
|
||||||
|
RM.OrigMI = DefMI;
|
||||||
|
if (!Edit.canRematerializeAt(RM, ValNo, CopyIdx, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DebugLoc DL = CopyMI->getDebugLoc();
|
DebugLoc DL = CopyMI->getDebugLoc();
|
||||||
MachineBasicBlock *MBB = CopyMI->getParent();
|
MachineBasicBlock *MBB = CopyMI->getParent();
|
||||||
MachineBasicBlock::iterator MII =
|
MachineBasicBlock::iterator MII =
|
||||||
std::next(MachineBasicBlock::iterator(CopyMI));
|
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);
|
MachineInstr &NewMI = *std::prev(MII);
|
||||||
NewMI.setDebugLoc(DL);
|
NewMI.setDebugLoc(DL);
|
||||||
|
|
||||||
|
@ -1403,7 +1400,6 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LIS->ReplaceMachineInstrInMaps(*CopyMI, NewMI);
|
|
||||||
CopyMI->eraseFromParent();
|
CopyMI->eraseFromParent();
|
||||||
ErasedInstrs.insert(CopyMI);
|
ErasedInstrs.insert(CopyMI);
|
||||||
|
|
||||||
|
@ -1597,7 +1593,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
|
||||||
// The source interval can become smaller because we removed a use.
|
// The source interval can become smaller because we removed a use.
|
||||||
shrinkToUses(&SrcInt, &DeadDefs);
|
shrinkToUses(&SrcInt, &DeadDefs);
|
||||||
if (!DeadDefs.empty())
|
if (!DeadDefs.empty())
|
||||||
eliminateDeadDefs();
|
eliminateDeadDefs(&Edit);
|
||||||
} else {
|
} else {
|
||||||
ToBeUpdated.insert(SrcReg);
|
ToBeUpdated.insert(SrcReg);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue