aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorMomchil Velikov <momchil.velikov@arm.com>2023-11-11 19:43:14 +0000
committerGitHub <noreply@github.com>2023-11-11 19:43:14 +0000
commite8209b2486d8fa1a5314af0fe896b9628effa471 (patch)
treee27e516fd92a50619ed3ff1fd15db9a42bacaeeb /llvm/lib/CodeGen/MachineSink.cpp
parent215bacb5dc6e7027402434a14e1153e687a4a1cf (diff)
downloadllvm-e8209b2486d8fa1a5314af0fe896b9628effa471.zip
llvm-e8209b2486d8fa1a5314af0fe896b9628effa471.tar.gz
llvm-e8209b2486d8fa1a5314af0fe896b9628effa471.tar.bz2
[MachineSink] Drop debug info for instructions deleted by sink-and-fold (#71443)
After performing sink-and-fold over a COPY, the original instruction is replaced with one that produces its output in the destination of the copy. Its value is still available (in a hard register), so if there are debug instructions which refer to the (now deleted) virtual register they could be updated to refer to the hard register, in principle. However, it's not clear how to do that, moreover in some cases the debug instructions may need to be replicated proportionally to the number of the COPY instructions replaced and in some extreme cases we can end up with quadratic increase in the number of debug instructions, e.g: int f(int); void g(int x) { int y = x + 1; int t0 = y; f(t0); int t1 = y; f(t1); }
Diffstat (limited to 'llvm/lib/CodeGen/MachineSink.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineSink.cpp31
1 files changed, 12 insertions, 19 deletions
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index d0e119c..9ed6b22 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -510,30 +510,23 @@ bool MachineSinking::PerformSinkAndFold(MachineInstr &MI,
LLVM_DEBUG(dbgs() << "Sinking copy of"; MI.dump(); dbgs() << "into";
SinkDst->dump());
if (SinkDst->isCopy()) {
+ // TODO: After performing the sink-and-fold, the original instruction is
+ // deleted. Its value is still available (in a hard register), so if there
+ // are debug instructions which refer to the (now deleted) virtual
+ // register they could be updated to refer to the hard register, in
+ // principle. However, it's not clear how to do that, moreover in some
+ // cases the debug instructions may need to be replicated proportionally
+ // to the number of the COPY instructions replaced and in some extreme
+ // cases we can end up with quadratic increase in the number of debug
+ // instructions.
+
// Sink a copy of the instruction, replacing a COPY instruction.
MachineBasicBlock::iterator InsertPt = SinkDst->getIterator();
Register DstReg = SinkDst->getOperand(0).getReg();
TII->reMaterialize(*SinkDst->getParent(), InsertPt, DstReg, 0, MI, *TRI);
- // If the original instruction did not have source location, reuse a one
- // from the COPY.
+ // Reuse the source location from the COPY.
New = &*std::prev(InsertPt);
- if (const DebugLoc &NewLoc = New->getDebugLoc(); !NewLoc)
- New->setDebugLoc(SinkDst->getDebugLoc());
- // Sink DBG_VALUEs, which refer to the original instruction's destination
- // (DefReg).
- MachineBasicBlock &SinkMBB = *SinkDst->getParent();
- auto &DbgUsers = SeenDbgUsers[DefReg];
- for (auto &U : DbgUsers) {
- MachineInstr *DbgMI = U.getPointer();
- if (U.getInt())
- continue;
- MachineInstr *NewDbgMI = SinkDst->getMF()->CloneMachineInstr(DbgMI);
- SinkMBB.insertAfter(InsertPt, NewDbgMI);
- for (auto &SrcMO : DbgMI->getDebugOperandsForReg(DefReg)) {
- auto &DstMO = NewDbgMI->getOperand(SrcMO.getOperandNo());
- DstMO.setReg(DstReg);
- }
- }
+ New->setDebugLoc(SinkDst->getDebugLoc());
} else {
// Fold instruction into the addressing mode of a memory instruction.
New = TII->emitLdStWithAddr(*SinkDst, MaybeAM);