summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse.llvm@gmail.com>2018-11-02 16:52:48 +0000
committerJeremy Morse <jeremy.morse.llvm@gmail.com>2018-11-02 16:52:48 +0000
commitd538352b3e4b1eabee02fc7ce491728678cc4716 (patch)
tree8e610ac20334332a92701d38b3e09c6708d6a0dd /llvm/lib/CodeGen/MachineSink.cpp
parent82536501c75c60c5a2a0bda9e255a51ce7741018 (diff)
downloadbcm5719-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.cpp57
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;
OpenPOWER on IntegriCloud