diff options
author | David Stenberg <david.stenberg@ericsson.com> | 2019-11-13 10:36:13 +0100 |
---|---|---|
committer | David Stenberg <david.stenberg@ericsson.com> | 2019-11-13 11:10:47 +0100 |
commit | 4fec44cd61517cda16f94067a34982628bda34f7 (patch) | |
tree | b20933940f840a82ef7d46f8181b377a9673fc92 /llvm/lib/CodeGen/LiveDebugValues.cpp | |
parent | 3367686b4d126e8e035c618829c78315f7751dfd (diff) | |
download | llvm-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.cpp | 89 |
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. |