<div dir="ltr">But that shouldn't cause the DW_TAG_variable to not be present, right? we keep all the variables in the "variables" list off the subprogram to emit even in the case of optimizations eliminating a variable (then the variable is emitted, but without any DW_AT_location) - that was my understanding.</div><br><div class="gmail_quote"><div dir="ltr">On Thu, Mar 29, 2018 at 10:11 AM Adrian Prantl <<a href="mailto:aprantl@apple.com">aprantl@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><br><blockquote type="cite"><div>On Mar 29, 2018, at 10:00 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:</div><br class="m_-5553316303691992338Apple-interchange-newline"><div><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Thu, Mar 29, 2018 at 9:09 AM Adrian Prantl <<a href="mailto:aprantl@apple.com" target="_blank">aprantl@apple.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><br><blockquote type="cite"><div>On Mar 29, 2018, at 9:02 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:</div><br class="m_-5553316303691992338m_8131005181638181115Apple-interchange-newline"><div><div dir="ltr">Seeing about a 7.5% increase in (compressed) debug_loc (and 4.2% increase in debug_info) in one binary at Google.<br></div></div></blockquote><div><br></div></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><div>So I guess this is ... good news?</div></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><div><br></div><blockquote type="cite"><div><div dir="ltr"><br>I haven't looked into it further - if you all think this is expected (an increase in debug location accuracy/granularity/etc would account for this sort of growth), I'm OK with it.<br><br>If useful, I can look into some samples further - or you can (assuming an optimized Clang shows similar growth - I haven't checked yet).<br></div></div></blockquote><div><br></div></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><div>Would it be easy for you to run llvm-dwarfdump --statistics on before and after? That might tell us how many more variables are visible for the extra cost in size.</div></div></div></blockquote><div><br></div><div>Sure, in both cases llvm-dwarfdump printed:<br><br><div>Location list overflows the debug_loc section.</div><div>error: failed to consume entire .debug_loc section<br><br>The % improvements:<br><br>Source functions: 0%</div><div>Inlined functions: 0%</div><div>Unique source variables: 11.19%<br>Source variables: 357.78%<br>Variables with locations: 15.09%<br>Scope bytes total: 8.39%<br>Scope bytes covered: 16.87%<br><br>So what does the "source variables" mean? Changes to optimizations shouldn't increase the number of variables we put in the DWARF, right? (that's why there's the "variables" list off the subprogram - to keep track of variables even if they're totally optimized away)</div></div></div></div></div></blockquote><div><br></div></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><div>dwarfdump has no way of knowing what variables *should* be in the debug info, so if this patch added new DBG_VALUEs that were previously being dropped, we can see an increase in variables that were previously missing entirely because the only DBG_VALUE describing them was dropped by SDag.</div></div></div><div style="word-wrap:break-word;line-break:after-white-space"><div><div><br></div><div>-- adrian</div><blockquote type="cite"><div><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><br><blockquote type="cite"><div><div dir="ltr"><br><div class="gmail_quote"><div dir="ltr">On Mon, Mar 12, 2018 at 11:05 AM Bjorn Pettersson via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: bjope<br>
Date: Mon Mar 12 11:02:39 2018<br>
New Revision: 327303<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=327303&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=327303&view=rev</a><br>
Log:<br>
[SelectionDAG] Improve handling of dangling debug info<br>
<br>
Summary:<br>
1) Make sure to discard dangling debug info if the variable (or<br>
variable fragment) is mapped to something new before we had a<br>
chance to resolve the dangling debug info.<br>
<br>
2) When resolving debug info, make sure to bump the associated<br>
SDNodeOrder to ensure that the DBG_VALUE is emitted after the<br>
instruction that defines the value used in the DBG_VALUE.<br>
This will avoid a debug-use before def scenario as seen in<br>
<a href="https://bugs.llvm.org/show_bug.cgi?id=36417" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=36417</a>.<br>
<br>
The new test case, test/DebugInfo/X86/sdag-dangling-dbgvalue.ll,<br>
show some other limitations in how dangling debug info is<br>
handled in the SelectionDAG. Since we currently only support<br>
having one dangling dbg.value per Value, we will end up dropping<br>
debug info when there are more than one variable that is described<br>
by the same "dangling value".<br>
<br>
Reviewers: aprantl<br>
<br>
Reviewed By: aprantl<br>
<br>
Subscribers: aprantl, eraman, llvm-commits, JDevlieghere<br>
<br>
Tags: #debug-info<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D44369" rel="noreferrer" target="_blank">https://reviews.llvm.org/D44369</a><br>
<br>
Added:<br>
    llvm/trunk/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/DebugInfoMetadata.h<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h<br>
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h<br>
    llvm/trunk/test/DebugInfo/X86/dbg-value-inlined-parameter.ll<br>
