llvm.org GIT mirror llvm / ec039c8
Recommitting r358783 and r358786 "[MS] Emit S_HEAPALLOCSITE debug info" with fixes for buildbot error (undefined assembler label). Summary: This emits labels around heapallocsite calls and S_HEAPALLOCSITE debug info in codeview. Currently only changes FastISel, so emitting labels still needs to be implemented in SelectionDAG. Reviewers: rnk Subscribers: aprantl, hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D61083 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359149 91177308-0d34-0410-b5e6-96231b3b80d8 Amy Huang 1 year, 4 months ago
9 changed file(s) with 182 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
320320 /// CodeView label annotations.
321321 std::vector> CodeViewAnnotations;
322322
323 /// CodeView heapallocsites.
324 std::vector>
325 CodeViewHeapAllocSites;
326
323327 bool CallsEHReturn = false;
324328 bool CallsUnwindInit = false;
325329 bool HasEHScopes = false;
904908 return CodeViewAnnotations;
905909 }
906910
911 /// Record heapallocsites
912 void addCodeViewHeapAllocSite(MachineInstr *I, MDNode *MD);
913
914 ArrayRef>
915 getCodeViewHeapAllocSites() const {
916 return CodeViewHeapAllocSites;
917 }
918
907919 /// Return a reference to the C++ typeinfo for the current function.
908920 const std::vector &getTypeInfos() const {
909921 return TypeInfos;
15471547 /// FIXME: This is not fully implemented yet.
15481548 void setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol);
15491549
1550 /// Clone another MachineInstr's pre- and post- instruction symbols and
1551 /// replace ours with it.
1552 void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI);
1553
15501554 /// Return the MIFlags which represent both MachineInstrs. This
15511555 /// should be used when merging two MachineInstrs into one. This routine does
15521556 /// not modify the MIFlags of this MachineInstr.
10711071 endSymbolRecord(AnnotEnd);
10721072 }
10731073
1074 for (auto HeapAllocSite : FI.HeapAllocSites) {
1075 MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
1076 MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
1077
1078 // The labels might not be defined if the instruction was replaced
1079 // somewhere in the codegen pipeline.
1080 if (!BeginLabel->isDefined() || !EndLabel->isDefined())
1081 continue;
1082
1083 DIType *DITy = std::get<2>(HeapAllocSite);
1084 MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
1085 OS.AddComment("Call site offset");
1086 OS.EmitCOFFSecRel32(BeginLabel, /*Offset=*/0);
1087 OS.AddComment("Call site section index");
1088 OS.EmitCOFFSectionIndex(BeginLabel);
1089 OS.AddComment("Call instruction length");
1090 OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
1091 OS.AddComment("Type index");
1092 OS.EmitIntValue(getCompleteTypeIndex(DITy).getIndex(), 4);
1093 endSymbolRecord(HeapAllocEnd);
1094 }
1095
10741096 if (SP != nullptr)
10751097 emitDebugInfoForUDTs(LocalUDTs);
10761098
28062828 }
28072829
28082830 CurFn->Annotations = MF->getCodeViewAnnotations();
2831 CurFn->HeapAllocSites = MF->getCodeViewHeapAllocSites();
28092832
28102833 CurFn->End = Asm->getFunctionEnd();
28112834
146146 SmallVector ChildBlocks;
147147
148148 std::vector> Annotations;
149 std::vector> HeapAllocSites;
149150
150151 const MCSymbol *Begin = nullptr;
151152 const MCSymbol *End = nullptr;
4242 #include "llvm/IR/BasicBlock.h"
4343 #include "llvm/IR/Constant.h"
4444 #include "llvm/IR/DataLayout.h"
45 #include "llvm/IR/DebugInfoMetadata.h"
4546 #include "llvm/IR/DerivedTypes.h"
4647 #include "llvm/IR/Function.h"
4748 #include "llvm/IR/GlobalValue.h"
805806 return FilterID;
806807 }
807808
809 void MachineFunction::addCodeViewHeapAllocSite(MachineInstr *I, MDNode *MD) {
810 MCSymbol *BeginLabel = Ctx.createTempSymbol("heapallocsite", true);
811 MCSymbol *EndLabel = Ctx.createTempSymbol("heapallocsite", true);
812 I->setPreInstrSymbol(*this, BeginLabel);
813 I->setPostInstrSymbol(*this, EndLabel);
814
815 DIType *DI = dyn_cast(MD);
816 CodeViewHeapAllocSites.push_back(std::make_tuple(BeginLabel, EndLabel, DI));
817 }
818
808819 /// \}
809820
810821 //===----------------------------------------------------------------------===//
512512 MF.createMIExtraInfo(memoperands(), getPreInstrSymbol(), Symbol));
513513 }
514514
515 void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
516 const MachineInstr &MI) {
517 if (this == &MI)
518 // Nothing to do for a self-clone!
519 return;
520
521 assert(&MF == MI.getMF() &&
522 "Invalid machine functions when cloning instruction symbols!");
523
524 setPreInstrSymbol(MF, MI.getPreInstrSymbol());
525 setPostInstrSymbol(MF, MI.getPostInstrSymbol());
526 }
527
515528 uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
516529 // For now, the just return the union of the flags. If the flags get more
517530 // complicated over time, we might need more logic here.
12331233 if (CLI.NumResultRegs && CLI.CS)
12341234 updateValueMap(CLI.CS->getInstruction(), CLI.ResultReg, CLI.NumResultRegs);
12351235
1236 // Set labels for heapallocsite call.
1237 if (CLI.CS && CLI.CS->getInstruction()->getMetadata("heapallocsite")) {
1238 MDNode *MD = CLI.CS->getInstruction()->getMetadata("heapallocsite");
1239 MF->addCodeViewHeapAllocSite(CLI.Call, MD);
1240 }
1241
12361242 return true;
12371243 }
12381244
39843984 }
39853985
39863986 Result->addMemOperand(*FuncInfo.MF, createMachineMemOperandFor(LI));
3987 Result->cloneInstrSymbols(*FuncInfo.MF, *MI);
39873988 MachineBasicBlock::iterator I(MI);
39883989 removeDeadCode(I, std::next(I));
39893990 return true;
0 ; RUN: llc -O0 < %s | FileCheck %s
1 ; FIXME: Add test for llc with optimizations once it is implemented.
2
3 ; Source to regenerate:
4 ; $ clang --target=x86_64-windows-msvc -S heapallocsite.c -g -gcodeview -o t.ll \
5 ; -emit-llvm -O0 -Xclang -disable-llvm-passes -fms-extensions
6 ; __declspec(allocator) char *myalloc(void);
7 ; void f() {
8 ; myalloc()
9 ; }
10 ;
11 ; struct Foo {
12 ; __declspec(allocator) virtual void *alloc();
13 ; };
14 ; void use_alloc(void*);
15 ; void do_alloc(Foo *p) {
16 ; use_alloc(p->alloc());
17 ; }
18
19 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
20 target triple = "x86_64-unknown-windows-msvc"
21
22 %struct.Foo = type { i32 (...)** }
23
24 ; Function Attrs: noinline optnone uwtable
25 define dso_local void @f() #0 !dbg !8 {
26 entry:
27 %call = call i8* @myalloc(), !dbg !11, !heapallocsite !2
28 ret void, !dbg !12
29 }
30
31 ; CHECK-LABEL: f: # @f
32 ; CHECK: .Lheapallocsite0:
33 ; CHECK: callq myalloc
34 ; CHECK: .Lheapallocsite1:
35 ; CHECK: retq
36
37 declare dso_local i8* @myalloc() #1
38
39 ; Function Attrs: noinline optnone uwtable
40 define dso_local void @do_alloc(%struct.Foo* %p) #0 !dbg !13 {
41 entry:
42 %p.addr = alloca %struct.Foo*, align 8
43 store %struct.Foo* %p, %struct.Foo** %p.addr, align 8
44 call void @llvm.dbg.declare(metadata %struct.Foo** %p.addr, metadata !18, metadata !DIExpression()), !dbg !19
45 %0 = load %struct.Foo*, %struct.Foo** %p.addr, align 8, !dbg !20
46 %1 = bitcast %struct.Foo* %0 to i8* (%struct.Foo*)***, !dbg !20
47 %vtable = load i8* (%struct.Foo*)**, i8* (%struct.Foo*)*** %1, align 8, !dbg !20
48 %vfn = getelementptr inbounds i8* (%struct.Foo*)*, i8* (%struct.Foo*)** %vtable, i64 0, !dbg !20
49 %2 = load i8* (%struct.Foo*)*, i8* (%struct.Foo*)** %vfn, align 8, !dbg !20
50 %call = call i8* %2(%struct.Foo* %0), !dbg !20, !heapallocsite !2
51 call void @use_alloc(i8* %call), !dbg !20
52 ret void, !dbg !21
53 }
54
55 ; CHECK-LABEL: do_alloc: # @do_alloc
56 ; CHECK: .Lheapallocsite2:
57 ; CHECK: callq *(%rax)
58 ; CHECK: .Lheapallocsite3:
59 ; CHECK: retq
60
61 ; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
62 ; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
63 ; CHECK-NEXT: .secrel32 .Lheapallocsite0
64 ; CHECK-NEXT: .secidx .Lheapallocsite0
65 ; CHECK-NEXT: .short .Lheapallocsite1-.Lheapallocsite0
66 ; CHECK-NEXT: .long 3
67 ; CHECK-NEXT: .p2align 2
68 ; CHECK-LABEL: .short 4431 # Record kind: S_PROC_ID_END
69
70 ; CHECK-LABEL: .short 4423 # Record kind: S_GPROC32_ID
71 ; CHECK: .short 4446 # Record kind: S_HEAPALLOCSITE
72 ; CHECK-NEXT: .secrel32 .Lheapallocsite2
73 ; CHECK-NEXT: .secidx .Lheapallocsite2
74 ; CHECK-NEXT: .short .Lheapallocsite3-.Lheapallocsite2
75 ; CHECK-NEXT: .long 3
76 ; CHECK-NEXT: .p2align 2
77 ; CHECK-LABEL: .short 4431 # Record kind: S_PROC_ID_END
78
79 ; Function Attrs: nounwind readnone speculatable
80 declare void @llvm.dbg.declare(metadata, metadata, metadata) #2
81
82 declare dso_local void @use_alloc(i8*) #1
83
84 !llvm.dbg.cu = !{!0}
85 !llvm.module.flags = !{!3, !4, !5, !6}
86 !llvm.ident = !{!7}
87
88 !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 9.0.0 (https://github.com/llvm/llvm-project.git 4eff3de99423a62fd6e833e29c71c1e62ba6140b)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
89 !1 = !DIFile(filename: "heapallocsite.cpp", directory: "C:\5Csrc\5Ctest", checksumkind: CSK_MD5, checksum: "6d758cfa3834154a04ce8a55102772a9")
90 !2 = !{}
91 !3 = !{i32 2, !"CodeView", i32 1}
92 !4 = !{i32 2, !"Debug Info Version", i32 3}
93 !5 = !{i32 1, !"wchar_size", i32 2}
94 !6 = !{i32 7, !"PIC Level", i32 2}
95 !7 = !{!"clang version 9.0.0 (https://github.com/llvm/llvm-project.git 4eff3de99423a62fd6e833e29c71c1e62ba6140b)"}
96 !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !9, scopeLine: 3, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
97 !9 = !DISubroutineType(types: !10)
98 !10 = !{null}
99 !11 = !DILocation(line: 4, scope: !8)
100 !12 = !DILocation(line: 5, scope: !8)
101 !13 = distinct !DISubprogram(name: "do_alloc", scope: !1, file: !1, line: 11, type: !14, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
102 !14 = !DISubroutineType(types: !15)
103 !15 = !{null, !16}
104 !16 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !17, size: 64)
105 !17 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !1, line: 7, flags: DIFlagFwdDecl)
106 !18 = !DILocalVariable(name: "p", arg: 1, scope: !13, file: !1, line: 11, type: !16)
107 !19 = !DILocation(line: 11, scope: !13)
108 !20 = !DILocation(line: 12, scope: !13)
109 !21 = !DILocation(line: 13, scope: !13)
110