llvm.org GIT mirror llvm / 8d3e87e
Merging r368230: ------------------------------------------------------------------------ r368230 | akhuang | 2019-08-08 00:49:40 +0200 (Thu, 08 Aug 2019) | 2 lines Recommit "[MS] Emit S_HEAPALLOCSITE debug info in Selection DAG" with a fix to clear the SDNode map when SelectionDAG is cleared. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_90@368571 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 2 months ago
5 changed file(s) with 138 addition(s) and 81 deletion(s). Raw diff Collapse all Expand all
268268
269269 using CallSiteInfo = MachineFunction::CallSiteInfo;
270270 using CallSiteInfoImpl = MachineFunction::CallSiteInfoImpl;
271 DenseMap SDCallSiteInfo;
271
272 struct CallSiteDbgInfo {
273 CallSiteInfo CSInfo;
274 MDNode *HeapAllocSite = nullptr;
275 };
276
277 DenseMap SDCallSiteDbgInfo;
272278
273279 uint16_t NextPersistentId = 0;
274280
16631669 }
16641670
16651671 void addCallSiteInfo(const SDNode *CallNode, CallSiteInfoImpl &&CallInfo) {
1666 SDCallSiteInfo[CallNode] = std::move(CallInfo);
1672 SDCallSiteDbgInfo[CallNode].CSInfo = std::move(CallInfo);
16671673 }
16681674
16691675 CallSiteInfo getSDCallSiteInfo(const SDNode *CallNode) {
1670 auto I = SDCallSiteInfo.find(CallNode);
1671 if (I != SDCallSiteInfo.end())
1672 return std::move(I->second);
1676 auto I = SDCallSiteDbgInfo.find(CallNode);
1677 if (I != SDCallSiteDbgInfo.end())
1678 return std::move(I->second).CSInfo;
16731679 return CallSiteInfo();
1680 }
1681
1682 void addHeapAllocSite(const SDNode *Node, MDNode *MD) {
1683 SDCallSiteDbgInfo[Node].HeapAllocSite = MD;
1684 }
1685
1686 /// Return the HeapAllocSite type associated with the SDNode, if it exists.
1687 MDNode *getHeapAllocSite(const SDNode *Node) {
1688 auto It = SDCallSiteDbgInfo.find(Node);
1689 if (It == SDCallSiteDbgInfo.end())
1690 return nullptr;
1691 return It->second.HeapAllocSite;
16741692 }
16751693
16761694 private:
908908 // Remember the source order of the inserted instruction.
909909 if (HasDbg)
910910 ProcessSourceNode(N, DAG, Emitter, VRBaseMap, Orders, Seen, NewInsn);
911
912 if (MDNode *MD = DAG->getHeapAllocSite(N)) {
913 if (NewInsn && NewInsn->isCall())
914 MF.addCodeViewHeapAllocSite(NewInsn, MD);
915 }
916
911917 GluedNodes.pop_back();
912918 }
913919 auto NewInsn =
916922 if (HasDbg)
917923 ProcessSourceNode(SU->getNode(), DAG, Emitter, VRBaseMap, Orders, Seen,
918924 NewInsn);
925 if (MDNode *MD = DAG->getHeapAllocSite(SU->getNode())) {
926 if (NewInsn && NewInsn->isCall())
927 MF.addCodeViewHeapAllocSite(NewInsn, MD);
928 }
919929 }
920930
921931 // Insert all the dbg_values which have not already been inserted in source
10831083 ExternalSymbols.clear();
10841084 TargetExternalSymbols.clear();
10851085 MCSymbols.clear();
1086 SDCallSiteDbgInfo.clear();
10861087 std::fill(CondCodeNodes.begin(), CondCodeNodes.end(),
10871088 static_cast(nullptr));
10881089 std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(),
40674067 }
40684068 InFlag = Chain.getValue(1);
40694069 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));
4070
4071 // Save heapallocsite metadata.
4072 if (CLI.CS)
4073 if (MDNode *HeapAlloc = CLI.CS->getMetadata("heapallocsite"))
4074 DAG.addHeapAllocSite(Chain.getNode(), HeapAlloc);
40704075
40714076 // Create the CALLSEQ_END node.
40724077 unsigned NumBytesForCalleeToPop;
None ; RUN: llc -O0 < %s | FileCheck %s
1 ; FIXME: Add test for llc with optimizations once it is implemented.
0 ; RUN: llc < %s | FileCheck --check-prefixes=DAG,CHECK %s
1 ; RUN: llc -O0 < %s | FileCheck --check-prefixes=FAST,CHECK %s
22
33 ; Source to regenerate:
4 ; $ clang --target=x86_64-windows-msvc -S heapallocsite.cpp -g -gcodeview -o t.ll \
5 ; -emit-llvm -O0 -Xclang -disable-llvm-passes -fms-extensions
4 ; $ clang -cc1 -triple x86_64-windows-msvc t.cpp -debug-info-kind=limited \
5 ; -gcodeview -O2 -fms-extensions -emit-llvm -o t.ll
66 ;
7 ; struct Foo {
7 ; extern "C" struct Foo {
88 ; __declspec(allocator) virtual void *alloc();
99 ; };
10 ;
1110 ; extern "C" __declspec(allocator) Foo *alloc_foo();
12 ;
13 ; extern "C" void use_alloc(void*);
14 ; extern "C" void call_virtual(Foo *p) {
15 ; use_alloc(p->alloc());
11 ; extern "C" void use_result(void *);
12 ; extern "C" Foo *call_tail() {
13 ; return alloc_foo();
1614 ; }
17 ;
18 ; extern "C" void call_multiple() {
19 ; use_alloc(alloc_foo());
20 ; use_alloc(alloc_foo());
15 ; extern "C" int call_virtual(Foo *p) {
16 ; use_result(p->alloc());
17 ; return 0;
18 ; }
19 ; extern "C" int call_multiple() {
20 ; use_result(alloc_foo());
21 ; use_result(alloc_foo());
22 ; return 0;
2123 ; }
2224
25 ; ModuleID = 't.cpp'
26 source_filename = "t.cpp"
2327 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2428 target triple = "x86_64-unknown-windows-msvc"
2529
2630 %struct.Foo = type { i32 (...)** }
2731
28 ; Function Attrs: noinline optnone uwtable
29 define dso_local void @call_virtual(%struct.Foo* %p) #0 !dbg !8 {
32 ; Function Attrs: nounwind
33 define dso_local %struct.Foo* @call_tail() local_unnamed_addr #0 !dbg !7 {
3034 entry:
31 %p.addr = alloca %struct.Foo*, align 8
32 store %struct.Foo* %p, %struct.Foo** %p.addr, align 8
33 call void @llvm.dbg.declare(metadata %struct.Foo** %p.addr, metadata !13, metadata !DIExpression()), !dbg !14
34 %0 = load %struct.Foo*, %struct.Foo** %p.addr, align 8, !dbg !15
35 %1 = bitcast %struct.Foo* %0 to i8* (%struct.Foo*)***, !dbg !15
36 %vtable = load i8* (%struct.Foo*)**, i8* (%struct.Foo*)*** %1, align 8, !dbg !15
37 %vfn = getelementptr inbounds i8* (%struct.Foo*)*, i8* (%struct.Foo*)** %vtable, i64 0, !dbg !15
38 %2 = load i8* (%struct.Foo*)*, i8* (%struct.Foo*)** %vfn, align 8, !dbg !15
39 %call = call i8* %2(%struct.Foo* %0), !dbg !15, !heapallocsite !2
40 call void @use_alloc(i8* %call), !dbg !15
41 ret void, !dbg !16
35 %call = tail call %struct.Foo* @alloc_foo() #3, !dbg !13, !heapallocsite !12
36 ret %struct.Foo* %call, !dbg !13
4237 }
4338
44 ; Function Attrs: nounwind readnone speculatable
45 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
39 declare dso_local %struct.Foo* @alloc_foo() local_unnamed_addr #1
4640
47 declare dso_local void @use_alloc(i8*) #2
48
49 ; Function Attrs: noinline optnone uwtable
50 define dso_local void @call_multiple() #0 !dbg !17 {
41 ; Function Attrs: nounwind
42 define dso_local i32 @call_virtual(%struct.Foo* %p) local_unnamed_addr #0 !dbg !14 {
5143 entry:
52 %call = call %struct.Foo* @alloc_foo(), !dbg !20, !heapallocsite !12
53 %0 = bitcast %struct.Foo* %call to i8*, !dbg !20
54 call void @use_alloc(i8* %0), !dbg !20
55 %call1 = call %struct.Foo* @alloc_foo(), !dbg !21, !heapallocsite !12
56 %1 = bitcast %struct.Foo* %call1 to i8*, !dbg !21
57 call void @use_alloc(i8* %1), !dbg !21
58 ret void, !dbg !22
44 call void @llvm.dbg.value(metadata %struct.Foo* %p, metadata !19, metadata !DIExpression()), !dbg !20
45 %0 = bitcast %struct.Foo* %p to i8* (%struct.Foo*)***, !dbg !21
46 %vtable = load i8* (%struct.Foo*)**, i8* (%struct.Foo*)*** %0, align 8, !dbg !21, !tbaa !22
47 %1 = load i8* (%struct.Foo*)*, i8* (%struct.Foo*)** %vtable, align 8, !dbg !21
48 %call = tail call i8* %1(%struct.Foo* %p) #3, !dbg !21, !heapallocsite !2
49 tail call void @use_result(i8* %call) #3, !dbg !21
50 ret i32 0, !dbg !25
5951 }
6052
61 declare dso_local %struct.Foo* @alloc_foo() #2
53 declare dso_local void @use_result(i8*) local_unnamed_addr #1
6254
63 ; CHECK-LABEL: call_virtual: # @call_virtual
55 ; Function Attrs: nounwind
56 define dso_local i32 @call_multiple() local_unnamed_addr #0 !dbg !26 {
57 entry:
58 %call = tail call %struct.Foo* @alloc_foo() #3, !dbg !29, !heapallocsite !12
59 %0 = bitcast %struct.Foo* %call to i8*, !dbg !29
60 tail call void @use_result(i8* %0) #3, !dbg !29
61 %call1 = tail call %struct.Foo* @alloc_foo() #3, !dbg !30, !heapallocsite !12
62 %1 = bitcast %struct.Foo* %call1 to i8*, !dbg !30
63 tail call void @use_result(i8* %1) #3, !dbg !30
64 ret i32 0, !dbg !31
65 }
66
67 ; Function Attrs: nounwind readnone speculatable willreturn
68 declare void @llvm.dbg.value(metadata, metadata, metadata) #2
69
70
71 ; Don't emit metadata for tail calls.
72 ; CHECK-LABEL: call_tail: # @call_tail
73 ; CHECK-NOT: .Lheapallocsite
74 ; CHECK: jmp alloc_foo
75
76 ; CHECK-LABEL: call_virtual: # @call_virtual
6477 ; CHECK: .Lheapallocsite0:
65 ; CHECK: callq *(%rax)
78 ; CHECK: callq *{{.*}}%rax{{.*}}
6679 ; CHECK: .Lheapallocsite1:
67 ; CHECK: retq
6880
69 ; CHECK-LABEL: call_multiple: # @call_multiple
70 ; CHECK: .Lheapallocsite4:
81 ; CHECK-LABEL: call_multiple: # @call_multiple
82 ; FastISel emits instructions in a different order.
83 ; DAG: .Lheapallocsite2:
84 ; FAST: .Lheapallocsite4:
7185 ; CHECK: callq alloc_foo
72 ; CHECK: .Lheapallocsite5:
73 ; CHECK: .Lheapallocsite2:
86 ; DAG: .Lheapallocsite3:
87 ; FAST: .Lheapallocsite5:
88 ; DAG: .Lheapallocsite4:
89 ; FAST: .Lheapallocsite2:
7490 ; CHECK: callq alloc_foo
75 ; CHECK: .Lheapallocsite3:
76 ; CHECK: retq
91 ; DAG: .Lheapallocsite5:
92 ; FAST: .Lheapallocsite3:
7793
7894 ; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
7995 ; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
8197 ; CHECK-NEXT: .secidx .Lheapallocsite0
8298 ; CHECK-NEXT: .short .Lheapallocsite1-.Lheapallocsite0
8399 ; CHECK-NEXT: .long 3
84 ; CHECK-NEXT: .p2align 2
85 ; CHECK-LABEL: .short 4431 # Record kind: S_PROC_ID_END
86
87 ; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
88100 ; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
89101 ; CHECK-NEXT: .secrel32 .Lheapallocsite2
90102 ; CHECK-NEXT: .secidx .Lheapallocsite2
91103 ; CHECK-NEXT: .short .Lheapallocsite3-.Lheapallocsite2
92104 ; CHECK-NEXT: .long 4096
93 ; CHECK-NEXT: .p2align 2
94
95105 ; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
96106 ; CHECK-NEXT: .secrel32 .Lheapallocsite4
97107 ; CHECK-NEXT: .secidx .Lheapallocsite4
98108 ; CHECK-NEXT: .short .Lheapallocsite5-.Lheapallocsite4
99109 ; CHECK-NEXT: .long 4096
100 ; CHECK-NEXT: .p2align 2
101 ; CHECK-LABEL: .short 4431 # Record kind: S_PROC_ID_END
110
111 attributes #0 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
112 attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
113 attributes #2 = { nounwind readnone speculatable willreturn }
114 attributes #3 = { nounwind }
102115
103116 !llvm.dbg.cu = !{!0}
104 !llvm.module.flags = !{!3, !4, !5, !6}
105 !llvm.ident = !{!7}
117 !llvm.module.flags = !{!3, !4, !5}
118 !llvm.ident = !{!6}
106119
107 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 9.0.0 (https://github.com/llvm/llvm-project.git 9c8073f44f786fbf47335e53f20abe64429e8e47)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)!1 = !DIFile(filename: "filename", directory: "directory", checksumkind: CSK_MD5, checksum: "096443b661a0af36da9006330c08f97e")
120 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 10.0.0 (https://github.com/llvm/llvm-project.git fa686ea7650235c6dff988cc8cba49e130b3d5f8)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
121 !1 = !DIFile(filename: "", directory: "/usr/local/google/home/akhuang/testing/heapallocsite", checksumkind: CSK_MD5, checksum: "e0a04508b4229fc4aee0baa364e25987")
108122 !2 = !{}
109123 !3 = !{i32 2, !"CodeView", i32 1}
110124 !4 = !{i32 2, !"Debug Info Version", i32 3}
111125 !5 = !{i32 1, !"wchar_size", i32 2}
112 !6 = !{i32 7, !"PIC Level", i32 2}
113 !7 = !{!"clang version 9.0.0 (https://github.com/llvm/llvm-project.git 9c8073f44f786fbf47335e53f20abe64429e8e47)"}
114 !8 = distinct !DISubprogram(name: "call_virtual", scope: !1, file: !1, line: 8, type: !9, scopeLine: 8, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
126 !6 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project.git fa686ea7650235c6dff988cc8cba49e130b3d5f8)"}
127 !7 = distinct !DISubprogram(name: "call_tail", scope: !8, file: !8, line: 6, type: !9, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
128 !8 = !DIFile(filename: "t.cpp", directory: "/usr/local/google/home/akhuang/testing/heapallocsite", checksumkind: CSK_MD5, checksum: "e0a04508b4229fc4aee0baa364e25987")
115129 !9 = !DISubroutineType(types: !10)
116 !10 = !{null, !11}
130 !10 = !{!11}
117131 !11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
118 !12 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !1, line: 1, flags: DIFlagFwdDecl, identifier: ".?AUFoo@@")
119 !13 = !DILocalVariable(name: "p", arg: 1, scope: !8, file: !1, line: 8, type: !11)
120 !14 = !DILocation(line: 8, scope: !8)
121 !15 = !DILocation(line: 9, scope: !8)
122 !16 = !DILocation(line: 10, scope: !8)
123 !17 = distinct !DISubprogram(name: "call_multiple", scope: !1, file: !1, line: 12, type: !18, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
124 !18 = !DISubroutineType(types: !19)
125 !19 = !{null}
126 !20 = !DILocation(line: 13, scope: !17)
127 !21 = !DILocation(line: 14, scope: !17)
128 !22 = !DILocation(line: 15, scope: !17)
132 !12 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !8, line: 1, flags: DIFlagFwdDecl, identifier: ".?AUFoo@@")
133 !13 = !DILocation(line: 7, scope: !7)
134 !14 = distinct !DISubprogram(name: "call_virtual", scope: !8, file: !8, line: 9, type: !15, scopeLine: 9, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !18)
135 !15 = !DISubroutineType(types: !16)
136 !16 = !{!17, !11}
137 !17 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
138 !18 = !{!19}
139 !19 = !DILocalVariable(name: "p", arg: 1, scope: !14, file: !8, line: 9, type: !11)
140 !20 = !DILocation(line: 0, scope: !14)
141 !21 = !DILocation(line: 10, scope: !14)
142 !22 = !{!23, !23, i64 0}
143 !23 = !{!"vtable pointer", !24, i64 0}
144 !24 = !{!"Simple C++ TBAA"}
145 !25 = !DILocation(line: 11, scope: !14)
146 !26 = distinct !DISubprogram(name: "call_multiple", scope: !8, file: !8, line: 13, type: !27, scopeLine: 13, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
147 !27 = !DISubroutineType(types: !28)
148 !28 = !{!17}
149 !29 = !DILocation(line: 14, scope: !26)
150 !30 = !DILocation(line: 15, scope: !26)
151 !31 = !DILocation(line: 16, scope: !26)