<br>
Modified: llvm/trunk/include/llvm/IR/DebugInfoMetadata.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfoMetadata.h?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DebugInfoMetadata.h?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/DebugInfoMetadata.h (original)<br>
+++ llvm/trunk/include/llvm/IR/DebugInfoMetadata.h Mon Mar 12 11:02:39 2018<br>
@@ -2415,6 +2415,32 @@ public:<br>
   static Optional<DIExpression *><br>
   createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits,<br>
                            unsigned SizeInBits);<br>
+<br>
+  /// Determine the relative position of the fragments described by this<br>
+  /// DIExpression and \p Other.<br>
+  /// Returns -1 if this is entirely before Other, 0 if this and Other overlap,<br>
+  /// 1 if this is entirely after Other.<br>
+  int fragmentCmp(const DIExpression *Other) const {<br>
+    auto Fragment1 = *getFragmentInfo();<br>
+    auto Fragment2 = *Other->getFragmentInfo();<br>
+    unsigned l1 = Fragment1.OffsetInBits;<br>
+    unsigned l2 = Fragment2.OffsetInBits;<br>
+    unsigned r1 = l1 + Fragment1.SizeInBits;<br>
+    unsigned r2 = l2 + Fragment2.SizeInBits;<br>
+    if (r1 <= l2)<br>
+      return -1;<br>
+    else if (r2 <= l1)<br>
+      return 1;<br>
+    else<br>
+      return 0;<br>
+  }<br>
+<br>
+  /// Check if fragments overlap between this DIExpression and \p Other.<br>
+  bool fragmentsOverlap(const DIExpression *Other) const {<br>
+    if (!isFragment() || !Other->isFragment())<br>
+      return true;<br>
+    return fragmentCmp(Other) == 0;<br>
+  }<br>
 };<br>
<br>
 /// Global variables.<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Mon Mar 12 11:02:39 2018<br>
@@ -1107,7 +1107,7 @@ void CodeViewDebug::calculateRanges(<br>
       auto J = std::next(I);<br>
       const DIExpression *DIExpr = DVInst->getDebugExpression();<br>
       while (J != E &&<br>
-             !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))<br>
+             !DIExpr->fragmentsOverlap(J->first->getDebugExpression()))<br>
         ++J;<br>
       if (J != E)<br>
         End = getLabelBeforeInsn(J->first);<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp Mon Mar 12 11:02:39 2018<br>
@@ -123,29 +123,6 @@ MCSymbol *DebugHandlerBase::getLabelAfte<br>
   return LabelsAfterInsn.lookup(MI);<br>
 }<br>
