diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-11-19 20:06:13 +0000 |
| commit | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch) | |
| tree | f42add1021b9f2ac6a69ac7cf6c4499962739a45 /llvm/lib/CodeGen/InlineSpiller.cpp | |
| parent | 344a3780b2e33f6ca763666c380202b18aab72a3 (diff) | |
Diffstat (limited to 'llvm/lib/CodeGen/InlineSpiller.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/InlineSpiller.cpp | 98 |
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); |
