[pkg-d-commits] [ldc] 211/211: Put debuginfo on GEP instead of on the alloca with an offset. (#1984)

Matthias Klumpp mak at moszumanska.debian.org
Sun Apr 23 22:36:24 UTC 2017


This is an automated email from the git hooks/post-receive script.

mak pushed a commit to annotated tag v1.1.0
in repository ldc.

commit 11d75f3f018f1076d810a0360a49eca45a09fc8b
Author: kinke <kinke at users.noreply.github.com>
Date:   Wed Jan 25 00:36:00 2017 +0100

    Put debuginfo on GEP instead of on the alloca with an offset. (#1984)
    
    For nested variables. Resolves issue #1933 at the expense of a debuginfo
    regression wrt. captured this pointer, see PR #1963.
    
    Also add DWARF deref for non-ref/out variables captured by reference.
---
 gen/dibuilder.cpp                |  2 +-
 gen/nested.cpp                   | 46 +++++++++++++---------------
 tests/compilable/gh1933.d        | 66 ++++++++++++++++++++++++++++++++++++++++
 tests/debuginfo/nested.d         |  7 ++++-
 tests/debuginfo/nested_llvm306.d |  7 ++++-
 tests/debuginfo/nested_llvm307.d |  7 ++++-
 6 files changed, 106 insertions(+), 29 deletions(-)

diff --git a/gen/dibuilder.cpp b/gen/dibuilder.cpp
index a105b50..f7bdcdd 100644
--- a/gen/dibuilder.cpp
+++ b/gen/dibuilder.cpp
@@ -1089,7 +1089,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
   if (static_cast<llvm::MDNode *>(TD) == nullptr)
     return; // unsupported
 
-  if (vd->storage_class & (STCref | STCout)) {
+  if (vd->isRef() || vd->isOut()) {
 #if LDC_LLVM_VER >= 308
     auto T = DtoType(type);
     TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD,
diff --git a/gen/nested.cpp b/gen/nested.cpp
index a15c979..d791447 100644
--- a/gen/nested.cpp
+++ b/gen/nested.cpp
@@ -56,20 +56,13 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
     return makeVarDValue(astype, vd);
   }
 
-  LLValue *dwarfValue = nullptr;
-#if LDC_LLVM_VER >= 306
-  std::vector<int64_t> dwarfAddr;
-#else
-  std::vector<LLValue *> dwarfAddr;
-#endif
-
   // get the nested context
   LLValue *ctx = nullptr;
+  bool skipDIDeclaration = false;
   auto currentCtx = gIR->funcGen().nestedVar;
   if (currentCtx) {
     Logger::println("Using own nested context of current function");
     ctx = currentCtx;
-    dwarfValue = currentCtx;
   } else if (irfunc->decl->isMember2()) {
     Logger::println(
         "Current function is member of nested class, loading vthis");
@@ -80,14 +73,11 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
       val = DtoLoad(val);
     }
     ctx = DtoLoad(DtoGEPi(val, 0, getVthisIdx(cd), ".vthis"));
+    skipDIDeclaration = true;
   } else {
     Logger::println("Regular nested function, loading context arg");
 
     ctx = DtoLoad(irfunc->nestArg);
-    dwarfValue = irfunc->nestArg;
-    if (global.params.symdebug) {
-      gIR->DBuilder.OpDeref(dwarfAddr);
-    }
   }
 
   assert(ctx);
@@ -120,10 +110,6 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
     IF_LOG Logger::println("Same depth");
   } else {
     // Load frame pointer and index that...
-    if (dwarfValue && global.params.symdebug) {
-      gIR->DBuilder.OpOffset(dwarfAddr, val, vardepth);
-      gIR->DBuilder.OpDeref(dwarfAddr);
-    }
     IF_LOG Logger::println("Lower depth");
     val = DtoGEPi(val, 0, vardepth);
     IF_LOG Logger::cout() << "Frame index: " << *val << '\n';
@@ -135,27 +121,37 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
   const auto idx = irLocal->nestedIndex;
   assert(idx != -1 && "Nested context not yet resolved for variable.");
 
-  if (dwarfValue && global.params.symdebug) {
-    gIR->DBuilder.OpOffset(dwarfAddr, val, idx);
-  }
+#if LDC_LLVM_VER >= 306
+    LLSmallVector<int64_t, 2> dwarfAddrOps;
+#else
+    LLSmallVector<LLValue *, 2> dwarfAddrOps;
+#endif
 
-  val = DtoGEPi(val, 0, idx, vd->toChars());
+  LLValue *gep = DtoGEPi(val, 0, idx, vd->toChars());
+  val = gep;
   IF_LOG {
     Logger::cout() << "Addr: " << *val << '\n';
     Logger::cout() << "of type: " << *val->getType() << '\n';
   }
-  if (!isSpecialRefVar(vd) && (byref || vd->isRef() || vd->isOut())) {
+  const bool isRefOrOut = vd->isRef() || vd->isOut();
+  if (!isSpecialRefVar(vd) && (byref || isRefOrOut)) {
     val = DtoAlignedLoad(val);
-    // dwarfOpDeref(dwarfAddr);
+    // ref/out variables get a reference-debuginfo-type in
+    // DIBuilder::EmitLocalVariable()
+    if (!isRefOrOut)
+      gIR->DBuilder.OpDeref(dwarfAddrOps);
     IF_LOG {
       Logger::cout() << "Was byref, now: " << *irLocal->value << '\n';
       Logger::cout() << "of type: " << *irLocal->value->getType() << '\n';
     }
   }
 
-  if (dwarfValue && global.params.symdebug) {
-    gIR->DBuilder.EmitLocalVariable(dwarfValue, vd, nullptr, false, true,
-                                    dwarfAddr);
+  if (!skipDIDeclaration && global.params.symdebug) {
+    // Because we are passing a GEP instead of an alloca to
+    // llvm.dbg.declare, we have to make the address dereference explicit.
+    gIR->DBuilder.OpDeref(dwarfAddrOps);
+    gIR->DBuilder.EmitLocalVariable(gep, vd, nullptr, false, true,
+                                    dwarfAddrOps);
   }
 
   return makeVarDValue(astype, vd, val);
diff --git a/tests/compilable/gh1933.d b/tests/compilable/gh1933.d
new file mode 100644
index 0000000..9d4069c
--- /dev/null
+++ b/tests/compilable/gh1933.d
@@ -0,0 +1,66 @@
+// See Github issue 1933.
+
+// RUN: %ldc -c -release -g -O0 %s
+// RUN: %ldc -c -release -g -O3 %s
+
+ptrdiff_t countUntil(T, N)(T haystack, N needle)
+{
+    ptrdiff_t result;
+    foreach (elem; haystack) {
+        if (elem == needle)
+            return result;
+        result++;
+    }
+    return -1;
+}
+
+bool foo(alias pred, N)(N haystack)
+{
+    foreach (elem; haystack) {
+        if (pred(elem))
+            return true;
+    }
+    return false;
+}
+
+struct MatchTree
+{
+    struct Tag
+    {
+    }
+
+    struct Terminal
+    {
+        string[] varNames;
+    }
+
+    Tag[] m_terminalTags;
+    Terminal term;
+
+    void rebuildGraph()
+    {
+
+        MatchGraphBuilder builder;
+        uint process()
+        {
+            auto aaa = m_terminalTags.length;
+            foreach (t; builder.m_nodes)
+            {
+                auto bbb = term.varNames.countUntil(t.var);
+                assert(m_terminalTags.foo!(u => t.index));
+            }
+            return 0;
+        }
+    }
+}
+
+struct MatchGraphBuilder
+{
+    struct TerminalTag
+    {
+        size_t index;
+        string var;
+    }
+
+    TerminalTag[] m_nodes;
+}
diff --git a/tests/debuginfo/nested.d b/tests/debuginfo/nested.d
index 92cf171..3d2dc81 100644
--- a/tests/debuginfo/nested.d
+++ b/tests/debuginfo/nested.d
@@ -12,7 +12,12 @@ void encloser(int arg0, int arg1)
     // CHECK-LABEL: define {{.*}}encloser{{.*}}nested
     void nested(int nes_i)
     {
-        // CHECK: @llvm.dbg.declare{{.*}}%nestedFrame{{.*}}arg1
+        // CHECK: %arg0 = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%arg0
+        // CHECK: %arg1 = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%arg1
+        // CHECK: %enc_n = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%enc_n
         arg0 = arg1 = enc_n = nes_i; // accessing arg0, arg1 and enc_n from a nested function turns them into closure variables
 
         // nes_i and arg1 have the same parameter index in the generated IR, if both get declared as
diff --git a/tests/debuginfo/nested_llvm306.d b/tests/debuginfo/nested_llvm306.d
index f98ff9e..ce6de5b 100644
--- a/tests/debuginfo/nested_llvm306.d
+++ b/tests/debuginfo/nested_llvm306.d
@@ -11,7 +11,12 @@ void encloser(int arg0, int arg1)
     // CHECK-LABEL: define {{.*}} @_D{{.*}}encloser{{.*}}nested
     void nested(int nes_i)
     {
-        // CHECK: @llvm.dbg.declare{{.*}}%nestedFrame{{.*}}arg1
+        // CHECK: %arg0 = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%arg0
+        // CHECK: %arg1 = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%arg1
+        // CHECK: %enc_n = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%enc_n
         arg0 = arg1 = enc_n = nes_i; // accessing arg0, arg1 and enc_n from a nested function turns them into closure variables
     }
 }
diff --git a/tests/debuginfo/nested_llvm307.d b/tests/debuginfo/nested_llvm307.d
index 5c39898..ab49385 100644
--- a/tests/debuginfo/nested_llvm307.d
+++ b/tests/debuginfo/nested_llvm307.d
@@ -11,7 +11,12 @@ void encloser(int arg0, int arg1)
     // CHECK-LABEL: define {{.*}} @_D{{.*}}8encloser{{.*}}nested
     void nested(int nes_i)
     {
-        // CHECK: @llvm.dbg.declare{{.*}}%nestedFrame{{.*}}arg1
+        // CHECK: %arg0 = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%arg0
+        // CHECK: %arg1 = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%arg1
+        // CHECK: %enc_n = getelementptr inbounds %nest.encloser
+        // CHECK: @llvm.dbg.declare{{.*}}%enc_n
         arg0 = arg1 = enc_n = nes_i; // accessing arg0, arg1 and enc_n from a nested function turns them into closure variables
     }
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git



More information about the pkg-d-commits mailing list