[pkg-d-commits] [ldc] 51/149: 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:56 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.2.0
in repository ldc.
commit 89e5d274150d01d26273388d467a61b362db6ae8
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 6ca50eb..15d4c2e 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