diff options
author | Jeremy Morse <jeremy.morse.llvm@gmail.com> | 2018-11-02 16:52:48 +0000 |
---|---|---|
committer | Jeremy Morse <jeremy.morse.llvm@gmail.com> | 2018-11-02 16:52:48 +0000 |
commit | d538352b3e4b1eabee02fc7ce491728678cc4716 (patch) | |
tree | 8e610ac20334332a92701d38b3e09c6708d6a0dd /llvm/lib/CodeGen/MachineSink.cpp | |
parent | 82536501c75c60c5a2a0bda9e255a51ce7741018 (diff) | |
download | bcm5719-llvm-d538352b3e4b1eabee02fc7ce491728678cc4716.tar.gz bcm5719-llvm-d538352b3e4b1eabee02fc7ce491728678cc4716.zip |
[MachineSink][DebugInfo] Correctly sink DBG_VALUEs
As reported in PR38952, postra-machine-sink relies on DBG_VALUE insns being
adjacent to the def of the register that they reference. This is not always
true, leading to register copies being sunk but not the associated DBG_VALUEs,
which gives the debugger a bad variable location.
This patch collects DBG_VALUEs as we walk through a BB looking for copies to
sink, then passes them down to performSink. Compile-time impact should be
negligable.
Differential Revision: https://reviews.llvm.org/D53992
llvm-svn: 345996
Diffstat (limited to 'llvm/lib/CodeGen/MachineSink.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineSink.cpp | 57 |
1 files changed, 47 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp index 1d2e85accbc..d45855407f2 100644 --- a/llvm/lib/CodeGen/MachineSink.cpp +++ b/llvm/lib/CodeGen/MachineSink.cpp @@ -734,12 +734,18 @@ static bool SinkingPreventsImplicitNullCheck(MachineInstr &MI, MBP.LHS.getReg() == BaseReg; } -/// Sink an instruction and its associated debug instructions. +/// Sink an instruction and its associated debug instructions. If the debug +/// instructions to be sunk are already known, they can be provided in DbgVals. static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo, - MachineBasicBlock::iterator InsertPos) { - // Collect matching debug values. + MachineBasicBlock::iterator InsertPos, + SmallVectorImpl<MachineInstr *> *DbgVals = nullptr) { + // If debug values are provided use those, otherwise call collectDebugValues. SmallVector<MachineInstr *, 2> DbgValuesToSink; - MI.collectDebugValues(DbgValuesToSink); + if (DbgVals) + DbgValuesToSink.insert(DbgValuesToSink.begin(), + DbgVals->begin(), DbgVals->end()); + else + MI.collectDebugValues(DbgValuesToSink); // If we cannot find a location to use (merge with), then we erase the debug // location to prevent debug-info driven tools from potentially reporting @@ -951,6 +957,9 @@ private: /// Track which register units have been modified and used. LiveRegUnits ModifiedRegUnits, UsedRegUnits; + /// Track DBG_VALUEs of (unmodified) register units. + DenseMap<unsigned, TinyPtrVector<MachineInstr*>> SeenDbgInstrs; + /// Sink Copy instructions unused in the same block close to their uses in /// successors. bool tryToSinkCopy(MachineBasicBlock &BB, MachineFunction &MF, @@ -1105,11 +1114,34 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, // block and the current instruction. ModifiedRegUnits.clear(); UsedRegUnits.clear(); + SeenDbgInstrs.clear(); for (auto I = CurBB.rbegin(), E = CurBB.rend(); I != E;) { MachineInstr *MI = &*I; ++I; + // Track the operand index for use in Copy. + SmallVector<unsigned, 2> UsedOpsInCopy; + // Track the register number defed in Copy. + SmallVector<unsigned, 2> DefedRegsInCopy; + + // We must sink this DBG_VALUE if its operand is sunk. To avoid searching + // for DBG_VALUEs later, record them when they're encountered. + if (MI->isDebugValue()) { + auto &MO = MI->getOperand(0); + if (MO.isReg() && TRI->isPhysicalRegister(MO.getReg())) { + // Bail if we can already tell the sink would be rejected, rather + // than needlessly accumulating lots of DBG_VALUEs. + if (hasRegisterDependency(MI, UsedOpsInCopy, DefedRegsInCopy, + ModifiedRegUnits, UsedRegUnits)) + continue; + + // Record debug use of this register. + SeenDbgInstrs[MO.getReg()].push_back(MI); + } + continue; + } + if (MI->isDebugInstr()) continue; @@ -1123,11 +1155,6 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, continue; } - // Track the operand index for use in Copy. - SmallVector<unsigned, 2> UsedOpsInCopy; - // Track the register number defed in Copy. - SmallVector<unsigned, 2> DefedRegsInCopy; - // Don't sink the COPY if it would violate a register dependency. if (hasRegisterDependency(MI, UsedOpsInCopy, DefedRegsInCopy, ModifiedRegUnits, UsedRegUnits)) { @@ -1149,11 +1176,21 @@ bool PostRAMachineSinking::tryToSinkCopy(MachineBasicBlock &CurBB, assert((SuccBB->pred_size() == 1 && *SuccBB->pred_begin() == &CurBB) && "Unexpected predecessor"); + // Collect DBG_VALUEs that must sink with this copy. + SmallVector<MachineInstr *, 4> DbgValsToSink; + for (auto &MO : MI->operands()) { + if (!MO.isReg() || !MO.isDef()) + continue; + unsigned reg = MO.getReg(); + for (auto *MI : SeenDbgInstrs.lookup(reg)) + DbgValsToSink.push_back(MI); + } + // Clear the kill flag if SrcReg is killed between MI and the end of the // block. clearKillFlags(MI, CurBB, UsedOpsInCopy, UsedRegUnits, TRI); MachineBasicBlock::iterator InsertPos = SuccBB->getFirstNonPHI(); - performSink(*MI, *SuccBB, InsertPos); + performSink(*MI, *SuccBB, InsertPos, &DbgValsToSink); updateLiveIn(MI, SuccBB, UsedOpsInCopy, DefedRegsInCopy); Changed = true; |