[llvm] r208506 - DebugInfo: Include lexical scopes in inlined subroutines.
Alexey Samsonov
samsonov at google.com
Mon May 12 16:51:10 PDT 2014
Looks like this change breaks debug info under certain conditions. Here's a
reproducer (sorry, but I wasn't able to quickly generate one without gtest):
$ cat tmp/dbginfo/inl.cc
#include "gtest/gtest.h"
#include <stdio.h>
void test(char x) {
if (x)
printf("good\n");
}
TEST(Foo, foo) {
char *x = new char[8];
fprintf(stderr, "x: %p\n", x);
test(x[1]);
}
$ ./bin/clang++ -std=c++11 -O2 -gline-tables-only -D__STDC_LIMIT_MACROS
-D__STDC_CONSTANT_MACROS -I /llvm_build/include -I
/llvm/utils/unittest/googletest/include -I /llvm/include
/llvm_build/lib/libgtest_main.a llvm_build/lib/libgtest.a
/llvm_build/lib/libLLVMSupport.a
-lcurses -lpthread -ldl tmp/dbginfo/inl.cc
invocation of test() gets inlined in Foo_foo_Test::TestBody(). However,
there is no sign of DW_TAG_inlined_subroutine in the debug info:
$ readelf -wi a.out
<...>
<1><46>: Abbrev Number: 3 (DW_TAG_subprogram)
<47> DW_AT_name : (indirect string, offset: 0x83): TestBody
<4b> DW_AT_decl_file : 2
<4c> DW_AT_decl_line : 9
<4d> DW_AT_external : 1
<4d> DW_AT_accessibility: 1 (public)
<4e> DW_AT_low_pc : 0x457b50
<56> DW_AT_high_pc : 0x37
<5a> DW_AT_frame_base : 1 byte block: 57 (DW_OP_reg7 (rsp))
<5c> Unknown AT value: 3fe7: 1
<1><5c>: Abbrev Number: 4 (DW_TAG_subprogram)
<5d> DW_AT_name : (indirect string, offset: 0x8c): Setup
<...>
This happens both for "-g" and for "-gline-tables-only". Any idea why this
might happen?
On Sun, May 11, 2014 at 11:12 AM, David Blaikie <dblaikie at gmail.com> wrote:
> Author: dblaikie
> Date: Sun May 11 13:12:17 2014
> New Revision: 208506
>
> URL: http://llvm.org/viewvc/llvm-project?rev=208506&view=rev
> Log:
> DebugInfo: Include lexical scopes in inlined subroutines.
>
> Added:
> llvm/trunk/test/DebugInfo/inline-scopes.ll
> Modified:
> llvm/trunk/include/llvm/ADT/STLExtras.h
> llvm/trunk/include/llvm/CodeGen/LexicalScopes.h
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> llvm/trunk/lib/CodeGen/LexicalScopes.cpp
>
> Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=208506&r1=208505&r2=208506&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
> +++ llvm/trunk/include/llvm/ADT/STLExtras.h Sun May 11 13:12:17 2014
> @@ -530,6 +530,13 @@ make_unique(size_t n) {
>
> #endif
>
> +template<typename First, typename Second>
> +struct pair_hash {
> + size_t operator()(const std::pair<First, Second> &P) const {
> + return std::hash<First>()(P.first) * 31 +
> std::hash<Second>()(P.second);
> + }
> +};
> +
> } // End llvm namespace
>
> #endif
>
> Modified: llvm/trunk/include/llvm/CodeGen/LexicalScopes.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LexicalScopes.h?rev=208506&r1=208505&r2=208506&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/LexicalScopes.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/LexicalScopes.h Sun May 11 13:12:17
> 2014
> @@ -21,6 +21,7 @@
> #include "llvm/ADT/DenseMap.h"
> #include "llvm/ADT/SmallPtrSet.h"
> #include "llvm/ADT/SmallVector.h"
> +#include "llvm/ADT/STLExtras.h"
> #include "llvm/IR/DebugLoc.h"
> #include "llvm/IR/Metadata.h"
> #include "llvm/IR/ValueHandle.h"
> @@ -185,9 +186,7 @@ public:
>
> /// findInlinedScope - Find an inlined scope for the given DebugLoc or
> return
> /// NULL.
> - LexicalScope *findInlinedScope(DebugLoc DL) {
> - return InlinedLexicalScopeMap.lookup(DL);
> - }
> + LexicalScope *findInlinedScope(DebugLoc DL);
>
> /// findLexicalScope - Find regular lexical scope or return null.
> LexicalScope *findLexicalScope(const MDNode *N) {
> @@ -230,7 +229,9 @@ private:
>
> /// InlinedLexicalScopeMap - Tracks inlined function scopes in current
> /// function.
> - DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
> + std::unordered_map<std::pair<const MDNode *, const MDNode *>,
> LexicalScope,
> + pair_hash<const MDNode *, const MDNode *>>
> + InlinedLexicalScopeMap;
>
> /// AbstractScopeMap - These scopes are not included LexicalScopeMap.
> // Use an unordered_map to ensure value pointer validity over insertion.
>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=208506&r1=208505&r2=208506&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Sun May 11 13:12:17
> 2014
> @@ -621,7 +621,7 @@ std::unique_ptr<DIE> DwarfDebug::constru
> // avoid creating un-used children then removing them later when we
> find out
> // the scope DIE is null.
> std::unique_ptr<DIE> ScopeDIE;
> - if (Scope->getInlinedAt()) {
> + if (DS.getContext() && DS.isSubprogram()) {
> ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
> if (!ScopeDIE)
> return nullptr;
> @@ -1212,10 +1212,12 @@ DwarfDebug::collectVariableInfo(SmallPtr
> if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
> DISubprogram(DV.getContext()).describes(CurFn->getFunction()))
> Scope = LScopes.getCurrentFunctionScope();
> - else if (MDNode *IA = DV.getInlinedAt())
> - Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA));
> - else
> - Scope = LScopes.findLexicalScope(cast<MDNode>(DV->getOperand(1)));
> + else if (MDNode *IA = DV.getInlinedAt()) {
> + DebugLoc DL = DebugLoc::getFromDILocation(IA);
> + Scope = LScopes.findInlinedScope(DebugLoc::get(
> + DL.getLine(), DL.getCol(), DV.getContext(), IA));
> + } else
> + Scope = LScopes.findLexicalScope(DV.getContext());
> // If variable scope is not found then skip this variable.
> if (!Scope)
> continue;
>
> Modified: llvm/trunk/lib/CodeGen/LexicalScopes.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LexicalScopes.cpp?rev=208506&r1=208505&r2=208506&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/LexicalScopes.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LexicalScopes.cpp Sun May 11 13:12:17 2014
> @@ -104,6 +104,14 @@ void LexicalScopes::extractLexicalScopes
> }
> }
>
> +LexicalScope *LexicalScopes::findInlinedScope(DebugLoc DL) {
> + MDNode *Scope = nullptr;
> + MDNode *IA = nullptr;
> + DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
> + auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
> + return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
> +}
> +
> /// findLexicalScope - Find lexical scope, either regular or inlined, for
> the
> /// given DebugLoc. Return NULL if not found.
> LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
> @@ -119,8 +127,10 @@ LexicalScope *LexicalScopes::findLexical
> if (D.isLexicalBlockFile())
> Scope = DILexicalBlockFile(Scope).getScope();
>
> - if (IA)
> - return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
> + if (IA) {
> + auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
> + return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
> + }
> return findLexicalScope(Scope);
> }
>
> @@ -170,21 +180,27 @@ LexicalScope *LexicalScopes::getOrCreate
> }
>
> /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
> -LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
> +LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *ScopeNode,
> MDNode *InlinedAt) {
> - auto I = LexicalScopeMap.find(InlinedAt);
> - if (I != LexicalScopeMap.end())
> + std::pair<const MDNode*, const MDNode*> P(ScopeNode, InlinedAt);
> + auto I = InlinedLexicalScopeMap.find(P);
> + if (I != InlinedLexicalScopeMap.end())
> return &I->second;
>
> - DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
> + LexicalScope *Parent;
> + DILexicalBlock Scope(ScopeNode);
> + if (Scope.isLexicalBlock()) {
> + DILexicalBlock PB(Scope.getContext());
> + Parent = getOrCreateInlinedScope(PB, InlinedAt);
> + } else
> + Parent =
> getOrCreateLexicalScope(DebugLoc::getFromDILocation(InlinedAt));
> +
> // FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012
> // compatibility is no longer required.
> - I = LexicalScopeMap.emplace(
> - std::piecewise_construct,
> std::make_tuple(InlinedAt),
> -
> std::make_tuple(getOrCreateLexicalScope(InlinedLoc),
> - DIDescriptor(Scope), InlinedAt,
> - false)).first;
> - InlinedLexicalScopeMap[InlinedLoc] = &I->second;
> + I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
> + std::make_tuple(P),
> + std::make_tuple(Parent, Scope,
> InlinedAt,
> + false)).first;
> return &I->second;
> }
>
>
> Added: llvm/trunk/test/DebugInfo/inline-scopes.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/inline-scopes.ll?rev=208506&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/DebugInfo/inline-scopes.ll (added)
> +++ llvm/trunk/test/DebugInfo/inline-scopes.ll Sun May 11 13:12:17 2014
> @@ -0,0 +1,83 @@
> +; REQUIRES: object-emission
> +
> +; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump
> -debug-dump=info - | FileCheck %s
> +
> +; bool f1();
> +; inline __attribute__((always_inline))
> +; int f() {
> +; if (bool b = f1())
> +; return 1;
> +; return 2;
> +; }
> +;
> +; int main() {
> +; f();
> +; }
> +
> +; Ensure that lexical_blocks within inlined_subroutines are
> preserved/emitted.
> +; CHECK: DW_TAG_inlined_subroutine
> +; CHECK-NOT: DW_TAG
> +; CHECK: DW_TAG_lexical_block
> +; CHECK: DW_TAG_variable
> +
> +; Function Attrs: uwtable
> +define i32 @main() #0 {
> +entry:
> + %retval.i = alloca i32, align 4
> + %b.i = alloca i8, align 1
> + call void @llvm.dbg.declare(metadata !{i8* %b.i}, metadata !13), !dbg
> !16
> + %call.i = call zeroext i1 @_Z2f1v(), !dbg !16
> + %frombool.i = zext i1 %call.i to i8, !dbg !16
> + store i8 %frombool.i, i8* %b.i, align 1, !dbg !16
> + %0 = load i8* %b.i, align 1, !dbg !16
> + %tobool.i = trunc i8 %0 to i1, !dbg !16
> + br i1 %tobool.i, label %if.then.i, label %if.end.i, !dbg !16
> +
> +if.then.i: ; preds = %entry
> + store i32 1, i32* %retval.i, !dbg !18
> + br label %_Z1fv.exit, !dbg !18
> +
> +if.end.i: ; preds = %entry
> + store i32 2, i32* %retval.i, !dbg !19
> + br label %_Z1fv.exit, !dbg !19
> +
> +_Z1fv.exit: ; preds = %if.then.i,
> %if.end.i
> + %1 = load i32* %retval.i, !dbg !20
> + ret i32 0, !dbg !21
> +}
> +
> +; Function Attrs: nounwind readnone
> +declare void @llvm.dbg.declare(metadata, metadata) #1
> +
> +declare zeroext i1 @_Z2f1v() #2
> +
> +attributes #0 = { uwtable "less-precise-fpmad"="false"
> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
> "no-infs-fp-math"="false" "no-nans-fp-math"="false"
> "stack-protector-buffer-size"="8" "unsafe-fp-math"="false"
> "use-soft-float"="false" }
> +attributes #1 = { nounwind readnone }
> +attributes #2 = { "less-precise-fpmad"="false"
> "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"
> "no-infs-fp-math"="false" "no-nans-fp-math"="false"
> "stack-protector-buffer-size"="8" "unsafe-fp-math"="false"
> "use-soft-float"="false" }
> +
> +!llvm.dbg.cu = !{!0}
> +!llvm.module.flags = !{!10, !11}
> +!llvm.ident = !{!12}
> +
> +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version
> 3.5.0 ", i1 false, metadata !"", i32 0, metadata !2, metadata !2, metadata
> !3, metadata !2, metadata !2, metadata !"", i32 1} ; [ DW_TAG_compile_unit
> ] [/tmp/dbginfo/inline-scopes.cpp] [DW_LANG_C_plus_plus]
> +!1 = metadata !{metadata !"inline-scopes.cpp", metadata !"/tmp/dbginfo"}
> +!2 = metadata !{}
> +!3 = metadata !{metadata !4, metadata !9}
> +!4 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"main",
> metadata !"main", metadata !"", i32 9, metadata !6, i1 false, i1 true, i32
> 0, i32 0, null, i32 256, i1 false, i32 ()* @main, null, null, metadata !2,
> i32 9} ; [ DW_TAG_subprogram ] [line 9] [def] [main]
> +!5 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ]
> [/tmp/dbginfo/inline-scopes.cpp]
> +!6 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64
> 0, i64 0, i32 0, null, metadata !7, i32 0, null, null, null} ; [
> DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ]
> +!7 = metadata !{metadata !8}
> +!8 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32,
> i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32,
> align 32, offset 0, enc DW_ATE_signed]
> +!9 = metadata !{i32 786478, metadata !1, metadata !5, metadata !"f",
> metadata !"f", metadata !"_Z1fv", i32 3, metadata !6, i1 false, i1 true,
> i32 0, i32 0, null, i32 256, i1 false, null, null, null, metadata !2, i32
> 3} ; [ DW_TAG_subprogram ] [line 3] [def] [f]
> +!10 = metadata !{i32 2, metadata !"Dwarf Version", i32 4}
> +!11 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
> +!12 = metadata !{metadata !"clang version 3.5.0 "}
> +!13 = metadata !{i32 786688, metadata !14, metadata !"b", metadata !5,
> i32 4, metadata !15, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [b] [line 4]
> +!14 = metadata !{i32 786443, metadata !1, metadata !9, i32 4, i32 0, i32
> 0, i32 0} ; [ DW_TAG_lexical_block ] [/tmp/dbginfo/inline-scopes.cpp]
> +!15 = metadata !{i32 786468, null, null, metadata !"bool", i32 0, i64 8,
> i64 8, i64 0, i32 0, i32 2} ; [ DW_TAG_base_type ] [bool] [line 0, size 8,
> align 8, offset 0, enc DW_ATE_boolean]
> +!16 = metadata !{i32 4, i32 0, metadata !14, metadata !17}
> +!17 = metadata !{i32 10, i32 0, metadata !4, null}
> +!18 = metadata !{i32 5, i32 0, metadata !14, metadata !17}
> +!19 = metadata !{i32 6, i32 0, metadata !9, metadata !17}
> +!20 = metadata !{i32 7, i32 0, metadata !9, metadata !17}
> +!21 = metadata !{i32 11, i32 0, metadata !4, null}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Alexey Samsonov, Mountain View, CA
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140512/445e5172/attachment.html>
More information about the llvm-commits
mailing list