aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveRangeEdit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/LiveRangeEdit.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveRangeEdit.cpp108
1 files changed, 40 insertions, 68 deletions
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp
index 59bc82d..5b0365d 100644
--- a/llvm/lib/CodeGen/LiveRangeEdit.cpp
+++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp
@@ -68,41 +68,12 @@ Register LiveRangeEdit::createFrom(Register OldReg) {
return VReg;
}
-void LiveRangeEdit::scanRemattable() {
- for (VNInfo *VNI : getParent().valnos) {
- if (VNI->isUnused())
- continue;
- Register Original = VRM->getOriginal(getReg());
- LiveInterval &OrigLI = LIS.getInterval(Original);
- VNInfo *OrigVNI = OrigLI.getVNInfoAt(VNI->def);
- if (!OrigVNI)
- continue;
- MachineInstr *DefMI = LIS.getInstructionFromIndex(OrigVNI->def);
- if (!DefMI)
- continue;
- if (TII.isReMaterializable(*DefMI))
- Remattable.insert(OrigVNI);
- }
- ScannedRemattable = true;
-}
-
-bool LiveRangeEdit::anyRematerializable() {
- if (!ScannedRemattable)
- scanRemattable();
- return !Remattable.empty();
-}
-
-bool LiveRangeEdit::canRematerializeAt(Remat &RM, VNInfo *OrigVNI,
- SlotIndex UseIdx) {
- assert(ScannedRemattable && "Call anyRematerializable first");
+bool LiveRangeEdit::canRematerializeAt(Remat &RM, SlotIndex UseIdx) {
+ assert(RM.OrigMI && "No defining instruction for remattable value");
- // Use scanRemattable info.
- if (!Remattable.count(OrigVNI))
+ if (!TII.isReMaterializable(*RM.OrigMI))
return false;
- // No defining instruction provided.
- assert(RM.OrigMI && "No defining instruction for remattable value");
-
// Verify that all used registers are available with the same values.
if (!VirtRegAuxInfo::allUsesAvailableAt(RM.OrigMI, UseIdx, LIS, MRI, TII))
return false;
@@ -303,6 +274,37 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
}
}
+ // 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. Note that if we keep the
+ // instruction with the original operands, that handles the physreg
+ // operand case (described just below) as well.
+ // 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.isReMaterializable(*MI)) {
+ LiveInterval &NewLI = createEmptyIntervalFrom(Dest, false);
+ VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator();
+ VNInfo *VNI = NewLI.getNextValue(Idx, Alloc);
+ NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI));
+
+ if (DestSubReg) {
+ const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
+ auto *SR =
+ NewLI.createSubRange(Alloc, TRI->getSubRegIndexLaneMask(DestSubReg));
+ SR->addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(),
+ SR->getNextValue(Idx, Alloc)));
+ }
+
+ pop_back();
+ DeadRemats->insert(MI);
+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+ MI->substituteRegister(Dest, NewLI.reg(), 0, TRI);
+ assert(MI->registerDefIsDead(NewLI.reg(), &TRI));
+ }
// Currently, we don't support DCE of physreg live ranges. If MI reads
// any unreserved physregs, don't erase the instruction, but turn it into
// a KILL instead. This way, the physreg live ranges don't end up
@@ -310,7 +312,7 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
// FIXME: It would be better to have something like shrinkToUses() for
// physregs. That could potentially enable more DCE and it would free up
// the physreg. It would not happen often, though.
- if (ReadsPhysRegs) {
+ else if (ReadsPhysRegs) {
MI->setDesc(TII.get(TargetOpcode::KILL));
// Remove all operands that aren't physregs.
for (unsigned i = MI->getNumOperands(); i; --i) {
@@ -322,41 +324,11 @@ void LiveRangeEdit::eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink) {
MI->dropMemRefs(*MI->getMF());
LLVM_DEBUG(dbgs() << "Converted physregs to:\t" << *MI);
} else {
- // 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.
- // 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.isReMaterializable(*MI)) {
- LiveInterval &NewLI = createEmptyIntervalFrom(Dest, false);
- VNInfo::Allocator &Alloc = LIS.getVNInfoAllocator();
- VNInfo *VNI = NewLI.getNextValue(Idx, Alloc);
- NewLI.addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(), VNI));
-
- if (DestSubReg) {
- const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
- auto *SR = NewLI.createSubRange(
- Alloc, TRI->getSubRegIndexLaneMask(DestSubReg));
- SR->addSegment(LiveInterval::Segment(Idx, Idx.getDeadSlot(),
- SR->getNextValue(Idx, Alloc)));
- }
-
- pop_back();
- DeadRemats->insert(MI);
- const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
- MI->substituteRegister(Dest, NewLI.reg(), 0, TRI);
- assert(MI->registerDefIsDead(NewLI.reg(), &TRI));
- } else {
- if (TheDelegate)
- TheDelegate->LRE_WillEraseInstruction(MI);
- LIS.RemoveMachineInstrFromMaps(*MI);
- MI->eraseFromParent();
- ++NumDCEDeleted;
- }
+ 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>