Skip to content

[Sample Profile] Check hot callsite threshold when inlining a function with a sample profile #93286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions llvm/lib/Transforms/IPO/SampleProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1391,10 +1391,11 @@ SampleProfileLoader::shouldInlineCandidate(InlineCandidate &Candidate) {
return InlineCost::getAlways("preinliner");
}

// For old FDO inliner, we inline the call site as long as cost is not
// "Never". The cost-benefit check is done earlier.
// For old FDO inliner, we inline the call site if it is below hot threshold,
// even if the function is hot based on sample profile data. This is to
// prevent huge functions from being inlined.
if (!CallsitePrioritizedInline) {
return InlineCost::get(Cost.getCost(), INT_MAX);
return InlineCost::get(Cost.getCost(), SampleHotCallSiteThreshold);
}

// Otherwise only use the cost from call analyzer, but overwite threshold with
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
foo:100:100
1: bar:100
1:100
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-hot-callsite-threshold.prof -S -pass-remarks=sample-profile -sample-profile-hot-inline-threshold=100 2>&1 | FileCheck %s

; CHECK: remark: a.cc:6:12: 'bar' inlined into 'foo' to match profiling context with (cost={{.*}}, threshold=100)
; CHECK: define dso_local noundef i32 @foo(i32 noundef %0)
; CHECK-NOT: %2 = tail call noundef i32 @bar(i32 noundef %0)
; CHECK-NEXT: %2 = icmp sgt i32 %0, 1
; CHECK-NEXT: br i1 %2, label %3, label %bar.exit

; Manually lower cost threshold for hot function inlining, so that the function
; is not inlined even profile indicates it as hot.
; RUN: opt < %s -passes=sample-profile -sample-profile-file=%S/Inputs/inline-hot-callsite-threshold.prof -S -pass-remarks=sample-profile -sample-profile-hot-inline-threshold=1 2>&1 | FileCheck %s --check-prefix=COST

; COST-NOT: remark
; COST: define dso_local noundef i32 @foo(i32 noundef %0)
; COST-NEXT: %2 = tail call noundef i32 @bar(i32 noundef %0)

define dso_local noundef i32 @bar(i32 noundef %0) #0 !dbg !10 {
%2 = icmp sgt i32 %0, 1
br i1 %2, label %3, label %15
3: ; preds = %1
%4 = add nsw i32 %0, -2
%5 = mul i32 %4, %4
%6 = add i32 %5, %0
%7 = zext nneg i32 %4 to i33
%8 = add nsw i32 %0, -3
%9 = zext i32 %8 to i33
%10 = mul i33 %7, %9
%11 = lshr i33 %10, 1
%12 = trunc nuw i33 %11 to i32
%13 = xor i32 %12, -1
%14 = add i32 %6, %13
br label %15
15: ; preds = %3, %1
%16 = phi i32 [ 0, %1 ], [ %14, %3 ]
ret i32 %16
}

define dso_local noundef i32 @foo(i32 noundef %0) #1 !dbg !20 {
%2 = tail call noundef i32 @bar(i32 noundef %0), !dbg !24
ret i32 %2
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "use-sample-profile" }
attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable "use-sample-profile" }
attributes #2 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3}

!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: NoDebug)
!1 = !DIFile(filename: "a.cc", directory: ".")
!2 = !{i32 2, !"Dwarf Version", i32 4}
!3 = !{i32 2, !"Debug Info Version", i32 3}
!10 = distinct !DISubprogram(name: "bar", linkageName: "bar", scope: !1, file: !1, line: 1, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0)
!11 = !DIFile(filename: "a.cc", directory: ".")
!12 = !DISubroutineType(types: !13)
!13 = !{!14, !14}
!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!20 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !11, file: !11, line: 5, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0)
!23 = !DILocation(line: 0, scope: !20)
!24 = !DILocation(line: 6, column: 12, scope: !20)
2 changes: 1 addition & 1 deletion llvm/test/Transforms/SampleProfile/pseudo-probe-inline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ if.end:
;YAML-NEXT: - String: '(cost='
;YAML-NEXT: - Cost: '15'
;YAML-NEXT: - String: ', threshold='
;YAML-NEXT: - Threshold: '2147483647'
;YAML-NEXT: - Threshold: '3000'
;YAML-NEXT: - String: ')'
;YAML-NEXT: - String: ' at callsite '
;YAML-NEXT: - String: foo
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/Transforms/SampleProfile/remarks.ll
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

; We are expecting foo() to be inlined in main() (almost all the cycles are
; spent inside foo).
; CHECK: remark: remarks.cc:13:21: '_Z3foov' inlined into 'main' to match profiling context with (cost=130, threshold=2147483647) at callsite main:0:21;
; CHECK: remark: remarks.cc:13:21: '_Z3foov' inlined into 'main' to match profiling context with (cost=130, threshold=3000) at callsite main:0:21;
; 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;

; The back edge for the loop is the hottest edge in the loop subgraph.
Expand Down Expand Up @@ -51,7 +51,7 @@
;YAML-NEXT: - String: '(cost='
;YAML-NEXT: - Cost: '130'
;YAML-NEXT: - String: ', threshold='
;YAML-NEXT: - Threshold: '2147483647'
;YAML-NEXT: - Threshold: '3000'
;YAML-NEXT: - String: ')'
;YAML-NEXT: - String: ' at callsite '
;YAML-NEXT: - String: main
Expand Down
Loading