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