305 lines · plain
1// RUN: split-file %s %t2 3// Assemble the input assembly code into an object file4// RUN: llc -enable-machine-outliner=never -mtriple arm64-apple-darwin -filetype=obj %t/call_sites.ll -o %t/call_sites.o5// RUN: llvm-gsymutil --num-threads=1 --convert=%t/call_sites.o --callsites-yaml-file=%t/callsites.yaml -o %t/call_sites_obj.gsym6 7// Dump the GSYM file and check the output for callsite information8// RUN: llvm-gsymutil %t/call_sites_obj.gsym | FileCheck --check-prefix=CHECK-GSYM %s9 10 11// CHECK-GSYM: FunctionInfo @ 0x[[#%x,FUNC_INFO:]]: [0x[[#%x,FUNC_START:]] - 0x[[#%x,FUNC_END:]]) "func_mainBin_dec_call_everything"12// CHECK-GSYM-NEXT: LineTable:13 // func_mainBin_dec_call_everything() {14// CHECK-GSYM-NEXT: 0x[[#%x,ENTRY:]] {{.*}}/call_sites.cpp:1615 // func_mainBin_dec_01();16// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_DEC_01_CALL:]] {{.*}}/call_sites.cpp:1717 // func_mainBin_dec_02();18// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_DEC_02_CALL:]] {{.*}}/call_sites.cpp:1819 // func_mainBin_dec_03();20// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_DEC_03_CALL:]] {{.*}}/call_sites.cpp:1921 // func_mainBin_inc_01();22// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_INC_01_CALL:]] {{.*}}/call_sites.cpp:2123 // func_mainBin_inc_02();24// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_INC_02_CALL:]] {{.*}}/call_sites.cpp:2225 // func_mainBin_inc_03();26// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_INC_03_CALL:]] {{.*}}/call_sites.cpp:2327 // g_func_ptr();28// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_FUNC_CALL:]] {{.*}}/call_sites.cpp:2529 // g_extern_func_ptr();30// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_EXTERN_FUNC_CALL:]] {{.*}}/call_sites.cpp:2631 // g_volatile_var = 0;32// CHECK-GSYM-NEXT: 0x[[#%x,ADDR_VAR_ASSIGN:]] {{.*}}/call_sites.cpp:2833 // }34// CHECK-GSYM-NEXT: 0x[[#%x,]] {{.*}}/call_sites.cpp:2935// CHECK-GSYM-NEXT: CallSites (by relative return offset):36// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_DEC_02_CALL,FUNC_START)]] Flags[InternalCall] MatchRegex[func_mainBin_dec_01]37// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_DEC_03_CALL,FUNC_START)]] Flags[InternalCall] MatchRegex[func_mainBin_dec_02]38// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_INC_01_CALL,FUNC_START)]] Flags[InternalCall] MatchRegex[func_mainBin_dec_03]39// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_INC_02_CALL,FUNC_START)]] Flags[InternalCall] MatchRegex[func_mainBin_inc_01]40// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_INC_03_CALL,FUNC_START)]] Flags[InternalCall] MatchRegex[func_mainBin_inc_02]41// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_FUNC_CALL,FUNC_START)]] Flags[InternalCall] MatchRegex[func_mainBin_inc_03]42// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_EXTERN_FUNC_CALL,FUNC_START)]] Flags[None] MatchRegex[.*func.*]43// CHECK-GSYM-NEXT: 0x[[#%.4x,sub(ADDR_VAR_ASSIGN,FUNC_START)]] Flags[ExternalCall] MatchRegex[.*extern_func.*]44 45 46//--- callsites.yaml47functions:48 - name: func_mainBin_dec_call_everything49 callsites:50 - return_offset: 0x0C51 match_regex: ["func_mainBin_dec_01"]52 flags:53 - "InternalCall"54 - return_offset: 0x1055 match_regex: ["func_mainBin_dec_02"]56 flags:57 - "InternalCall"58 - return_offset: 0x1459 match_regex: ["func_mainBin_dec_03"]60 flags:61 - "InternalCall"62 - return_offset: 2463 match_regex: ["func_mainBin_inc_01"]64 flags:65 - "InternalCall"66 - return_offset: 2867 match_regex: ["func_mainBin_inc_02"]68 flags:69 - "InternalCall"70 - return_offset: 3271 match_regex: ["func_mainBin_inc_03"]72 flags:73 - "InternalCall"74 - return_offset: 4475 match_regex: [".*func.*"]76 - return_offset: 5677 match_regex: [".*extern_func.*"]78 flags:79 - "ExternalCall"80 81 82//--- call_sites.ll83; ModuleID = 'call_sites.cpp'84source_filename = "call_sites.cpp"85target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32"86target triple = "arm64-unknown-macosx10.4.0"87 88@g_volatile_var = global i32 0, align 4, !dbg !089@g_func_ptr = global ptr null, align 8, !dbg !590@g_extern_func_ptr = global ptr null, align 8, !dbg !1291 92; Function Attrs: minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none)93define void @func_mainBin_dec_01() local_unnamed_addr #0 !dbg !21 {94entry:95 %0 = load volatile i32, ptr @g_volatile_var, align 4, !dbg !24, !tbaa !2596 %dec = add nsw i32 %0, -1, !dbg !2497 store volatile i32 %dec, ptr @g_volatile_var, align 4, !dbg !24, !tbaa !2598 ret void, !dbg !2999}100 101; Function Attrs: minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none)102define void @func_mainBin_dec_02() local_unnamed_addr #0 !dbg !30 {103entry:104 %0 = load volatile i32, ptr @g_volatile_var, align 4, !dbg !31, !tbaa !25105 %dec = add nsw i32 %0, -1, !dbg !31106 store volatile i32 %dec, ptr @g_volatile_var, align 4, !dbg !31, !tbaa !25107 ret void, !dbg !32108}109 110; Function Attrs: minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none)111define void @func_mainBin_dec_03() local_unnamed_addr #0 !dbg !33 {112entry:113 %0 = load volatile i32, ptr @g_volatile_var, align 4, !dbg !34, !tbaa !25114 %dec = add nsw i32 %0, -1, !dbg !34115 store volatile i32 %dec, ptr @g_volatile_var, align 4, !dbg !34, !tbaa !25116 ret void, !dbg !35117}118 119; Function Attrs: minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none)120define void @func_mainBin_inc_01() local_unnamed_addr #0 !dbg !36 {121entry:122 %0 = load volatile i32, ptr @g_volatile_var, align 4, !dbg !37, !tbaa !25123 %inc = add nsw i32 %0, 1, !dbg !37124 store volatile i32 %inc, ptr @g_volatile_var, align 4, !dbg !37, !tbaa !25125 ret void, !dbg !38126}127 128; Function Attrs: minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none)129define void @func_mainBin_inc_02() local_unnamed_addr #0 !dbg !39 {130entry:131 %0 = load volatile i32, ptr @g_volatile_var, align 4, !dbg !40, !tbaa !25132 %inc = add nsw i32 %0, 1, !dbg !40133 store volatile i32 %inc, ptr @g_volatile_var, align 4, !dbg !40, !tbaa !25134 ret void, !dbg !41135}136 137; Function Attrs: minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none)138define void @func_mainBin_inc_03() local_unnamed_addr #0 !dbg !42 {139entry:140 %0 = load volatile i32, ptr @g_volatile_var, align 4, !dbg !43, !tbaa !25141 %inc = add nsw i32 %0, 1, !dbg !43142 store volatile i32 %inc, ptr @g_volatile_var, align 4, !dbg !43, !tbaa !25143 ret void, !dbg !44144}145 146; Function Attrs: minsize mustprogress noinline nounwind optsize ssp147define void @func_mainBin_dec_call_everything() local_unnamed_addr #1 !dbg !45 {148entry:149 tail call void @func_mainBin_dec_01() #3, !dbg !46150 tail call void @func_mainBin_dec_02() #3, !dbg !47151 tail call void @func_mainBin_dec_03() #3, !dbg !48152 tail call void @func_mainBin_inc_01() #3, !dbg !49153 tail call void @func_mainBin_inc_02() #3, !dbg !50154 tail call void @func_mainBin_inc_03() #3, !dbg !51155 %0 = load volatile ptr, ptr @g_func_ptr, align 8, !dbg !52, !tbaa !53156 %call = tail call noundef i32 %0() #4, !dbg !52157 %1 = load volatile ptr, ptr @g_extern_func_ptr, align 8, !dbg !55, !tbaa !53158 %call1 = tail call noundef i32 %1() #4, !dbg !55159 store volatile i32 0, ptr @g_volatile_var, align 4, !dbg !56, !tbaa !25160 ret void, !dbg !57161}162 163; Function Attrs: minsize mustprogress norecurse nounwind optsize ssp164define noundef i32 @main() local_unnamed_addr #2 !dbg !58 {165entry:166 tail call void @func_mainBin_dec_call_everything() #3, !dbg !59167 ret i32 0, !dbg !60168}169 170attributes #0 = { minsize mustprogress nofree noinline norecurse nounwind optsize ssp memory(readwrite, argmem: none) "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }171attributes #1 = { minsize mustprogress noinline nounwind optsize ssp "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }172attributes #2 = { minsize mustprogress norecurse nounwind optsize ssp "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+altnzcv,+ccdp,+ccidx,+complxnum,+crc,+dit,+dotprod,+flagm,+fp-armv8,+fp16fml,+fptoint,+fullfp16,+jsconv,+lse,+neon,+pauth,+perfmon,+predres,+ras,+rcpc,+rdm,+sb,+sha2,+sha3,+specrestrict,+ssbs,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8a" }173attributes #3 = { minsize optsize }174attributes #4 = { minsize nounwind optsize }175 176!llvm.dbg.cu = !{!2}177!llvm.module.flags = !{!15, !16, !17, !18, !19}178!llvm.ident = !{!20}179 180!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())181!1 = distinct !DIGlobalVariable(name: "g_volatile_var", scope: !2, file: !3, line: 4, type: !14, isLocal: false, isDefinition: true)182!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 20.0.0git (https://github.com/alx32/llvm-project.git f41f6ea1f33c4f5e7c94f3d155e44292d1809c50)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None, sysroot: "/")183!3 = !DIFile(filename: "call_sites.cpp", directory: "/tmp/tst")184!4 = !{!0, !5, !12}185!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())186!6 = distinct !DIGlobalVariable(name: "g_func_ptr", scope: !2, file: !3, line: 5, type: !7, isLocal: false, isDefinition: true)187!7 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !8)188!8 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !9, size: 64)189!9 = !DISubroutineType(types: !10)190!10 = !{!11}191!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)192!12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression())193!13 = distinct !DIGlobalVariable(name: "g_extern_func_ptr", scope: !2, file: !3, line: 6, type: !7, isLocal: false, isDefinition: true)194!14 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !11)195!15 = !{i32 7, !"Dwarf Version", i32 4}196!16 = !{i32 2, !"Debug Info Version", i32 3}197!17 = !{i32 1, !"wchar_size", i32 4}198!18 = !{i32 8, !"PIC Level", i32 2}199!19 = !{i32 7, !"frame-pointer", i32 1}200!20 = !{!"clang version 20.0.0git (https://github.com/alx32/llvm-project.git f41f6ea1f33c4f5e7c94f3d155e44292d1809c50)"}201!21 = distinct !DISubprogram(name: "func_mainBin_dec_01", scope: !3, file: !3, line: 8, type: !22, scopeLine: 8, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)202!22 = !DISubroutineType(types: !23)203!23 = !{null}204!24 = !DILocation(line: 8, column: 54, scope: !21)205!25 = !{!26, !26, i64 0}206!26 = !{!"int", !27, i64 0}207!27 = !{!"omnipotent char", !28, i64 0}208!28 = !{!"Simple C++ TBAA"}209!29 = !DILocation(line: 8, column: 58, scope: !21)210!30 = distinct !DISubprogram(name: "func_mainBin_dec_02", scope: !3, file: !3, line: 9, type: !22, scopeLine: 9, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)211!31 = !DILocation(line: 9, column: 54, scope: !30)212!32 = !DILocation(line: 9, column: 58, scope: !30)213!33 = distinct !DISubprogram(name: "func_mainBin_dec_03", scope: !3, file: !3, line: 10, type: !22, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)214!34 = !DILocation(line: 10, column: 54, scope: !33)215!35 = !DILocation(line: 10, column: 58, scope: !33)216!36 = distinct !DISubprogram(name: "func_mainBin_inc_01", scope: !3, file: !3, line: 12, type: !22, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)217!37 = !DILocation(line: 12, column: 54, scope: !36)218!38 = !DILocation(line: 12, column: 58, scope: !36)219!39 = distinct !DISubprogram(name: "func_mainBin_inc_02", scope: !3, file: !3, line: 13, type: !22, scopeLine: 13, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)220!40 = !DILocation(line: 13, column: 54, scope: !39)221!41 = !DILocation(line: 13, column: 58, scope: !39)222!42 = distinct !DISubprogram(name: "func_mainBin_inc_03", scope: !3, file: !3, line: 14, type: !22, scopeLine: 14, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)223!43 = !DILocation(line: 14, column: 54, scope: !42)224!44 = !DILocation(line: 14, column: 58, scope: !42)225!45 = distinct !DISubprogram(name: "func_mainBin_dec_call_everything", scope: !3, file: !3, line: 16, type: !22, scopeLine: 16, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)226!46 = !DILocation(line: 17, column: 5, scope: !45)227!47 = !DILocation(line: 18, column: 5, scope: !45)228!48 = !DILocation(line: 19, column: 5, scope: !45)229!49 = !DILocation(line: 21, column: 5, scope: !45)230!50 = !DILocation(line: 22, column: 5, scope: !45)231!51 = !DILocation(line: 23, column: 5, scope: !45)232!52 = !DILocation(line: 25, column: 5, scope: !45)233!53 = !{!54, !54, i64 0}234!54 = !{!"any pointer", !27, i64 0}235!55 = !DILocation(line: 26, column: 5, scope: !45)236!56 = !DILocation(line: 28, column: 20, scope: !45)237!57 = !DILocation(line: 29, column: 1, scope: !45)238!58 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 31, type: !9, scopeLine: 31, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2)239!59 = !DILocation(line: 32, column: 3, scope: !58)240!60 = !DILocation(line: 33, column: 3, scope: !58)241 242 243//--- generate-callsite-test-data.sh244#!/bin/bash245## This is provided for reference only, if we need to modify the file and regenerate the assembly code246set -ex247 248TOOLCHAIN_DIR="llvm-project/build/Debug/bin"249 250# Create call_sites.cpp251cat > call_sites.cpp <<EOF252 253#define FUNC_ATTR extern "C" __attribute__((noinline))254 255volatile int g_volatile_var;256int (*volatile g_func_ptr)();257int (*volatile g_extern_func_ptr)();258 259FUNC_ATTR void func_mainBin_dec_01() { g_volatile_var--; }260FUNC_ATTR void func_mainBin_dec_02() { g_volatile_var--; }261FUNC_ATTR void func_mainBin_dec_03() { g_volatile_var--; }262 263FUNC_ATTR void func_mainBin_inc_01() { g_volatile_var++; }264FUNC_ATTR void func_mainBin_inc_02() { g_volatile_var++; }265FUNC_ATTR void func_mainBin_inc_03() { g_volatile_var++; }266 267FUNC_ATTR void func_mainBin_dec_call_everything() {268 func_mainBin_dec_01();269 func_mainBin_dec_02();270 func_mainBin_dec_03();271 272 func_mainBin_inc_01();273 func_mainBin_inc_02();274 func_mainBin_inc_03();275 276 g_func_ptr();277 g_extern_func_ptr();278 279 g_volatile_var = 0;280}281 282int main() {283 func_mainBin_dec_call_everything();284 return 0;285}286EOF287 288# Generate IR from call_sites.cpp289"$TOOLCHAIN_DIR"/clang++ -mno-outline -target arm64-apple-macos -g -Oz -fno-exceptions -S -emit-llvm call_sites.cpp -o call_sites.ll290 291# Compile the assembly into an object file292"$TOOLCHAIN_DIR"/llc -filetype=obj call_sites.ll -o call_sites.o293 294# Link the object file into an executable using lld directly295"$TOOLCHAIN_DIR"/ld64.lld -arch arm64 -platform_version macos 11.0.0 11.0.0 -o call_sites call_sites.o -lSystem296 297# Create a dSYM file298"$TOOLCHAIN_DIR"/dsymutil call_sites -o call_sites.dSYM299 300# Dump the binary to YAML301"$TOOLCHAIN_DIR"/obj2yaml call_sites > call_sites_binary.yaml302 303# Dump the dSYM to YAML304"$TOOLCHAIN_DIR"/obj2yaml call_sites.dSYM/Contents/Resources/DWARF/call_sites > call_sites_dsym.yaml305