<br>
-int DebugHandlerBase::fragmentCmp(const DIExpression *P1,<br>
-                                  const DIExpression *P2) {<br>
-  auto Fragment1 = *P1->getFragmentInfo();<br>
-  auto Fragment2 = *P2->getFragmentInfo();<br>
-  unsigned l1 = Fragment1.OffsetInBits;<br>
-  unsigned l2 = Fragment2.OffsetInBits;<br>
-  unsigned r1 = l1 + Fragment1.SizeInBits;<br>
-  unsigned r2 = l2 + Fragment2.SizeInBits;<br>
-  if (r1 <= l2)<br>
-    return -1;<br>
-  else if (r2 <= l1)<br>
-    return 1;<br>
-  else<br>
-    return 0;<br>
-}<br>
-<br>
-bool DebugHandlerBase::fragmentsOverlap(const DIExpression *P1,<br>
-                                        const DIExpression *P2) {<br>
-  if (!P1->isFragment() || !P2->isFragment())<br>
-    return true;<br>
-  return fragmentCmp(P1, P2) == 0;<br>
-}<br>
-<br>
 /// If this type is derived from a base type then return base type size.<br>
 uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {<br>
   DIType *Ty = TyRef.resolve();<br>
@@ -232,8 +209,8 @@ void DebugHandlerBase::beginFunction(con<br>
           const DIExpression *Fragment = I->first->getDebugExpression();<br>
           if (std::all_of(Ranges.begin(), I,<br>
                           [&](DbgValueHistoryMap::InstrRange Pred) {<br>
-                            return !fragmentsOverlap(<br>
-                                Fragment, Pred.first->getDebugExpression());<br>
+                            return !Fragment->fragmentsOverlap(<br>
+                                Pred.first->getDebugExpression());<br>
                           }))<br>
             LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();<br>
           else<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DebugHandlerBase.h Mon Mar 12 11:02:39 2018<br>
@@ -122,14 +122,6 @@ public:<br>
   /// Return Label immediately following the instruction.<br>
   MCSymbol *getLabelAfterInsn(const MachineInstr *MI);<br>
<br>
-  /// Determine the relative position of the fragments described by P1 and P2.<br>
-  /// Returns -1 if P1 is entirely before P2, 0 if P1 and P2 overlap, 1 if P1 is<br>
-  /// entirely after P2.<br>
-  static int fragmentCmp(const DIExpression *P1, const DIExpression *P2);<br>
-<br>
-  /// Determine whether two variable fragments overlap.<br>
-  static bool fragmentsOverlap(const DIExpression *P1, const DIExpression *P2);<br>
-<br>
   /// If this type is derived from a base type then return base type size.<br>
   static uint64_t getBaseTypeSize(const DITypeRef TyRef);<br>
 };<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Mon Mar 12 11:02:39 2018<br>
@@ -919,8 +919,7 @@ bool DebugLocEntry::MergeValues(const De<br>
     // sorted.<br>
     for (unsigned i = 0, j = 0; i < Values.size(); ++i) {<br>
       for (; j < Next.Values.size(); ++j) {<br>
-        int res = DebugHandlerBase::fragmentCmp(<br>
-            cast<DIExpression>(Values[i].Expression),<br>
+        int res = cast<DIExpression>(Values[i].Expression)->fragmentCmp(<br>
             cast<DIExpression>(Next.Values[j].Expression));<br>
         if (res == 0) // The two expressions overlap, we can't merge.<br>
           return false;<br>
@@ -983,7 +982,7 @@ DwarfDebug::buildLocationList(SmallVecto<br>
     // If this fragment overlaps with any open ranges, truncate them.<br>
     const DIExpression *DIExpr = Begin->getDebugExpression();<br>
     auto Last = remove_if(OpenRanges, [&](DebugLocEntry::Value R) {<br>
-      return fragmentsOverlap(DIExpr, R.getExpression());<br>
+      return DIExpr->fragmentsOverlap(R.getExpression());<br>
     });<br>
     OpenRanges.erase(Last, OpenRanges.end());<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Mar 12 11:02:39 2018<br>
@@ -12,6 +12,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "SelectionDAGBuilder.h"<br>
+#include "SDNodeDbgValue.h"<br>
 #include "llvm/ADT/APFloat.h"<br>
 #include "llvm/ADT/APInt.h"<br>
 #include "llvm/ADT/ArrayRef.h"<br>
@@ -1077,29 +1078,64 @@ void SelectionDAGBuilder::visit(unsigned<br>
   }<br>
 }<br>
<br>
+void SelectionDAGBuilder::dropDanglingDebugInfo(const DILocalVariable *Variable,<br>
+                                                const DIExpression *Expr) {<br>
+  SmallVector<const Value *, 4> ToRemove;<br>
+  for (auto &DMI : DanglingDebugInfoMap) {<br>
+    DanglingDebugInfo &DDI = DMI.second;<br>
+    if (DDI.getDI()) {<br>
+      const DbgValueInst *DI = DDI.getDI();<br>
+      DIVariable *DanglingVariable = DI->getVariable();<br>
+      DIExpression *DanglingExpr = DI->getExpression();<br>
+      if (DanglingVariable == Variable &&<br>
+          Expr->fragmentsOverlap(DanglingExpr)) {<br>
+        DEBUG(dbgs() << "Dropping dangling debug info for " << *DI << "\n");<br>
+        ToRemove.push_back(DMI.first);<br>
+      }<br>
+    }<br>
+  }<br>
+<br>
+  for (auto V : ToRemove)<br>
+    DanglingDebugInfoMap[V] = DanglingDebugInfo();<br>
+}<br>
+<br>
 // resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V,<br>
 // generate the debug data structures now that we've seen its definition.<br>
 void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,<br>
                                                    SDValue Val) {<br>
   DanglingDebugInfo &DDI = DanglingDebugInfoMap[V];<br>
-  if (DDI.getDI()) {<br>
-    const DbgValueInst *DI = DDI.getDI();<br>
-    DebugLoc dl = DDI.getdl();<br>
-    unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();<br>
-    DILocalVariable *Variable = DI->getVariable();<br>
-    DIExpression *Expr = DI->getExpression();<br>
-    assert(Variable->isValidLocationForIntrinsic(dl) &&<br>
-           "Expected inlined-at fields to agree");<br>
-    SDDbgValue *SDV;<br>
-    if (Val.getNode()) {<br>
-      if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, false, Val)) {<br>
-        SDV = getDbgValue(Val, Variable, Expr, dl, DbgSDNodeOrder);<br>
-        DAG.AddDbgValue(SDV, Val.getNode(), false);<br>
-      }<br>
+  if (!DDI.getDI())<br>
+    return;<br>
+  const DbgValueInst *DI = DDI.getDI();<br>
+  DebugLoc dl = DDI.getdl();<br>
+  unsigned ValSDNodeOrder = Val.getNode()->getIROrder();<br>
+  unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();<br>
+  DILocalVariable *Variable = DI->getVariable();<br>
+  DIExpression *Expr = DI->getExpression();<br>
+  assert(Variable->isValidLocationForIntrinsic(dl) &&<br>
+         "Expected inlined-at fields to agree");<br>
+  SDDbgValue *SDV;<br>
+  if (Val.getNode()) {<br>
+    if (!EmitFuncArgumentDbgValue(V, Variable, Expr, dl, false, Val)) {<br>
+      DEBUG(dbgs() << "Resolve dangling debug info [order=" << DbgSDNodeOrder<br>
+            << "] for:\n  " << *DI << "\n");<br>
+      DEBUG(dbgs() << "  By mapping to:\n    "; Val.dump());<br>
+      // Increase the SDNodeOrder for the DbgValue here to make sure it is<br>
+      // inserted after the definition of Val when emitting the instructions<br>
+      // after ISel. An alternative could be to teach<br>
+      // ScheduleDAGSDNodes::EmitSchedule to delay the insertion properly.<br>
+      DEBUG(if (ValSDNodeOrder > DbgSDNodeOrder)<br>
+              dbgs() << "changing SDNodeOrder from " << DbgSDNodeOrder<br>
+                     << " to " << ValSDNodeOrder << "\n");<br>
+      SDV = getDbgValue(Val, Variable, Expr, dl,<br>
+                        std::max(DbgSDNodeOrder, ValSDNodeOrder));<br>
+      DAG.AddDbgValue(SDV, Val.getNode(), false);<br>
     } else<br>
-      DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");<br>
-    DanglingDebugInfoMap[V] = DanglingDebugInfo();<br>
-  }<br>
+      DEBUG(dbgs() << "Resolved dangling debug info for " << *DI<br>
+            << "in EmitFuncArgumentDbgValue\n");<br>
+  } else<br>
+    DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n");<br>
+  DanglingDebugInfoMap[V] = DanglingDebugInfo();<br>
 }<br>
<br>
 /// getCopyFromRegs - If there was virtual register allocated for the value V<br>
@@ -5178,6 +5214,7 @@ SelectionDAGBuilder::visitIntrinsicCall(<br>
     const DbgInfoIntrinsic &DI = cast<DbgInfoIntrinsic>(I);<br>
     DILocalVariable *Variable = DI.getVariable();<br>
     DIExpression *Expression = DI.getExpression();<br>
+    dropDanglingDebugInfo(Variable, Expression);<br>
     assert(Variable && "Missing variable");<br>
<br>
     // Check if address has undef value.<br>
@@ -5209,10 +5246,11 @@ SelectionDAGBuilder::visitIntrinsicCall(<br>
     // DBG_VALUE instructions. llvm.dbg.declare is handled as a frame index in<br>
     // the MachineFunction variable table.<br>
     if (FI != std::numeric_limits<int>::max()) {<br>
-      if (Intrinsic == Intrinsic::dbg_addr)<br>
-        DAG.AddDbgValue(DAG.getFrameIndexDbgValue(Variable, Expression, FI, dl,<br>
-                                                  SDNodeOrder),<br>
-                        getRoot().getNode(), isParameter);<br>
+      if (Intrinsic == Intrinsic::dbg_addr) {<br>
+         SDDbgValue *SDV = DAG.getFrameIndexDbgValue(Variable, Expression,<br>
+                                                     FI, dl, SDNodeOrder);<br>
+         DAG.AddDbgValue(SDV, getRoot().getNode(), isParameter);<br>
+      }<br>
       return nullptr;<br>
     }<br>
<br>
@@ -5256,6 +5294,7 @@ SelectionDAGBuilder::visitIntrinsicCall(<br>
<br>
     DILocalVariable *Variable = DI.getVariable();<br>
     DIExpression *Expression = DI.getExpression();<br>
+    dropDanglingDebugInfo(Variable, Expression);<br>
     const Value *V = DI.getValue();<br>
     if (!V)<br>
       return nullptr;<br>
@@ -5280,6 +5319,12 @@ SelectionDAGBuilder::visitIntrinsicCall(<br>
       return nullptr;<br>
     }<br>
<br>
+    // TODO: When we get here we will either drop the dbg.value completely, or<br>
+    // we try to move it forward by letting it dangle for awhile. So we should<br>
+    // probably add an extra DbgValue to the DAG here, with a reference to<br>
+    // "noreg", to indicate that we have lost the debug location for the<br>
+    // variable.<br>
+<br>
     if (!V->use_empty() ) {<br>
       // Do not call getValue(V) yet, as we don't want to generate code.<br>
       // Remember it for later.<br>
<br>
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)<br>
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Mon Mar 12 11:02:39 2018<br>
@@ -671,6 +671,12 @@ public:<br>
   /// emit CopyFromReg of the specified type Ty. Return empty SDValue() otherwise.<br>
   SDValue getCopyFromRegs(const Value *V, Type *Ty);<br>
<br>
+  /// If we have dangling debug info that describes \p Variable, or an<br>
+  /// overlapping part of variable considering the \p Expr, then this method<br>
+  /// weill drop that debug info as it isn't valid any longer.<br>
+  void dropDanglingDebugInfo(const DILocalVariable *Variable,<br>
+                             const DIExpression *Expr);<br>
+<br>
   // resolveDanglingDebugInfo - if we saw an earlier dbg_value referring to V,<br>
   // generate the debug data structures now that we've seen its definition.<br>
   void resolveDanglingDebugInfo(const Value *V, SDValue Val);<br>
<br>
Modified: llvm/trunk/test/DebugInfo/X86/dbg-value-inlined-parameter.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dbg-value-inlined-parameter.ll?rev=327303&r1=327302&r2=327303&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/dbg-value-inlined-parameter.ll?rev=327303&r1=327302&r2=327303&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/X86/dbg-value-inlined-parameter.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/X86/dbg-value-inlined-parameter.ll Mon Mar 12 11:02:39 2018<br>
@@ -32,10 +32,10 @@<br>
 ;CHECK-NEXT: DW_AT_call_line<br>
<br>
 ;CHECK: DW_TAG_formal_parameter<br>
+;FIXME: Linux shouldn't drop this parameter either...<br>
 ;CHECK-NOT: DW_TAG<br>
-;FIXME: Shouldn't drop this parameter...<br>
-;XCHECK:   DW_AT_abstract_origin {{.*}} "sp"<br>
-;XCHECK: DW_TAG_formal_parameter<br>
+;DARWIN:   DW_AT_abstract_origin {{.*}} "sp"<br>
+;DARWIN: DW_TAG_formal_parameter<br>
 ;CHECK: DW_AT_abstract_origin {{.*}} "nums"<br>
 ;CHECK-NOT: DW_TAG_formal_parameter<br>
<br>
<br>
Added: llvm/trunk/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll?rev=327303&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll?rev=327303&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll (added)<br>
+++ llvm/trunk/test/DebugInfo/X86/sdag-dangling-dbgvalue.ll Mon Mar 12 11:02:39 2018<br>
@@ -0,0 +1,201 @@<br>
+; RUN: llc %s -stop-before expand-isel-pseudos -o - | FileCheck %s<br>
+<br>
+;--------------------------------------------------------------------<br>
+; This test case is basically generated from the following C code.<br>
+; Compiled with "--target=x86_64-apple-darwin -S -g -O3" to get debug<br>
+; info for optimized code.<br>
+;<br>
+; struct SS {<br>
+;   int a;<br>
+;   int b;<br>
+; } S = { .a = 23, .b = -17 };<br>
+;<br>
+; int test1() {<br>
+;   struct SS* foo1 = &S;<br>
+;   return (int)foo1;<br>
+; }<br>
+;<br>
+; int test2() {<br>
+;   struct SS* foo2 = &S;<br>
+;   struct SS* bar2 = &S;<br>
+;   return (int)foo2 + (int)bar2;<br>
+; }<br>
+;<br>
+; int test3() {<br>
+;   struct SS* bar3 = &S;<br>
+;   struct SS* foo3 = &S;<br>
+;   return (int)foo3 + (int)bar3;<br>
+; }<br>
+;<br>
+; int test4() {<br>
+;   struct SS* foo4 = &S;<br>
+;   struct SS* bar4 = &S;<br>
+;   foo = 0;<br>
+;   return (int)foo4 + (int)bar4;<br>
+; }<br>
+;<br>
+; int test5() {<br>
+;   struct SS* bar5 = &S;<br>
+;   struct SS* foo5 = &S;<br>
+;   foo5 = 0;<br>
+;   return (int)foo5 + (int)bar5;<br>
+; }<br>
+;--------------------------------------------------------------------<br>
+<br>
+; CHECK:  ![[FOO1:.*]] = !DILocalVariable(name: "foo1"<br>
+; CHECK:  ![[BAR1:.*]] = !DILocalVariable(name: "bar1"<br>
+; CHECK:  ![[FOO2:.*]] = !DILocalVariable(name: "foo2"<br>
+; CHECK:  ![[BAR2:.*]] = !DILocalVariable(name: "bar2"<br>
+; CHECK:  ![[FOO3:.*]] = !DILocalVariable(name: "bar3"<br>
+; CHECK:  ![[BAR3:.*]] = !DILocalVariable(name: "foo3"<br>
+; CHECK:  ![[FOO4:.*]] = !DILocalVariable(name: "foo4"<br>
+; CHECK:  ![[BAR4:.*]] = !DILocalVariable(name: "bar4"<br>
+; CHECK:  ![[FOO5:.*]] = !DILocalVariable(name: "bar5"<br>
+; CHECK:  ![[BAR5:.*]] = !DILocalVariable(name: "foo5"<br>
+<br>
+<br>
+source_filename = "sdag-dangling-dbgvalue.c"<br>
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"<br>
+target triple = "x86_64-apple-macosx10.4.0"<br>
+<br>
+%struct.SS = type { i32, i32 }<br>
+<br>
+@S = global %struct.SS { i32 23, i32 -17 }, align 4, !dbg !0<br>
+<br>
+; Verify that the def comes before the debug-use for foo1.<br>
+; TODO: Currently dbg.value for bar1 is dropped(?), is that expected?<br>
+define i32 @test1() local_unnamed_addr #0 !dbg !17 {<br>
+; CHECK-LABEL: bb.0.entry1<br>
+; CHECK-NEXT:    [[REG1:%[0-9]+]]:gr64 =<br>
+; CHECK-NEXT:    DBG_VALUE debug-use [[REG1]], debug-use $noreg, ![[FOO1]], !DIExpression()<br>
+entry1:<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !20, metadata !DIExpression()), !dbg !23<br>
+  call void @llvm.dbg.value(metadata %struct.SS* null, metadata !22, metadata !DIExpression()), !dbg !24<br>
+  ret i32 ptrtoint (%struct.SS* @S to i32), !dbg !25<br>
+}<br>
+<br>
+; Verify that the def comes before the debug-use for bar2.<br>
+; TODO: Currently dbg.value for foo2 is dropped. Seems to be a bug. The<br>
+;       SelectionDAGBuilder should support several dangling dbg.value for the<br>
+;       same value.<br>
+define i32 @test2() local_unnamed_addr #0 !dbg !26 {<br>
+; CHECK-LABEL: bb.0.entry2<br>
+; CHECK-NEXT:    [[REG2:%[0-9]+]]:gr64 =<br>
+; CHECK-NEXT:    DBG_VALUE debug-use [[REG2]], debug-use $noreg, ![[BAR2]], !DIExpression()<br>
+entry2:<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !28, metadata !DIExpression()), !dbg !30<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !29, metadata !DIExpression()), !dbg !31<br>
+  ret i32 add (i32 ptrtoint (%struct.SS* @S to i32), i32 ptrtoint (%struct.SS* @S to i32)), !dbg !32<br>
+}<br>
+<br>
+; Verify that the def comes before the debug-use for foo3.<br>
+; TODO: Currently dbg.value for bar3 is dropped. Seems to be a bug. The<br>
+;       SelectionDAGBuilder should support several dangling dbg.value for the<br>
+;       same value.<br>
+define i32 @test3() local_unnamed_addr #0 !dbg !33 {<br>
+; CHECK-LABEL: bb.0.entry3<br>
+; CHECK-NEXT:    [[REG3:%[0-9]+]]:gr64 =<br>
+; CHECK-NEXT:    DBG_VALUE debug-use [[REG3]], debug-use $noreg, ![[FOO3]], !DIExpression()<br>
+entry3:<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !36, metadata !DIExpression()), !dbg !38<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !35, metadata !DIExpression()), !dbg !37<br>
+  ret i32 add (i32 ptrtoint (%struct.SS* @S to i32), i32 ptrtoint (%struct.SS* @S to i32)), !dbg !39<br>
+}<br>
+<br>
+; Verify that the def comes before the debug-use for bar4.<br>
+; TODO: Currently dbg.value for foo4 is dropped. It is set to null and not<br>
+;       used. Just like in test1 it can be discussed if there should be a<br>
+;       DBG_VALUE for foo4 here.<br>
+define i32 @test4() local_unnamed_addr #0 !dbg !40 {<br>
+; CHECK-LABEL: bb.0.entry4<br>
+; CHECK-NEXT:    [[REG4:%[0-9]+]]:gr64 =<br>
+; CHECK-NEXT:    DBG_VALUE debug-use [[REG4]], debug-use $noreg, ![[BAR4]], !DIExpression()<br>
+entry4:<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !42, metadata !DIExpression()), !dbg !44<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !43, metadata !DIExpression()), !dbg !45<br>
+  call void @llvm.dbg.value(metadata %struct.SS* null, metadata !42, metadata !DIExpression()), !dbg !44<br>
+  ret i32 ptrtoint (%struct.SS* @S to i32), !dbg !46<br>
+}<br>
+<br>
+; Verify that we do not get a DBG_VALUE that maps foo5 to @S here.<br>
+; TODO: At the moment we do not get any DBG_VALUE at all here. If<br>
+;       SelectionDAGBuilder should support several dangling dbg.value for the<br>
+;       same value it would be possible to at least get a DBG_VALUE for<br>
+;       bar5.<br>
+; TODO: foo5 is set to null, and it is not really used. Just like in test1 it<br>
+;       can be discussed if there should be a DBG_VALUE for foo5 here.<br>
+define i32 @test5() local_unnamed_addr #0 !dbg !47 {<br>
+; CHECK-LABEL: bb.0.entry5:<br>
+; CHECK-NOT:     DBG_VALUE<br>
+; CHECK:         RET<br>
+entry5:<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !49, metadata !DIExpression()), !dbg !51<br>
+  call void @llvm.dbg.value(metadata %struct.SS* @S, metadata !50, metadata !DIExpression()), !dbg !52<br>
+  call void @llvm.dbg.value(metadata %struct.SS* null, metadata !50, metadata !DIExpression()), !dbg !52<br>
+  ret i32 ptrtoint (%struct.SS* @S to i32), !dbg !53<br>
+}<br>
+<br>
+; Function Attrs: nounwind readnone speculatable<br>
+declare void @llvm.dbg.value(metadata, metadata, metadata) #1<br>
+<br>
+attributes #0 = { nounwind readnone uwtable }<br>
+attributes #1 = { nounwind readnone speculatable }<br>
+<br>
+!<a href="http://llvm.dbg.cu/" rel="noreferrer" target="_blank">llvm.dbg.cu</a> = !{!2}<br>
+!llvm.module.flags = !{!12, !13, !14, !15}<br>
+!llvm.ident = !{!16}<br>
+<br>
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())<br>
+!1 = distinct !DIGlobalVariable(name: "S", scope: !2, file: !3, line: 4, type: !8, isLocal: false, isDefinition: true)<br>
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0 (trunk 327229) (llvm/trunk 327239)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !7)<br>
+!3 = !DIFile(filename: "sdag-dangling-dbgvalue.c", directory: "/repo/uabbpet/llvm-master")<br>
+!4 = !{}<br>
+!5 = !{!6}<br>
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)<br>
+!7 = !{!0}<br>
+!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SS", file: !3, line: 1, size: 64, elements: !9)<br>
+!9 = !{!10, !11}<br>
+!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 2, baseType: !6, size: 32)<br>
+!11 = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: !8, file: !3, line: 3, baseType: !6, size: 32, offset: 32)<br>
+!12 = !{i32 2, !"Dwarf Version", i32 2}<br>
+!13 = !{i32 2, !"Debug Info Version", i32 3}<br>
+!14 = !{i32 1, !"wchar_size", i32 4}<br>
+!15 = !{i32 7, !"PIC Level", i32 2}<br>
+!16 = !{!"clang version 7.0.0 (trunk 327229) (llvm/trunk 327239)"}<br>
+!17 = distinct !DISubprogram(name: "test1", scope: !3, file: !3, line: 6, type: !18, isLocal: false, isDefinition: true, scopeLine: 6, isOptimized: true, unit: !2, variables: !19)<br>
+!18 = !DISubroutineType(types: !5)<br>
+!19 = !{!20, !22}<br>
+!20 = !DILocalVariable(name: "foo1", scope: !17, file: !3, line: 7, type: !21)<br>
+!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)<br>
+!22 = !DILocalVariable(name: "bar1", scope: !17, file: !3, line: 8, type: !21)<br>
+!23 = !DILocation(line: 7, column: 14, scope: !17)<br>
+!24 = !DILocation(line: 8, column: 14, scope: !17)<br>
+!25 = !DILocation(line: 9, column: 3, scope: !17)<br>
+!26 = distinct !DISubprogram(name: "test2", scope: !3, file: !3, line: 12, type: !18, isLocal: false, isDefinition: true, scopeLine: 12, isOptimized: true, unit: !2, variables: !27)<br>
+!27 = !{!28, !29}<br>
+!28 = !DILocalVariable(name: "foo2", scope: !26, file: !3, line: 13, type: !21)<br>
+!29 = !DILocalVariable(name: "bar2", scope: !26, file: !3, line: 14, type: !21)<br>
+!30 = !DILocation(line: 13, column: 14, scope: !26)<br>
+!31 = !DILocation(line: 14, column: 14, scope: !26)<br>
+!32 = !DILocation(line: 15, column: 3, scope: !26)<br>
+!33 = distinct !DISubprogram(name: "test3", scope: !3, file: !3, line: 18, type: !18, isLocal: false, isDefinition: true, scopeLine: 18, isOptimized: true, unit: !2, variables: !34)<br>
+!34 = !{!35, !36}<br>
+!35 = !DILocalVariable(name: "bar3", scope: !33, file: !3, line: 19, type: !21)<br>
+!36 = !DILocalVariable(name: "foo3", scope: !33, file: !3, line: 20, type: !21)<br>
+!37 = !DILocation(line: 19, column: 14, scope: !33)<br>
+!38 = !DILocation(line: 20, column: 14, scope: !33)<br>
+!39 = !DILocation(line: 21, column: 3, scope: !33)<br>
+!40 = distinct !DISubprogram(name: "test4", scope: !3, file: !3, line: 24, type: !18, isLocal: false, isDefinition: true, scopeLine: 24, isOptimized: true, unit: !2, variables: !41)<br>
+!41 = !{!42, !43}<br>
+!42 = !DILocalVariable(name: "foo4", scope: !40, file: !3, line: 25, type: !21)<br>
+!43 = !DILocalVariable(name: "bar4", scope: !40, file: !3, line: 26, type: !21)<br>
+!44 = !DILocation(line: 25, column: 14, scope: !40)<br>
+!45 = !DILocation(line: 26, column: 14, scope: !40)<br>
+!46 = !DILocation(line: 28, column: 3, scope: !40)<br>
+!47 = distinct !DISubprogram(name: "test5", scope: !3, file: !3, line: 31, type: !18, isLocal: false, isDefinition: true, scopeLine: 31, isOptimized: true, unit: !2, variables: !48)<br>
+!48 = !{!49, !50}<br>
+!49 = !DILocalVariable(name: "bar5", scope: !47, file: !3, line: 32, type: !21)<br>
+!50 = !DILocalVariable(name: "foo5", scope: !47, file: !3, line: 33, type: !21)<br>
+!51 = !DILocation(line: 32, column: 14, scope: !47)<br>
+!52 = !DILocation(line: 33, column: 14, scope: !47)<br>
+!53 = !DILocation(line: 35, column: 3, scope: !47)<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>
</div></blockquote></div></div></blockquote></div></div>
</div></blockquote></div></div></blockquote></div>