-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
llvm-pretty-bc-parser
inlines metadata nodes unnecessarily
#260
Comments
I briefly looked at this, and there appear to be two separate (but related) issues involved:
What both of these issues have in common is that both of these forms of metadata are parsed outside of It's not yet clear to me what the right way to fix this is. I think we will likely need to move some of the |
@peterohanley found another occurrence of this issue in #265 (comment): struct h {
bool a;
};
void g(struct h *s) {
}
void f() {
struct h s;
} When compiling directly with ; ModuleID = 'p2.cpp'
source_filename = "p2.cpp"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-gnu"
%struct.h = type { i8 }
; Function Attrs: mustprogress noinline nounwind optnone uwtable
define dso_local void @_Z1gP1h(%struct.h* noundef %0) #0 !dbg !10 {
%2 = alloca %struct.h*, align 8
store %struct.h* %0, %struct.h** %2, align 8
call void @llvm.dbg.declare(metadata %struct.h** %2, metadata !19, metadata !DIExpression()), !dbg !20
ret void, !dbg !21
}
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
; Function Attrs: mustprogress noinline nounwind optnone uwtable
define dso_local void @_Z1fv() #0 !dbg !22 {
%1 = alloca %struct.h, align 1
call void @llvm.dbg.declare(metadata %struct.h* %1, metadata !25, metadata !DIExpression()), !dbg !26
ret void, !dbg !27
}
attributes #0 = { mustprogress noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
!llvm.ident = !{!9}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "Ubuntu clang version 14.0.0-1ubuntu1.1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!1 = !DIFile(filename: "p2.cpp", directory: "/home/ryanscott/Documents/Hacking/Haskell/llvm-pretty-bc-parser", checksumkind: CSK_MD5, checksum: "3a886ebcac895e3acf83864f97430f6d")
!2 = !{i32 7, !"Dwarf Version", i32 5}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"PIC Level", i32 2}
!6 = !{i32 7, !"PIE Level", i32 2}
!7 = !{i32 7, !"uwtable", i32 1}
!8 = !{i32 7, !"frame-pointer", i32 2}
!9 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"}
!10 = distinct !DISubprogram(name: "g", linkageName: "_Z1gP1h", scope: !1, file: !1, line: 5, type: !11, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18)
!11 = !DISubroutineType(types: !12)
!12 = !{null, !13}
!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64)
!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "h", file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !15, identifier: "_ZTS1h")
!15 = !{!16}
!16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 2, baseType: !17, size: 8)
!17 = !DIBasicType(name: "bool", size: 8, encoding: DW_ATE_boolean)
!18 = !{}
!19 = !DILocalVariable(name: "s", arg: 1, scope: !10, file: !1, line: 5, type: !13)
!20 = !DILocation(line: 5, column: 18, scope: !10)
!21 = !DILocation(line: 6, column: 1, scope: !10)
!22 = distinct !DISubprogram(name: "f", linkageName: "_Z1fv", scope: !1, file: !1, line: 8, type: !23, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18)
!23 = !DISubroutineType(types: !24)
!24 = !{null}
!25 = !DILocalVariable(name: "s", scope: !22, file: !1, line: 9, type: !14)
!26 = !DILocation(line: 9, column: 12, scope: !22)
!27 = !DILocation(line: 10, column: 1, scope: !22) After round-tripping through source_filename = "p2.cpp"
target triple = "x86_64-pc-linux-gnu-"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
%struct.h = type { i8 }
declare default void @llvm.dbg.declare(metadata, metadata,
metadata)
define default void @_Z1gP1h(%struct.h* %0) !dbg !15 {
; <label>: 1
%2 = alloca %struct.h*, align 8
store %struct.h* %0, %struct.h** %2, align 8
call void @llvm.dbg.declare(metadata %struct.h** %2,
metadata !DILocalVariable(scope: !15, name: "s",
file: !DIFile(filename: "p2.cpp",
directory: "/home/ryanscott/Documents/Hacking/Haskell/llvm-pretty-bc-parser"),
line: 5, type: !16, arg: 1, flags: 0,
align: 0),
metadata !DIExpression()), !dbg !DILocation(line: 5, column: 18,
scope: !15)
ret void, !dbg !DILocation(line: 6, column: 1, scope: !15)
}
define default void @_Z1fv() !dbg !20 {
; <label>: 0
%1 = alloca %struct.h, align 1
call void @llvm.dbg.declare(metadata %struct.h* %1,
metadata !DILocalVariable(scope: !20, name: "s",
file: !DIFile(filename: "p2.cpp",
directory: "/home/ryanscott/Documents/Hacking/Haskell/llvm-pretty-bc-parser"),
line: 9,
type: !DICompositeType(tag: 19, name: "h",
file: !2, line: 1,
size: 8, align: 0,
offset: 0,
flags: 4194304,
elements: !13,
runtimeLang: 0,
identifier: "_ZTS1h"),
arg: 0, flags: 0, align: 0),
metadata !DIExpression()), !dbg !DILocation(line: 9, column: 12,
scope: !20)
ret void, !dbg !DILocation(line: 10, column: 1, scope: !20)
}
!llvm.dbg.cu = !{!0}
!llvm.ident = !{!10}
!llvm.module.flags = !{!3, !4, !5, !6, !7, !8, !9}
!0 =
distinct !DICompileUnit(language: 33, file: !2,
producer: "Ubuntu clang version 14.0.0-1ubuntu1.1",
isOptimized: false, flags: "", runtimeVersion: 0, emissionKind: 1,
dwoId: 0, splitDebugInlining: false, debugInfoForProfiling: false,
nameTableKind: 2)
!1 =
distinct !DICompositeType(tag: 19, name: "h", file: !2, line: 1,
size: 8, align: 0, offset: 0, flags: 4194304, elements: !13,
runtimeLang: 0, identifier: "_ZTS1h")
!2 =
!DIFile(filename: "p2.cpp",
directory: "/home/ryanscott/Documents/Hacking/Haskell/llvm-pretty-bc-parser")
!3 = !{i32 7, !"Dwarf Version", i32 5}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{i32 7, !"PIC Level", i32 2}
!7 = !{i32 7, !"PIE Level", i32 2}
!8 = !{i32 7, !"uwtable", i32 1}
!9 = !{i32 7, !"frame-pointer", i32 2}
!10 = !{!"Ubuntu clang version 14.0.0-1ubuntu1.1"}
!11 =
!DIBasicType(tag: 36, name: "bool", size: 8, align: 0,
encoding: 2, flags: 0)
!12 =
!DIDerivedType(tag: 13, name: "a", file: !2, line: 2, scope: !1,
baseType: !11, size: 8, align: 0, offset: 0, flags: 0)
!13 = !{!12}
!14 = !{}
!15 =
distinct !DISubprogram(scope: !2, name: "g",
linkageName: "_Z1gP1h", file: !2, line: 5, type: !18,
isLocal: false, isDefinition: true, scopeLine: 5, virtuality: 0,
virtualIndex: 0, flags: 256, isOptimized: false, unit: !0,
retainedNodes: !14)
!16 =
!DIDerivedType(tag: 15, line: 0, baseType: !1, size: 64, align: 0,
offset: 0, flags: 0)
!17 = !{null, !16}
!18 = distinct !DISubroutineType(flags: 0, types: !17)
!19 =
!DILocalVariable(scope: !15, name: "s", file: !2, line: 5,
type: !16, arg: 1, flags: 0, align: 0)
!20 =
distinct !DISubprogram(scope: !2, name: "f", linkageName: "_Z1fv",
file: !2, line: 8, type: !22, isLocal: false, isDefinition: true,
scopeLine: 8, virtuality: 0, virtualIndex: 0, flags: 256,
isOptimized: false, unit: !0, retainedNodes: !14)
!21 = !{null}
!22 = distinct !DISubroutineType(flags: 0, types: !21)
!23 =
!DILocalVariable(scope: !20, name: "s", file: !2, line: 9,
type: !1, arg: 0, flags: 0, align: 0) In the former define dso_local void @_Z1fv() #0 !dbg !22 {
%1 = alloca %struct.h, align 1
call void @llvm.dbg.declare(metadata %struct.h* %1, metadata !25, metadata !DIExpression()), !dbg !26
ret void, !dbg !27
}
!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "h", file: !1, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !15, identifier: "_ZTS1h")
!25 = !DILocalVariable(name: "s", scope: !22, file: !1, line: 9, type: !14) Note how In the latter define default void @_Z1fv() !dbg !20 {
; <label>: 0
%1 = alloca %struct.h, align 1
call void @llvm.dbg.declare(metadata %struct.h* %1,
metadata !DILocalVariable(scope: !20, name: "s",
file: !DIFile(filename: "p2.cpp",
directory: "/home/ryanscott/Documents/Hacking/Haskell/llvm-pretty-bc-parser"),
line: 9,
type: !DICompositeType(tag: 19, name: "h",
file: !2, line: 1,
size: 8, align: 0,
offset: 0,
flags: 4194304,
elements: !13,
runtimeLang: 0,
identifier: "_ZTS1h"),
arg: 0, flags: 0, align: 0),
metadata !DIExpression()), !dbg !DILocation(line: 9, column: 12,
scope: !20)
ret void, !dbg !DILocation(line: 10, column: 1, scope: !20)
}
!1 =
distinct !DICompositeType(tag: 19, name: "h", file: !2, line: 1,
size: 8, align: 0, offset: 0, flags: 4194304, elements: !13,
runtimeLang: 0, identifier: "_ZTS1h")
!23 =
!DILocalVariable(scope: !20, name: "s", file: !2, line: 9,
type: !1, arg: 0, flags: 0, align: 0) This time, This |
If you compile this program:
Like so:
Then this is what the resulting
test.ll
file will look like:So far, so good. Now let's see what happens when we round-trip this through
llvm-pretty-bc-parser
:The part that I want to draw attention to is the
call void @llvm.dbg.declare(...)
statement. In the originaltest.ll
file, we have this:But in the roundtripped code, we instead have this:
Note how instead of printing references to
!15
and!16
, the latter inlines the definitions of!15
and!16
entirely, resulting in much more verbose code.Although strange, this is not wrong in this example, since both versions of the program are equivalent. This is not always the case, however. If you repeat this experiment with the test case in #258 (using Clang 17), however, you will see this in the original
.ll
file:And this in the roundtripped version:
Note that we are now inlining the expression
metdata !DIAssignID
. This is invalid, as LLVM requires that allDIAssignID
nodes bedistinct
. This is the case in the original.ll
file, but the roundtripped version drops thedistinct
keyword after inlining. By that point, it is too late, as it is not possible to attach thedistinct
to inline metadata nodes—the only way to do so is by putting the node in the top-level list of metadata nodes (e.g.,!24
in the original.ll
file).In order to make the test case from #258 work, we will need to prevent
llvm-pretty-bc-parser
from performing this gratuitous inlining. This issue tracks that task.The text was updated successfully, but these errors were encountered: