From 6e39379bbbe1d8aba658f638dfc42f0ba0cbb926 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Wed, 20 May 2020 15:30:58 -0700 Subject: [DwarfExpression] Support entry values for indirect parameters Summary: A struct argument can be passed-by-value to a callee via a pointer to a temporary stack copy. Add support for emitting an entry value DBG_VALUE when an indirect parameter DBG_VALUE becomes unavailable. This is done by omitting DW_OP_stack_value from the entry value expression, to make the expression describe the location of an object. rdar://63373691 Reviewers: djtodoro, aprantl, dstenb Subscribers: hiraditya, lldb-commits, llvm-commits Tags: #lldb, #llvm Differential Revision: https://reviews.llvm.org/D80345 --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 7 ++----- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 7 ++----- llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp | 22 +++++++++++++++++++++- llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h | 15 +++++++++++---- llvm/lib/CodeGen/LiveDebugValues.cpp | 6 +----- 5 files changed, 37 insertions(+), 20 deletions(-) (limited to 'llvm/lib/CodeGen') diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 93bf9d6..dce90b3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1285,15 +1285,12 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die, DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc); const DIExpression *DIExpr = DV.getSingleExpression(); DwarfExpr.addFragmentOffset(DIExpr); - if (Location.isIndirect()) - DwarfExpr.setMemoryLocationKind(); + DwarfExpr.setLocation(Location, DIExpr); DIExpressionCursor Cursor(DIExpr); - if (DIExpr->isEntryValue()) { - DwarfExpr.setEntryValueFlag(); + if (DIExpr->isEntryValue()) DwarfExpr.beginEntryValueExpression(Cursor); - } const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo(); if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 17fcf69..953154f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2399,14 +2399,11 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, DwarfExpr.addUnsignedConstant(Value.getInt()); } else if (Value.isLocation()) { MachineLocation Location = Value.getLoc(); - if (Location.isIndirect()) - DwarfExpr.setMemoryLocationKind(); + DwarfExpr.setLocation(Location, DIExpr); DIExpressionCursor Cursor(DIExpr); - if (DIExpr->isEntryValue()) { - DwarfExpr.setEntryValueFlag(); + if (DIExpr->isEntryValue()) DwarfExpr.beginEntryValueExpression(Cursor); - } const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo(); if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg())) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp index 69bc06c..7b64c22 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp @@ -259,7 +259,8 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, if (isEntryValue()) finalizeEntryValue(); - if (isEntryValue() && !isParameterValue() && DwarfVersion >= 4) + if (isEntryValue() && !isIndirect() && !isParameterValue() && + DwarfVersion >= 4) emitOp(dwarf::DW_OP_stack_value); DwarfRegs.clear(); @@ -318,6 +319,25 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI, return true; } +void DwarfExpression::setEntryValueFlags(const MachineLocation &Loc) { + LocationFlags |= EntryValue; + if (Loc.isIndirect()) + LocationFlags |= Indirect; +} + +void DwarfExpression::setLocation(const MachineLocation &Loc, + const DIExpression *DIExpr) { + if (Loc.isIndirect()) + // Do not treat entry value descriptions of indirect parameters as memory + // locations. This allows DwarfExpression::addReg() to add DW_OP_regN to an + // entry value description. + if (!DIExpr->isEntryValue()) + setMemoryLocationKind(); + + if (DIExpr->isEntryValue()) + setEntryValueFlags(Loc); +} + void DwarfExpression::beginEntryValueExpression( DIExpressionCursor &ExprCursor) { auto Op = ExprCursor.take(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h index 5d43862..42be827 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h @@ -30,6 +30,7 @@ class APInt; class DwarfCompileUnit; class DIELoc; class TargetRegisterInfo; +class MachineLocation; /// Holds a DIExpression and keeps track of how many operands have been consumed /// so far. @@ -142,14 +143,18 @@ protected: /// The kind of location description being produced. enum { Unknown = 0, Register, Memory, Implicit }; - /// The flags of location description being produced. - enum { EntryValue = 1, CallSiteParamValue }; + /// Additional location flags which may be combined with any location kind. + /// Currently, entry values are not supported for the Memory location kind. + enum { EntryValue = 1 << 0, Indirect = 1 << 1, CallSiteParamValue = 1 << 2 }; unsigned LocationKind : 3; - unsigned LocationFlags : 2; + unsigned LocationFlags : 3; unsigned DwarfVersion : 4; public: + /// Set the location (\p Loc) and \ref DIExpression (\p DIExpr) to describe. + void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr); + bool isUnknownLocation() const { return LocationKind == Unknown; } bool isMemoryLocation() const { return LocationKind == Memory; } @@ -160,6 +165,8 @@ public: bool isEntryValue() const { return LocationFlags & EntryValue; } + bool isIndirect() const { return LocationFlags & Indirect; } + bool isParameterValue() { return LocationFlags & CallSiteParamValue; } Optional TagOffset; @@ -296,7 +303,7 @@ public: } /// Lock this down to become an entry value location. - void setEntryValueFlag() { LocationFlags |= EntryValue; } + void setEntryValueFlags(const MachineLocation &Loc); /// Lock this down to become a call site parameter location. void setCallSiteParamValueFlag() { LocationFlags |= CallSiteParamValue; } diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp index 470cb22..00a6149a 100644 --- a/llvm/lib/CodeGen/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues.cpp @@ -1613,10 +1613,6 @@ bool LiveDebugValues::isEntryValueCandidate( 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. @@ -1631,7 +1627,7 @@ bool LiveDebugValues::isEntryValueCandidate( return false; // TODO: Add support for parameters that have a pre-existing debug expressions - // (e.g. fragments, or indirect parameters using DW_OP_deref). + // (e.g. fragments). if (MI.getDebugExpression()->getNumElements() > 0) return false; -- cgit v1.1