274 lines · plain
1; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s2; RUN: FileCheck %s -check-prefixes=YAML,YAML-NO-ANNOTATE < %t.opt.yaml3 4; RUN: opt < %s -passes=sample-profile -annotate-sample-profile-inline-phase -sample-profile-file=%S/Inputs/remarks.prof -S -pass-remarks=sample-profile -pass-remarks-output=%t.opt.yaml 2>&1 | FileCheck %s5; RUN: FileCheck %s -check-prefixes=YAML,YAML-ANNOTATE < %t.opt.yaml6 7; Original test case.8;9; 1 #include <stdlib.h>10; 211; 3 long long foo() {12; 4 long long int sum = 0;13; 5 for (int i = 0; i < 500000000; i++)14; 6 if (i < 1000)15; 7 sum -= i;16; 8 else17; 9 sum += -i * rand();18; 10 return sum;19; 11 }20; 1221; 13 int main() { return foo() > 0; }22 23; We are expecting foo() to be inlined in main() (almost all the cycles are24; spent inside foo).25; CHECK: remark: remarks.cc:13:21: '_Z3foov' inlined into 'main' to match profiling context with (cost=130, threshold=3000) at callsite main:0:21;26; CHECK: remark: remarks.cc:9:19: 'rand' inlined into 'main' to match profiling context with (cost=always): always inline attribute at callsite _Z3foov:6:19 @ main:0:21;27 28; The back edge for the loop is the hottest edge in the loop subgraph.29; CHECK: remark: remarks.cc:6:9: most popular destination for conditional branches at remarks.cc:5:330 31; The predicate almost always chooses the 'else' branch.32; CHECK: remark: remarks.cc:9:15: most popular destination for conditional branches at remarks.cc:6:933 34; Checking to see if YAML file is generated and contains remarks35;YAML: --- !Passed36;YAML-NO-ANNOTATE-NEXT: Pass: sample-profile-inline37;YAML-ANNOTATE-NEXT: Pass: main-sample-profile-inline38;YAML-NEXT: Name: Inlined39;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 13, Column: 21 }40;YAML-NEXT: Function: main41;YAML-NEXT: Args:42;YAML-NEXT: - String: ''''43;YAML-NEXT: - Callee: _Z3foov44;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 3, Column: 0 }45;YAML-NEXT: - String: ''' inlined into '46;YAML-NEXT: - Caller: main47;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 13, Column: 0 }48;YAML-NEXT: - String: ''''49;YAML-NEXT: - String: ' to match profiling context'50;YAML-NEXT: - String: ' with '51;YAML-NEXT: - String: '(cost='52;YAML-NEXT: - Cost: '130'53;YAML-NEXT: - String: ', threshold='54;YAML-NEXT: - Threshold: '3000'55;YAML-NEXT: - String: ')'56;YAML-NEXT: - String: ' at callsite '57;YAML-NEXT: - String: main58;YAML-NEXT: - String: ':'59;YAML-NEXT: - Line: '0'60;YAML-NEXT: - String: ':'61;YAML-NEXT: - Column: '21'62;YAML-NEXT: - String: ';'63;YAML-NEXT: ...64;YAML: --- !Passed65;YAML-NO-ANNOTATE-NEXT: Pass: sample-profile-inline66;YAML-ANNOTATE-NEXT: Pass: main-sample-profile-inline67;YAML-NEXT: Name: AlwaysInline68;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 9, Column: 19 }69;YAML-NEXT: Function: main70;YAML-NEXT: Args:71;YAML-NEXT: - String: ''''72;YAML-NEXT: - Callee: rand73;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 90, Column: 0 }74;YAML-NEXT: - String: ''' inlined into '''75;YAML-NEXT: - Caller: main76;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 13, Column: 0 }77;YAML-NEXT: - String: ''''78;YAML-NEXT: - String: ' to match profiling context'79;YAML-NEXT: - String: ' with '80;YAML-NEXT: - String: '(cost=always)'81;YAML-NEXT: - String: ': '82;YAML-NEXT: - Reason: always inline attribute83;YAML-NEXT: - String: ' at callsite '84;YAML-NEXT: - String: _Z3foov85;YAML-NEXT: - String: ':'86;YAML-NEXT: - Line: '6'87;YAML-NEXT: - String: ':'88;YAML-NEXT: - Column: '19'89;YAML-NEXT: - String: ' @ '90;YAML-NEXT: - String: main91;YAML-NEXT: - String: ':'92;YAML-NEXT: - Line: '0'93;YAML-NEXT: - String: ':'94;YAML-NEXT: - Column: '21'95;YAML-NEXT: - String: ';'96;YAML: --- !Analysis97;YAML-NEXT: Pass: sample-profile98;YAML-NEXT: Name: AppliedSamples99;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 5, Column: 12 }100;YAML-NEXT: Function: main101;YAML-NEXT: Args:102;YAML-NEXT: - String: 'Applied '103;YAML-NEXT: - NumSamples: '18305'104;YAML-NEXT: - String: ' samples from profile (offset: '105;YAML-NEXT: - LineOffset: '2'106;YAML-NEXT: - String: ')'107;YAML-NEXT: ...108;YAML: --- !Passed109;YAML-NEXT: Pass: sample-profile110;YAML-NEXT: Name: PopularDest111;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 6, Column: 9 }112;YAML-NEXT: Function: main113;YAML-NEXT: Args:114;YAML-NEXT: - String: 'most popular destination for conditional branches at '115;YAML-NEXT: - CondBranchesLoc: 'remarks.cc:5:3'116;YAML-NEXT: DebugLoc: { File: remarks.cc, Line: 5, Column: 3 }117;YAML-NEXT: ...118 119; Function Attrs: nounwind uwtable120define i64 @_Z3foov() #0 !dbg !4 {121entry:122 %sum = alloca i64, align 8123 %i = alloca i32, align 4124 call void @llvm.lifetime.start.p0(ptr %sum) #4, !dbg !19125 call void @llvm.dbg.declare(metadata ptr %sum, metadata !9, metadata !20), !dbg !21126 store i64 0, ptr %sum, align 8, !dbg !21, !tbaa !22127 call void @llvm.lifetime.start.p0(ptr %i) #4, !dbg !26128 call void @llvm.dbg.declare(metadata ptr %i, metadata !10, metadata !20), !dbg !27129 store i32 0, ptr %i, align 4, !dbg !27, !tbaa !28130 br label %for.cond, !dbg !26131 132for.cond: ; preds = %for.inc, %entry133 %0 = load i32, ptr %i, align 4, !dbg !30, !tbaa !28134 %cmp = icmp slt i32 %0, 500000000, !dbg !34135 br i1 %cmp, label %for.body, label %for.cond.cleanup, !dbg !35136 137for.cond.cleanup: ; preds = %for.cond138 call void @llvm.lifetime.end.p0(ptr %i) #4, !dbg !36139 br label %for.end140 141for.body: ; preds = %for.cond142 %1 = load i32, ptr %i, align 4, !dbg !38, !tbaa !28143 %cmp1 = icmp slt i32 %1, 1000, !dbg !40144 br i1 %cmp1, label %if.then, label %if.else, !dbg !41145 146if.then: ; preds = %for.body147 %2 = load i32, ptr %i, align 4, !dbg !42, !tbaa !28148 %conv = sext i32 %2 to i64, !dbg !42149 %3 = load i64, ptr %sum, align 8, !dbg !43, !tbaa !22150 %sub = sub nsw i64 %3, %conv, !dbg !43151 store i64 %sub, ptr %sum, align 8, !dbg !43, !tbaa !22152 br label %if.end, !dbg !44153 154if.else: ; preds = %for.body155 %4 = load i32, ptr %i, align 4, !dbg !45, !tbaa !28156 %sub2 = sub nsw i32 0, %4, !dbg !46157 %call = call i32 @rand() #4, !dbg !47158 %mul = mul nsw i32 %sub2, %call, !dbg !48159 %conv3 = sext i32 %mul to i64, !dbg !46160 %5 = load i64, ptr %sum, align 8, !dbg !49, !tbaa !22161 %add = add nsw i64 %5, %conv3, !dbg !49162 store i64 %add, ptr %sum, align 8, !dbg !49, !tbaa !22163 br label %if.end164 165if.end: ; preds = %if.else, %if.then166 br label %for.inc, !dbg !50167 168for.inc: ; preds = %if.end169 %6 = load i32, ptr %i, align 4, !dbg !51, !tbaa !28170 %inc = add nsw i32 %6, 1, !dbg !51171 store i32 %inc, ptr %i, align 4, !dbg !51, !tbaa !28172 br label %for.cond, !dbg !52173 174for.end: ; preds = %for.cond.cleanup175 %7 = load i64, ptr %sum, align 8, !dbg !53, !tbaa !22176 call void @llvm.lifetime.end.p0(ptr %sum) #4, !dbg !54177 ret i64 %7, !dbg !55178}179 180; Function Attrs: nounwind argmemonly181declare void @llvm.lifetime.start.p0(ptr nocapture) #1182 183; Function Attrs: nounwind readnone184declare void @llvm.dbg.declare(metadata, metadata, metadata) #2185 186; Function Attrs: nounwind187define i32 @rand() #3 !dbg !59 {188 ret i32 1189}190 191; Function Attrs: nounwind argmemonly192declare void @llvm.lifetime.end.p0(ptr nocapture) #1193 194; Function Attrs: nounwind uwtable195define i32 @main() #0 !dbg !13 {196entry:197 %retval = alloca i32, align 4198 store i32 0, ptr %retval, align 4199 %call = call i64 @_Z3foov(), !dbg !56200 %cmp = icmp sgt i64 %call, 0, !dbg !57201 %conv = zext i1 %cmp to i32, !dbg !56202 ret i32 %conv, !dbg !58203}204 205attributes #0 = { nounwind uwtable "use-sample-profile" }206attributes #1 = { nounwind argmemonly }207attributes #2 = { nounwind readnone }208attributes #3 = { nounwind alwaysinline }209attributes #4 = { nounwind }210 211!llvm.dbg.cu = !{!0}212!llvm.module.flags = !{!16, !17}213!llvm.ident = !{!18}214 215!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 251041) (llvm/trunk 251053)", isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug, enums: !2)216!1 = !DIFile(filename: "remarks.cc", directory: ".")217!2 = !{}218!4 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !1, file: !1, line: 3, type: !5, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !8)219!5 = !DISubroutineType(types: !6)220!6 = !{!7}221!7 = !DIBasicType(name: "long long int", size: 64, align: 64, encoding: DW_ATE_signed)222!8 = !{!9, !10}223!9 = !DILocalVariable(name: "sum", scope: !4, file: !1, line: 4, type: !7)224!10 = !DILocalVariable(name: "i", scope: !11, file: !1, line: 5, type: !12)225!11 = distinct !DILexicalBlock(scope: !4, file: !1, line: 5, column: 3)226!12 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)227!13 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 13, type: !14, isLocal: false, isDefinition: true, scopeLine: 13, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2)228!14 = !DISubroutineType(types: !15)229!15 = !{!12}230!16 = !{i32 2, !"Dwarf Version", i32 4}231!17 = !{i32 2, !"Debug Info Version", i32 3}232!18 = !{!"clang version 3.8.0 (trunk 251041) (llvm/trunk 251053)"}233!19 = !DILocation(line: 4, column: 3, scope: !4)234!20 = !DIExpression()235!21 = !DILocation(line: 4, column: 17, scope: !4)236!22 = !{!23, !23, i64 0}237!23 = !{!"long long", !24, i64 0}238!24 = !{!"omnipotent char", !25, i64 0}239!25 = !{!"Simple C/C++ TBAA"}240!26 = !DILocation(line: 5, column: 8, scope: !11)241!27 = !DILocation(line: 5, column: 12, scope: !11)242!28 = !{!29, !29, i64 0}243!29 = !{!"int", !24, i64 0}244!30 = !DILocation(line: 5, column: 19, scope: !31)245!31 = !DILexicalBlockFile(scope: !32, file: !1, discriminator: 3)246!32 = !DILexicalBlockFile(scope: !33, file: !1, discriminator: 1)247!33 = distinct !DILexicalBlock(scope: !11, file: !1, line: 5, column: 3)248!34 = !DILocation(line: 5, column: 21, scope: !33)249!35 = !DILocation(line: 5, column: 3, scope: !11)250!36 = !DILocation(line: 5, column: 3, scope: !37)251!37 = !DILexicalBlockFile(scope: !33, file: !1, discriminator: 2)252!38 = !DILocation(line: 6, column: 9, scope: !39)253!39 = distinct !DILexicalBlock(scope: !33, file: !1, line: 6, column: 9)254!40 = !DILocation(line: 6, column: 11, scope: !39)255!41 = !DILocation(line: 6, column: 9, scope: !33)256!42 = !DILocation(line: 7, column: 14, scope: !39)257!43 = !DILocation(line: 7, column: 11, scope: !39)258!44 = !DILocation(line: 7, column: 7, scope: !39)259!45 = !DILocation(line: 9, column: 15, scope: !39)260!46 = !DILocation(line: 9, column: 14, scope: !39)261!47 = !DILocation(line: 9, column: 19, scope: !39)262!48 = !DILocation(line: 9, column: 17, scope: !39)263!49 = !DILocation(line: 9, column: 11, scope: !39)264!50 = !DILocation(line: 6, column: 13, scope: !39)265!51 = !DILocation(line: 5, column: 35, scope: !33)266!52 = !DILocation(line: 5, column: 3, scope: !33)267!53 = !DILocation(line: 10, column: 10, scope: !4)268!54 = !DILocation(line: 11, column: 1, scope: !4)269!55 = !DILocation(line: 10, column: 3, scope: !4)270!56 = !DILocation(line: 13, column: 21, scope: !13)271!57 = !DILocation(line: 13, column: 27, scope: !13)272!58 = !DILocation(line: 13, column: 14, scope: !13)273!59 = distinct !DISubprogram(name: "rand", linkageName: "rand", scope: !1, file: !1, line: 90, type: !5, isLocal: false, isDefinition: true, scopeLine: 90, flags: DIFlagPrototyped, isOptimized: true, unit: !0)274