1;; Test we merge non-inlined profile only once with '-sample-profile-merge-inlinee' 2; RUN: opt < %s -passes='function(callsite-splitting),sample-profile' -sample-profile-file=%S/Inputs/inline-mergeprof.prof -sample-profile-merge-inlinee=true -S | FileCheck %s 3 4%struct.bitmap = type { i32, %struct.bitmap* } 5 6; CHECK-LABEL: @main 7define void @main(i1 %c, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt) #0 !dbg !6 { 8entry: 9 br label %Top 10 11Top: 12 %tobool1 = icmp eq %struct.bitmap* %a_elt, null 13 br i1 %tobool1, label %CallSiteBB, label %NextCond 14 15NextCond: 16 %cmp = icmp ne %struct.bitmap* %b_elt, null 17 br i1 %cmp, label %CallSiteBB, label %End 18 19CallSiteBB: 20 %p = phi i1 [0, %Top], [%c, %NextCond] 21;; The call site is replicated by callsite-splitting pass and they end up share the same sample profile 22; CHECK: call void @_Z3sumii(%struct.bitmap* null, %struct.bitmap* null, %struct.bitmap* %b_elt, i1 false) 23; CHECK: call void @_Z3sumii(%struct.bitmap* nonnull %a_elt, %struct.bitmap* nonnull %a_elt, %struct.bitmap* nonnull %b_elt, i1 %c) 24 call void @_Z3sumii(%struct.bitmap* %a_elt, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt, i1 %p), !dbg !8 25 br label %End 26 27End: 28 ret void 29} 30 31define void @_Z3sumii(%struct.bitmap* %dst_elt, %struct.bitmap* %a_elt, %struct.bitmap* %b_elt, i1 %c) #0 !dbg !12 { 32entry: 33 %tobool = icmp ne %struct.bitmap* %a_elt, null 34 %tobool1 = icmp ne %struct.bitmap* %b_elt, null 35 %or.cond = and i1 %tobool, %tobool1, !dbg !13 36 br i1 %or.cond, label %Cond, label %Big 37 38Cond: 39 %cmp = icmp eq %struct.bitmap* %dst_elt, %a_elt, !dbg !14 40 br i1 %cmp, label %Small, label %Big, !dbg !15 41 42Small: 43 br label %End 44 45Big: 46 br label %End 47 48End: 49 ret void 50} 51 52attributes #0 = { "use-sample-profile" } 53 54!llvm.dbg.cu = !{!0} 55!llvm.module.flags = !{!3, !4} 56!llvm.ident = !{!5} 57 58!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.5 ", isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2) 59!1 = !DIFile(filename: "calls.cc", directory: ".") 60!2 = !{} 61!3 = !{i32 2, !"Dwarf Version", i32 4} 62!4 = !{i32 1, !"Debug Info Version", i32 3} 63!5 = !{!"clang version 3.5 "} 64!6 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 7, type: !7, scopeLine: 7, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 65!7 = !DISubroutineType(types: !2) 66!8 = !DILocation(line: 10, scope: !9) 67!9 = !DILexicalBlockFile(scope: !10, file: !1, discriminator: 2) 68!10 = distinct !DILexicalBlock(scope: !6, file: !1, line: 10) 69!11 = !DILocation(line: 12, scope: !6) 70!12 = distinct !DISubprogram(name: "sum", scope: !1, file: !1, line: 3, type: !7, scopeLine: 3, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 71!13 = !DILocation(line: 4, scope: !12) 72!14 = !DILocation(line: 5, scope: !12) 73!15 = !DILocation(line: 6, scope: !12) 74 75 76;; Check the profile of funciton sum is only merged once though the original callsite is replicted. 77; CHECK: name: "sum" 78; CHECK-NEXT: {!"function_entry_count", i64 46} 79; CHECK: !{!"branch_weights", i32 11, i32 37} 80; CHECK: !{!"branch_weights", i32 11, i32 1} 81