summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/InlineSpiller.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-11-19 20:06:13 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-11-19 20:06:13 +0000
commitc0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch)
treef42add1021b9f2ac6a69ac7cf6c4499962739a45 /llvm/lib/CodeGen/InlineSpiller.cpp
parent344a3780b2e33f6ca763666c380202b18aab72a3 (diff)
Diffstat (limited to 'llvm/lib/CodeGen/InlineSpiller.cpp')
-rw-r--r--llvm/lib/CodeGen/InlineSpiller.cpp98
1 files changed, 59 insertions, 39 deletions
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index 71e91b445d9a..64e1f4351456 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -341,9 +341,8 @@ void InlineSpiller::collectRegsToSpill() {
if (Original == Reg)
return;
- for (MachineRegisterInfo::reg_instr_iterator
- RI = MRI.reg_instr_begin(Reg), E = MRI.reg_instr_end(); RI != E; ) {
- MachineInstr &MI = *RI++;
+ for (MachineInstr &MI :
+ llvm::make_early_inc_range(MRI.reg_instructions(Reg))) {
Register SnipReg = isFullCopyOf(MI, Reg);
if (!isSibling(SnipReg))
continue;
@@ -465,10 +464,8 @@ void InlineSpiller::eliminateRedundantSpills(LiveInterval &SLI, VNInfo *VNI) {
LLVM_DEBUG(dbgs() << "Merged to stack int: " << *StackInt << '\n');
// Find all spills and copies of VNI.
- for (MachineRegisterInfo::use_instr_nodbg_iterator
- UI = MRI.use_instr_nodbg_begin(Reg), E = MRI.use_instr_nodbg_end();
- UI != E; ) {
- MachineInstr &MI = *UI++;
+ for (MachineInstr &MI :
+ llvm::make_early_inc_range(MRI.use_nodbg_instructions(Reg))) {
if (!MI.isCopy() && !MI.mayStore())
continue;
SlotIndex Idx = LIS.getInstructionIndex(MI);
@@ -676,11 +673,7 @@ void InlineSpiller::reMaterializeAll() {
bool anyRemat = false;
for (Register Reg : RegsToSpill) {
LiveInterval &LI = LIS.getInterval(Reg);
- for (MachineRegisterInfo::reg_bundle_iterator
- RegI = MRI.reg_bundle_begin(Reg), E = MRI.reg_bundle_end();
- RegI != E; ) {
- MachineInstr &MI = *RegI++;
-
+ for (MachineInstr &MI : llvm::make_early_inc_range(MRI.reg_bundles(Reg))) {
// Debug values are not allowed to affect codegen.
if (MI.isDebugValue())
continue;
@@ -928,6 +921,39 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr *, unsigned>> Ops,
// Update the call site info.
if (MI->isCandidateForCallSiteEntry())
MI->getMF()->moveCallSiteInfo(MI, FoldMI);
+
+ // If we've folded a store into an instruction labelled with debug-info,
+ // record a substitution from the old operand to the memory operand. Handle
+ // the simple common case where operand 0 is the one being folded, plus when
+ // the destination operand is also a tied def. More values could be
+ // substituted / preserved with more analysis.
+ if (MI->peekDebugInstrNum() && Ops[0].second == 0) {
+ // Helper lambda.
+ auto MakeSubstitution = [this,FoldMI,MI,&Ops]() {
+ // Substitute old operand zero to the new instructions memory operand.
+ unsigned OldOperandNum = Ops[0].second;
+ unsigned NewNum = FoldMI->getDebugInstrNum();
+ unsigned OldNum = MI->getDebugInstrNum();
+ MF.makeDebugValueSubstitution({OldNum, OldOperandNum},
+ {NewNum, MachineFunction::DebugOperandMemNumber});
+ };
+
+ const MachineOperand &Op0 = MI->getOperand(Ops[0].second);
+ if (Ops.size() == 1 && Op0.isDef()) {
+ MakeSubstitution();
+ } else if (Ops.size() == 2 && Op0.isDef() && MI->getOperand(1).isTied() &&
+ Op0.getReg() == MI->getOperand(1).getReg()) {
+ MakeSubstitution();
+ }
+ } else if (MI->peekDebugInstrNum()) {
+ // This is a debug-labelled instruction, but the operand being folded isn't
+ // at operand zero. Most likely this means it's a load being folded in.
+ // Substitute any register defs from operand zero up to the one being
+ // folded -- past that point, we don't know what the new operand indexes
+ // will be.
+ MF.substituteDebugValuesForInst(*MI, *FoldMI, Ops[0].second);
+ }
+
MI->eraseFromParent();
// Insert any new instructions other than FoldMI into the LIS maps.
@@ -1038,57 +1064,53 @@ void InlineSpiller::spillAroundUses(Register Reg) {
LiveInterval &OldLI = LIS.getInterval(Reg);
// Iterate over instructions using Reg.
- for (MachineRegisterInfo::reg_bundle_iterator
- RegI = MRI.reg_bundle_begin(Reg), E = MRI.reg_bundle_end();
- RegI != E; ) {
- MachineInstr *MI = &*(RegI++);
-
+ for (MachineInstr &MI : llvm::make_early_inc_range(MRI.reg_bundles(Reg))) {
// Debug values are not allowed to affect codegen.
- if (MI->isDebugValue()) {
+ if (MI.isDebugValue()) {
// Modify DBG_VALUE now that the value is in a spill slot.
- MachineBasicBlock *MBB = MI->getParent();
- LLVM_DEBUG(dbgs() << "Modifying debug info due to spill:\t" << *MI);
- buildDbgValueForSpill(*MBB, MI, *MI, StackSlot, Reg);
+ MachineBasicBlock *MBB = MI.getParent();
+ LLVM_DEBUG(dbgs() << "Modifying debug info due to spill:\t" << MI);
+ buildDbgValueForSpill(*MBB, &MI, MI, StackSlot, Reg);
MBB->erase(MI);
continue;
}
- assert(!MI->isDebugInstr() && "Did not expect to find a use in debug "
+ assert(!MI.isDebugInstr() && "Did not expect to find a use in debug "
"instruction that isn't a DBG_VALUE");
// Ignore copies to/from snippets. We'll delete them.
- if (SnippetCopies.count(MI))
+ if (SnippetCopies.count(&MI))
continue;
// Stack slot accesses may coalesce away.
- if (coalesceStackAccess(MI, Reg))
+ if (coalesceStackAccess(&MI, Reg))
continue;
// Analyze instruction.
SmallVector<std::pair<MachineInstr*, unsigned>, 8> Ops;
- VirtRegInfo RI = AnalyzeVirtRegInBundle(*MI, Reg, &Ops);
+ VirtRegInfo RI = AnalyzeVirtRegInBundle(MI, Reg, &Ops);
// Find the slot index where this instruction reads and writes OldLI.
// This is usually the def slot, except for tied early clobbers.
- SlotIndex Idx = LIS.getInstructionIndex(*MI).getRegSlot();
+ SlotIndex Idx = LIS.getInstructionIndex(MI).getRegSlot();
if (VNInfo *VNI = OldLI.getVNInfoAt(Idx.getRegSlot(true)))
if (SlotIndex::isSameInstr(Idx, VNI->def))
Idx = VNI->def;
// Check for a sibling copy.
- Register SibReg = isFullCopyOf(*MI, Reg);
+ Register SibReg = isFullCopyOf(MI, Reg);
if (SibReg && isSibling(SibReg)) {
// This may actually be a copy between snippets.
if (isRegToSpill(SibReg)) {
- LLVM_DEBUG(dbgs() << "Found new snippet copy: " << *MI);
- SnippetCopies.insert(MI);
+ LLVM_DEBUG(dbgs() << "Found new snippet copy: " << MI);
+ SnippetCopies.insert(&MI);
continue;
}
if (RI.Writes) {
- if (hoistSpillInsideBB(OldLI, *MI)) {
+ if (hoistSpillInsideBB(OldLI, MI)) {
// This COPY is now dead, the value is already in the stack slot.
- MI->getOperand(0).setIsDead();
- DeadDefs.push_back(MI);
+ MI.getOperand(0).setIsDead();
+ DeadDefs.push_back(&MI);
continue;
}
} else {
@@ -1108,7 +1130,7 @@ void InlineSpiller::spillAroundUses(Register Reg) {
Register NewVReg = Edit->createFrom(Reg);
if (RI.Reads)
- insertReload(NewVReg, Idx, MI);
+ insertReload(NewVReg, Idx, &MI);
// Rewrite instruction operands.
bool hasLiveDef = false;
@@ -1123,12 +1145,12 @@ void InlineSpiller::spillAroundUses(Register Reg) {
hasLiveDef = true;
}
}
- LLVM_DEBUG(dbgs() << "\trewrite: " << Idx << '\t' << *MI << '\n');
+ LLVM_DEBUG(dbgs() << "\trewrite: " << Idx << '\t' << MI << '\n');
// FIXME: Use a second vreg if instruction has no tied ops.
if (RI.Writes)
if (hasLiveDef)
- insertSpill(NewVReg, true, MI);
+ insertSpill(NewVReg, true, &MI);
}
}
@@ -1163,10 +1185,8 @@ void InlineSpiller::spillAll() {
// Finally delete the SnippetCopies.
for (Register Reg : RegsToSpill) {
- for (MachineRegisterInfo::reg_instr_iterator
- RI = MRI.reg_instr_begin(Reg), E = MRI.reg_instr_end();
- RI != E; ) {
- MachineInstr &MI = *(RI++);
+ for (MachineInstr &MI :
+ llvm::make_early_inc_range(MRI.reg_instructions(Reg))) {
assert(SnippetCopies.count(&MI) && "Remaining use wasn't a snippet copy");
// FIXME: Do this with a LiveRangeEdit callback.
LIS.RemoveMachineInstrFromMaps(MI);