aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugValues.cpp
diff options
context:
space:
mode:
authorDavid Stenberg <david.stenberg@ericsson.com>2019-11-13 10:36:13 +0100
committerDavid Stenberg <david.stenberg@ericsson.com>2019-11-13 11:10:47 +0100
commit4fec44cd61517cda16f94067a34982628bda34f7 (patch)
treeb20933940f840a82ef7d46f8181b377a9673fc92 /llvm/lib/CodeGen/LiveDebugValues.cpp
parent3367686b4d126e8e035c618829c78315f7751dfd (diff)
downloadllvm-4fec44cd61517cda16f94067a34982628bda34f7.zip
llvm-4fec44cd61517cda16f94067a34982628bda34f7.tar.gz
llvm-4fec44cd61517cda16f94067a34982628bda34f7.tar.bz2
[DebugInfo] Add helper for finding entry value candidates [NFC]
Summary: The conditions that are used to determine if entry values should be emitted for a parameter are quite many, and will grow slightly in a follow-up commit, so move those to a helper function, as was suggested in the code review for D69889. Reviewers: djtodoro, NikolaPrica Reviewed By: djtodoro Subscribers: probinson, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69955
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugValues.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues.cpp89
1 files changed, 61 insertions, 28 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp
index 56fbdff..1b2dfe5 100644
--- a/llvm/lib/CodeGen/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues.cpp
@@ -89,6 +89,24 @@ static Register isDbgValueDescribedByReg(const MachineInstr &MI) {
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register();
}
+/// If \p Op is a stack or frame register return true, otherwise return false.
+/// This is used to avoid basing the debug entry values on the registers, since
+/// we do not support it at the moment.
+static bool isRegOtherThanSPAndFP(const MachineOperand &Op,
+ const MachineInstr &MI,
+ const TargetRegisterInfo *TRI) {
+ if (!Op.isReg())
+ return false;
+
+ const MachineFunction *MF = MI.getParent()->getParent();
+ const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
+ unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
+ Register FP = TRI->getFrameRegister(*MF);
+ Register Reg = Op.getReg();
+
+ return Reg && Reg != SP && Reg != FP;
+}
+
namespace {
class LiveDebugValues : public MachineFunctionPass {
@@ -456,6 +474,13 @@ private:
bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF,
unsigned &Reg);
+ /// Returns true if the given machine instruction is a debug value which we
+ /// can emit entry values for.
+ ///
+ /// Currently, we generate debug entry values only for parameters that are
+ /// unmodified throughout the function and located in a register.
+ bool isEntryValueCandidate(const MachineInstr &MI) const;
+
/// If a given instruction is identified as a spill, return the spill location
/// and set \p Reg to the spilled register.
Optional<VarLoc::SpillLoc> isRestoreInstruction(const MachineInstr &MI,
@@ -1253,6 +1278,39 @@ void LiveDebugValues::flushPendingLocs(VarLocInMBB &PendingInLocs,
}
}
+bool LiveDebugValues::isEntryValueCandidate(const MachineInstr &MI) const {
+ if (!MI.isDebugValue())
+ return false;
+
+ // TODO: Add support for local variables that are expressed in terms of
+ // parameters entry values.
+ // TODO: Add support for modified arguments that can be expressed
+ // by using its entry value.
+ auto *DIVar = MI.getDebugVariable();
+ if (!DIVar->isParameter() || !DIVar->isNotModified())
+ return false;
+
+ // Do not consider parameters that belong to an inlined function.
+ if (MI.getDebugLoc()->getInlinedAt())
+ return false;
+
+ // Do not consider indirect debug values (TODO: explain why).
+ if (MI.isIndirectDebugValue())
+ return false;
+
+ // Only consider parameters that are described using registers. Parameters
+ // that are passed on the stack are not yet supported, so ignore debug
+ // values that are described by the frame or stack pointer.
+ if (!isRegOtherThanSPAndFP(MI.getOperand(0), MI, TRI))
+ return false;
+
+ // TODO: Add support for parameters that are described as fragments.
+ if (MI.getDebugExpression()->isFragment())
+ return false;
+
+ return true;
+}
+
/// Calculate the liveness information for the given machine function and
/// extend ranges across basic blocks.
bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
@@ -1289,41 +1347,16 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
std::greater<unsigned int>>
Pending;
- // Besides parameter's modification, check whether a DBG_VALUE is inlined
- // in order to deduce whether the variable that it tracks comes from
- // a different function. If that is the case we can't track its entry value.
- auto IsUnmodifiedFuncParam = [&](const MachineInstr &MI) {
- auto *DIVar = MI.getDebugVariable();
- return DIVar->isParameter() && DIVar->isNotModified() &&
- !MI.getDebugLoc()->getInlinedAt();
- };
-
- const TargetLowering *TLI = MF.getSubtarget().getTargetLowering();
- unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
- Register FP = TRI->getFrameRegister(MF);
- auto IsRegOtherThanSPAndFP = [&](const MachineOperand &Op) -> bool {
- return Op.isReg() && Op.getReg() != SP && Op.getReg() != FP;
- };
-
// Working set of currently collected debug variables mapped to DBG_VALUEs
// representing candidates for production of debug entry values.
DebugParamMap DebugEntryVals;
- MachineBasicBlock &First_MBB = *(MF.begin());
// Only in the case of entry MBB collect DBG_VALUEs representing
// function parameters in order to generate debug entry values for them.
- // Currently, we generate debug entry values only for parameters that are
- // unmodified throughout the function and located in a register.
- // TODO: Add support for parameters that are described as fragments.
- // TODO: Add support for modified arguments that can be expressed
- // by using its entry value.
- // TODO: Add support for local variables that are expressed in terms of
- // parameters entry values.
+ MachineBasicBlock &First_MBB = *(MF.begin());
for (auto &MI : First_MBB)
- if (MI.isDebugValue() && IsUnmodifiedFuncParam(MI) &&
- !MI.isIndirectDebugValue() && IsRegOtherThanSPAndFP(MI.getOperand(0)) &&
- !DebugEntryVals.count(MI.getDebugVariable()) &&
- !MI.getDebugExpression()->isFragment())
+ if (isEntryValueCandidate(MI) &&
+ !DebugEntryVals.count(MI.getDebugVariable()))
DebugEntryVals[MI.getDebugVariable()] = &MI;
// Initialize per-block structures and scan for fragment overlaps.