summaryrefslogtreecommitdiffstats
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.cpp63
1 files changed, 43 insertions, 20 deletions
diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp
index 72eafcd0792..5610c5afa0d 100644
--- a/llvm/lib/CodeGen/LiveRangeEdit.cpp
+++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp
@@ -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,24 +116,18 @@ 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))
@@ -261,6 +258,15 @@ 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);
+ isOrigDef = SlotIndex::isSameInstr(OrigVNI->def, Idx);
+ }
// Check for live intervals that may shrink
for (MachineInstr::mop_iterator MOI = MI->operands_begin(),
@@ -314,11 +320,24 @@ 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, don't delete the inst. Replace
+ // the dest with a new reg, 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) {
+ unsigned NewDest = createFrom(Dest);
+ pop_back();
+ markDeadRemat(MI);
+ const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
+ MI->substituteRegister(Dest, NewDest, 0, TRI);
+ MI->getOperand(0).setIsDead(false);
+ } 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,8 +351,9 @@ 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,
+ bool NoSplit) {
ToShrinkSet ToShrink;
for (;;) {
@@ -355,6 +375,9 @@ void LiveRangeEdit::eliminateDeadDefs(SmallVectorImpl<MachineInstr*> &Dead,
if (!LIS.shrinkToUses(LI, &Dead))
continue;
+ if (NoSplit)
+ continue;
+
// Don't create new intervals for a register being spilled.
// The new intervals would have to be spilled anyway so its not worth it.
// Also they currently aren't spilled so creating them and not spilling
OpenPOWER on IntegriCloud