diff options
author | Momchil Velikov <momchil.velikov@arm.com> | 2023-11-11 19:43:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-11 19:43:14 +0000 |
commit | e8209b2486d8fa1a5314af0fe896b9628effa471 (patch) | |
tree | e27e516fd92a50619ed3ff1fd15db9a42bacaeeb /llvm/lib/CodeGen/MachineSink.cpp | |
parent | 215bacb5dc6e7027402434a14e1153e687a4a1cf (diff) | |
download | llvm-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.cpp | 31 |
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); |