[PGO] Context sensitive PGO (part 4)

Part 4 of CSPGO changes:
(1) add support in cmake for cspgo build.
(2) fix an issue in big endian.
(3) test cases.

Differential Revision: https://reviews.llvm.org/D54175

llvm-svn: 355541
This commit is contained in:
Rong Xu 2019-03-06 19:31:37 +00:00
parent 49d880caca
commit 36a2adc1b6
21 changed files with 1049 additions and 1 deletions

View File

@ -604,6 +604,12 @@ if (LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE OR
endif()
file(TO_NATIVE_PATH "${LLVM_PROFILE_DATA_DIR}/%${LLVM_PROFILE_MERGE_POOL_SIZE}m.profraw" LLVM_PROFILE_FILE_PATTERN)
endif()
if(NOT LLVM_CSPROFILE_FILE_PATTERN)
if(NOT LLVM_CSPROFILE_DATA_DIR)
file(TO_NATIVE_PATH "${LLVM_BINARY_DIR}/csprofiles" LLVM_CSPROFILE_DATA_DIR)
endif()
file(TO_NATIVE_PATH "${LLVM_CSPROFILE_DATA_DIR}/%${LLVM_PROFILE_MERGE_POOL_SIZE}m.profraw" LLVM_CSPROFILE_FILE_PATTERN)
endif()
endif()
if (LLVM_BUILD_STATIC)

View File

@ -809,6 +809,12 @@ if (LLVM_BUILD_INSTRUMENTED)
CMAKE_C_FLAGS
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
elseif(uppercase_LLVM_BUILD_INSTRUMENTED STREQUAL "CSIR")
append("-fcs-profile-generate='${LLVM_CSPROFILE_DATA_DIR}'"
CMAKE_CXX_FLAGS
CMAKE_C_FLAGS
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
else()
append("-fprofile-instr-generate='${LLVM_PROFILE_FILE_PATTERN}'"
CMAKE_CXX_FLAGS
@ -818,6 +824,14 @@ if (LLVM_BUILD_INSTRUMENTED)
endif()
endif()
# Need to pass -fprofile-instr-use to linker for context-sensitive PGO
# compilation.
if(LLVM_PROFDATA_FILE AND EXISTS ${LLVM_PROFDATA_FILE})
append("-fprofile-instr-use='${LLVM_PROFDATA_FILE}'"
CMAKE_EXE_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS)
endif()
option(LLVM_BUILD_INSTRUMENTED_COVERAGE "Build LLVM and tools with Code Coverage instrumentation" Off)
mark_as_advanced(LLVM_BUILD_INSTRUMENTED_COVERAGE)
append_if(LLVM_BUILD_INSTRUMENTED_COVERAGE "-fprofile-instr-generate='${LLVM_PROFILE_FILE_PATTERN}' -fcoverage-mapping"

View File

@ -813,7 +813,7 @@ Error IndexedInstrProfReader::readHeader() {
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
/* UseCS */ false);
if (Header->Version & VARIANT_MASK_CSIR_PROF)
if (FormatVersion & VARIANT_MASK_CSIR_PROF)
Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
/* UseCS */ true);

View File

@ -0,0 +1 @@
:csir

View File

@ -0,0 +1 @@
:ir

View File

@ -0,0 +1,13 @@
; Test CSGen pass in CSPGO.
; RUN: llvm-profdata merge %S/Inputs/cspgo-noncs.proftext -o %t-noncs.profdata
; RUN: llvm-profdata merge %S/Inputs/cspgo-cs.proftext -o %t-cs.profdata
; RUN: opt -O2 -debug-pass=Structure -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-gen-pipeline -cs-profilegen-file=alloc %s 2>&1 |FileCheck %s --check-prefixes=CSGENDEFAULT
; CSGENDEFAULT: PGOInstrumentationUse
; CSGENDEFAULT: PGOInstrumentationGenCreateVar
; CSGENDEFAULT: PGOInstrumentationGen
; Test CSUse pass in CSPGO.
; RUN: opt -O2 -debug-pass=Structure -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-cs.profdata' -cspgo-kind=cspgo-instr-use-pipeline %s 2>&1 |FileCheck %s --check-prefixes=CSUSEDEFAULT
; CSUSEDEFAULT: PGOInstrumentationUse
; CSUSEDEFAULT-NOT: PGOInstrumentationGenCreateVar
; CSUSEDEFAULT: PGOInstrumentationUse

View File

@ -0,0 +1,32 @@
; Test CSGen pass in CSPGO.
; RUN: llvm-profdata merge %S/Inputs/cspgo-noncs.proftext -o %t-noncs.profdata
; RUN: llvm-profdata merge %S/Inputs/cspgo-cs.proftext -o %t-cs.profdata
; RUN: opt -debug-pass-manager -passes='default<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-gen-pipeline -cs-profilegen-file=alloc %s 2>&1 |FileCheck %s --check-prefixes=CSGENDEFAULT
; RUN: opt -debug-pass-manager -passes='thinlto-pre-link<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-gen-pipeline -cs-profilegen-file=alloc %s 2>&1 |FileCheck %s --check-prefixes=CSGENPRELINK
; RUN: opt -debug-pass-manager -passes='thinlto<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-gen-pipeline -cs-profilegen-file=alloc %s 2>&1 |FileCheck %s --check-prefixes=CSGENLTO
; RUN: opt -debug-pass-manager -passes='lto-pre-link<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-gen-pipeline -cs-profilegen-file=alloc %s 2>&1 |FileCheck %s --check-prefixes=CSGENPRELINK
; RUN: opt -debug-pass-manager -passes='lto<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-gen-pipeline -cs-profilegen-file=alloc %s 2>&1 |FileCheck %s --check-prefixes=CSGENLTO
; CSGENDEFAULT: Running pass: PGOInstrumentationUse
; CSGENDEFAULT: Running pass: PGOInstrumentationGenCreateVar
; CSGENDEFAULT: Running pass: PGOInstrumentationGen
; CSGENPRELINK: Running pass: PGOInstrumentationUse
; CSGENPRELINK: Running pass: PGOInstrumentationGenCreateVar
; CSGENPRELINK-NOT: Running pass: PGOInstrumentationGen
; CSGENLTO-NOT: Running pass: PGOInstrumentationUse
; CSGENLTO-NOT: Running pass: PGOInstrumentationGenCreateVar
; CSGENLTO: Running pass: PGOInstrumentationGen
; Test CSUse pass in CSPGO.
; RUN: opt -debug-pass-manager -passes='default<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-cs.profdata' -cspgo-kind=cspgo-instr-use-pipeline %s 2>&1 |FileCheck %s --check-prefixes=CSUSEDEFAULT
; RUN: opt -debug-pass-manager -passes='thinlto-pre-link<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-cs.profdata' -cspgo-kind=cspgo-instr-use-pipeline %s 2>&1 |FileCheck %s --check-prefixes=CSUSEPRELINK
; RUN: opt -debug-pass-manager -passes='thinlto<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-cs.profdata' -cspgo-kind=cspgo-instr-use-pipeline %s 2>&1 |FileCheck %s --check-prefixes=CSUSELTO
; RUN: opt -debug-pass-manager -passes='lto-pre-link<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-noncs.profdata' -cspgo-kind=cspgo-instr-use-pipeline %s 2>&1 |FileCheck %s --check-prefixes=CSUSEPRELINK
; RUN: opt -debug-pass-manager -passes='lto<O2>' -pgo-kind=pgo-instr-use-pipeline -profile-file='%t-cs.profdata' -cspgo-kind=cspgo-instr-use-pipeline %s 2>&1 |FileCheck %s --check-prefixes=CSUSELTO
; CSUSEDEFAULT: Running pass: PGOInstrumentationUse
; CSUSEDEFAULT-NOT: Running pass: PGOInstrumentationGenCreateVar
; CSUSEDEFAULT: Running pass: PGOInstrumentationUse
; CSUSEPRELINK: Running pass: PGOInstrumentationUse
; CSUSEPRELINK-NOT: Running pass: PGOInstrumentationGenCreateVar
; CSUSEPRELINK-NOT: Running pass: PGOInstrumentationUse
; CSUSELTO: Running pass: PGOInstrumentationUse
; CSUSELTO-NOT: Running pass: PGOInstrumentationUse

View File

@ -0,0 +1,151 @@
# CSIR level Instrumentation Flag
:csir
bar_m
# Func Hash:
29667547796
# Num Counters:
2
# Counter Values:
99949
51
bar_m
# Func Hash:
1224979111529676799
# Num Counters:
2
# Counter Values:
100000
99949
csfdo_plain.c:cond
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
200000
csfdo_plain.c:cond
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
200000
bar_m2
# Func Hash:
1152921534274394772
# Num Counters:
2
# Counter Values:
99938
62
bar_m2
# Func Hash:
29667547796
# Num Counters:
2
# Counter Values:
99938
62
foo
# Func Hash:
1152921640672869708
# Num Counters:
10
# Counter Values:
100000
100000
0
66666
66666
0
100000
66667
100000
1
foo
# Func Hash:
29212902728
# Num Counters:
2
# Counter Values:
100000
1
bar
# Func Hash:
1152921569533132113
# Num Counters:
5
# Counter Values:
0
0
0
0
0
bar
# Func Hash:
56228292833
# Num Counters:
4
# Counter Values:
800000
399999
100000
100000
main
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
1
main
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
1
csfdo_plain.c:barbar
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
100000
csfdo_plain.c:barbar
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
100000
goo
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
100000
goo
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
100000

View File

@ -0,0 +1,72 @@
# CSIR level Instrumentation Flag
:csir
cond.llvm.11253644763537639171
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
200000
foo
# Func Hash:
29212902728
# Num Counters:
2
# Counter Values:
100000
1
bar
# Func Hash:
1152921534274394772
# Num Counters:
2
# Counter Values:
0
0
bar
# Func Hash:
29667547796
# Num Counters:
2
# Counter Values:
100000
100000
main
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
1
main
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
1
cspgo.c:foo
# Func Hash:
1152921563228422740
# Num Counters:
4
# Counter Values:
100000
100000
0
1
cspgo_bar.c:cond
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
200000

View File

@ -0,0 +1,74 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
$__llvm_profile_filename = comdat any
$__llvm_profile_raw_version = comdat any
@odd = common dso_local global i32 0, align 4
@even = common dso_local global i32 0, align 4
@__llvm_profile_filename = constant [25 x i8] c"pass2/default_%m.profraw\00", comdat
@__llvm_profile_raw_version = constant i64 216172782113783812, comdat
define dso_local void @bar(i32 %n) !prof !29 {
entry:
%call = tail call fastcc i32 @cond(i32 %n)
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %if.else, label %if.then, !prof !30
if.then:
%0 = load i32, i32* @odd, align 4
%inc = add i32 %0, 1
store i32 %inc, i32* @odd, align 4
br label %if.end
if.else:
%1 = load i32, i32* @even, align 4
%inc1 = add i32 %1, 1
store i32 %inc1, i32* @even, align 4
br label %if.end
if.end:
ret void
}
define internal fastcc i32 @cond(i32 %i) #1 !prof !29 !PGOFuncName !35 {
entry:
%rem = srem i32 %i, 2
ret i32 %rem
}
attributes #1 = { inlinehint noinline }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
!4 = !{!"TotalCount", i64 500002}
!5 = !{!"MaxCount", i64 200000}
!6 = !{!"MaxInternalCount", i64 100000}
!7 = !{!"MaxFunctionCount", i64 200000}
!8 = !{!"NumCounts", i64 6}
!9 = !{!"NumFunctions", i64 4}
!10 = !{!"DetailedSummary", !11}
!11 = !{!12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27}
!12 = !{i32 10000, i64 200000, i32 1}
!13 = !{i32 100000, i64 200000, i32 1}
!14 = !{i32 200000, i64 200000, i32 1}
!15 = !{i32 300000, i64 200000, i32 1}
!16 = !{i32 400000, i64 200000, i32 1}
!17 = !{i32 500000, i64 100000, i32 4}
!18 = !{i32 600000, i64 100000, i32 4}
!19 = !{i32 700000, i64 100000, i32 4}
!20 = !{i32 800000, i64 100000, i32 4}
!21 = !{i32 900000, i64 100000, i32 4}
!22 = !{i32 950000, i64 100000, i32 4}
!23 = !{i32 990000, i64 100000, i32 4}
!24 = !{i32 999000, i64 100000, i32 4}
!25 = !{i32 999900, i64 100000, i32 4}
!26 = !{i32 999990, i64 100000, i32 4}
!27 = !{i32 999999, i64 1, i32 6}
!29 = !{!"function_entry_count", i64 200000}
!30 = !{!"branch_weights", i32 100000, i32 100000}
!35 = !{!"cspgo_bar.c:cond"}

View File

@ -0,0 +1,70 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@odd = common dso_local global i32 0, align 4
@even = common dso_local global i32 0, align 4
define dso_local void @bar(i32 %n) #0 !prof !29 {
entry:
%call = tail call fastcc i32 @cond(i32 %n)
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %if.else, label %if.then, !prof !30
if.then:
%0 = load i32, i32* @odd, align 4
%inc = add i32 %0, 1
store i32 %inc, i32* @odd, align 4
br label %if.end
if.else:
%1 = load i32, i32* @even, align 4
%inc1 = add i32 %1, 1
store i32 %inc1, i32* @even, align 4
br label %if.end
if.end:
ret void
}
define internal fastcc i32 @cond(i32 %i) #1 !prof !29 !PGOFuncName !35 {
entry:
%rem = srem i32 %i, 2
ret i32 %rem
}
attributes #0 = { "target-cpu"="x86-64" }
attributes #1 = { inlinehint noinline }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
!4 = !{!"TotalCount", i64 500002}
!5 = !{!"MaxCount", i64 200000}
!6 = !{!"MaxInternalCount", i64 100000}
!7 = !{!"MaxFunctionCount", i64 200000}
!8 = !{!"NumCounts", i64 6}
!9 = !{!"NumFunctions", i64 4}
!10 = !{!"DetailedSummary", !11}
!11 = !{!12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27}
!12 = !{i32 10000, i64 200000, i32 1}
!13 = !{i32 100000, i64 200000, i32 1}
!14 = !{i32 200000, i64 200000, i32 1}
!15 = !{i32 300000, i64 200000, i32 1}
!16 = !{i32 400000, i64 200000, i32 1}
!17 = !{i32 500000, i64 100000, i32 4}
!18 = !{i32 600000, i64 100000, i32 4}
!19 = !{i32 700000, i64 100000, i32 4}
!20 = !{i32 800000, i64 100000, i32 4}
!21 = !{i32 900000, i64 100000, i32 4}
!22 = !{i32 950000, i64 100000, i32 4}
!23 = !{i32 990000, i64 100000, i32 4}
!24 = !{i32 999000, i64 100000, i32 4}
!25 = !{i32 999900, i64 100000, i32 4}
!26 = !{i32 999990, i64 100000, i32 4}
!27 = !{i32 999999, i64 1, i32 6}
!29 = !{!"function_entry_count", i64 200000}
!30 = !{!"branch_weights", i32 100000, i32 100000}
!35 = !{!"cspgo_bar.c:cond"}

View File

@ -0,0 +1,155 @@
; Test the profile summary for context sensitive PGO (CSPGO)
; RUN: llvm-profdata merge %S/Inputs/cspgo.proftext -o %t.profdata
; RUN: opt < %s -O2 -disable-preinline -pgo-kind=pgo-instr-use-pipeline -profile-file=%t.profdata -S | FileCheck %s --check-prefix=PGOSUMMARY
; RUN: opt < %s -O2 -disable-preinline -pgo-kind=pgo-instr-use-pipeline -profile-file=%t.profdata -S -cspgo-kind=cspgo-instr-use-pipeline| FileCheck %s --check-prefix=CSPGOSUMMARY
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@odd = common dso_local global i32 0, align 4
@even = common dso_local global i32 0, align 4
@not_six = common dso_local global i32 0, align 4
define dso_local i32 @goo(i32 %n) {
entry:
%i = alloca i32, align 4
%i.0..sroa_cast = bitcast i32* %i to i8*
store volatile i32 %n, i32* %i, align 4
%i.0. = load volatile i32, i32* %i, align 4
ret i32 %i.0.
}
define dso_local void @bar(i32 %n) {
entry:
%call = call fastcc i32 @cond(i32 %n)
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %if.else, label %if.then
if.then:
%0 = load i32, i32* @odd, align 4
%inc = add i32 %0, 1
store i32 %inc, i32* @odd, align 4
br label %if.end
if.else:
%1 = load i32, i32* @even, align 4
%inc1 = add i32 %1, 1
store i32 %inc1, i32* @even, align 4
br label %if.end
if.end:
br label %for.cond
for.cond:
%i.0 = phi i32 [ 0, %if.end ], [ %inc6, %for.inc ]
%cmp = icmp ult i32 %i.0, 4
br i1 %cmp, label %for.body, label %for.end
for.body:
%mul = mul nsw i32 %i.0, %n
%rem = srem i32 %mul, 6
%tobool2 = icmp eq i32 %rem, 0
br i1 %tobool2, label %for.inc, label %if.then3
if.then3:
%2 = load i32, i32* @not_six, align 4
%inc4 = add i32 %2, 1
store i32 %inc4, i32* @not_six, align 4
br label %for.inc
for.inc:
%inc6 = add nuw nsw i32 %i.0, 1
br label %for.cond
for.end:
ret void
}
; PGOSUMMARY-LABEL: @bar
; PGOSUMMARY: %odd.sink = select i1 %tobool, i32* @even, i32* @odd
; PGOSUMMARY-SAME: !prof ![[BW_PGO_BAR:[0-9]+]]
; CSPGOSUMMARY-LABEL: @bar
; CSPGOSUMMARY: %odd.sink = select i1 %tobool, i32* @even, i32* @odd
; CSPGOSUMMARY-SAME: !prof ![[BW_CSPGO_BAR:[0-9]+]]
define internal fastcc i32 @cond(i32 %i) {
entry:
%rem = srem i32 %i, 2
ret i32 %rem
}
define dso_local void @foo() {
entry:
br label %for.cond
for.cond:
%i.0 = phi i32 [ 0, %entry ], [ %add4, %for.body ]
%cmp = icmp slt i32 %i.0, 200000
br i1 %cmp, label %for.body, label %for.end
for.body:
%call = call i32 @goo(i32 %i.0)
call void @bar(i32 %call)
%add = add nsw i32 %call, 1
call void @bar(i32 %add)
%call1 = call i32 @bar_m(i32 %call) #4
%call3 = call i32 @bar_m2(i32 %add) #4
call fastcc void @barbar()
%add4 = add nsw i32 %call, 2
br label %for.cond
for.end:
ret void
}
; CSPGOSUMMARY-LABEL: @foo
; CSPGOSUMMARY: %even.sink{{[0-9]*}} = select i1 %tobool.i{{[0-9]*}}, i32* @even, i32* @odd
; CSPGOSUMMARY-SAME: !prof ![[BW1_CSPGO_FOO:[0-9]+]]
; CSPGOSUMMARY: %even.sink{{[0-9]*}} = select i1 %tobool.i{{[0-9]*}}, i32* @even, i32* @odd
; CSPGOSUMMARY-SAME: !prof ![[BW2_CSPGO_FOO:[0-9]+]]
declare dso_local i32 @bar_m(i32)
declare dso_local i32 @bar_m2(i32)
define internal fastcc void @barbar() {
entry:
%0 = load i32, i32* @odd, align 4
%inc = add i32 %0, 1
store i32 %inc, i32* @odd, align 4
ret void
}
define dso_local i32 @main() {
entry:
call void @foo()
ret i32 0
}
; PGOSUMMARY: {{![0-9]+}} = !{i32 1, !"ProfileSummary", !{{[0-9]+}}}
; PGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"InstrProf"}
; PGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 2100001}
; PGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 800000}
; PGOSUMMARY: {{![0-9]+}} = !{!"MaxInternalCount", i64 399999}
; PGOSUMMARY: {{![0-9]+}} = !{!"MaxFunctionCount", i64 800000}
; PGOSUMMARY: {{![0-9]+}} = !{!"NumCounts", i64 14}
; PGOSUMMARY: {{![0-9]+}} = !{!"NumFunctions", i64 8}
; PGOSUMMARY-DAG: ![[BW_PGO_BAR]] = !{!"branch_weights", i32 100000, i32 100000}
; CSPGOSUMMARY: {{![0-9]+}} = !{i32 1, !"ProfileSummary", !1}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"InstrProf"}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 2100001}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 800000}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxInternalCount", i64 399999}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxFunctionCount", i64 800000}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"NumCounts", i64 14}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"NumFunctions", i64 8}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"DetailedSummary", !10}
; CSPGOSUMMARY: {{![0-9]+}} = !{i32 1, !"CSProfileSummary", !{{[0-9]+}}}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"ProfileFormat", !"CSInstrProf"}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"TotalCount", i64 1299950}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxCount", i64 200000}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxInternalCount", i64 100000}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"MaxFunctionCount", i64 200000}
; CSPGOSUMMARY: {{![0-9]+}} = !{!"NumCounts", i64 23}
; CSPGOSUMMARY-DAG: ![[BW_CSPGO_BAR]] = !{!"branch_weights", i32 100000, i32 100000}
; CSPGOSUMMARY-DAG: ![[BW1_CSPGO_FOO]] = !{!"branch_weights", i32 100000, i32 0}
; CSPGOSUMMARY-DAG: ![[BW2_CSPGO_FOO]] = !{!"branch_weights", i32 0, i32 100000}

View File

@ -0,0 +1,86 @@
; RUN: opt -module-summary %s -o %t1.bc
; RUN: opt -module-summary %S/Inputs/thinlto_cspgo_bar_gen.ll -o %t2.bc
; RUN: llvm-lto2 run -lto-cspgo-profile-file=alloc -lto-cspgo-gen -save-temps -o %t %t1.bc %t2.bc \
; RUN: -r=%t1.bc,foo,pl \
; RUN: -r=%t1.bc,bar,l \
; RUN: -r=%t1.bc,main,plx \
; RUN: -r=%t1.bc,__llvm_profile_filename,plx \
; RUN: -r=%t1.bc,__llvm_profile_raw_version,plx \
; RUN: -r=%t2.bc,bar,pl \
; RUN: -r=%t2.bc,odd,pl \
; RUN: -r=%t2.bc,even,pl \
; RUN: -r=%t2.bc,__llvm_profile_filename,x \
; RUN: -r=%t2.bc,__llvm_profile_raw_version,x
; RUN: llvm-dis %t.1.4.opt.bc -o - | FileCheck %s --check-prefix=CSGEN
; CSGEN: @__profc_
; CSGEN: @__profd_
source_filename = "cspgo.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
$__llvm_profile_filename = comdat any
$__llvm_profile_raw_version = comdat any
@__llvm_profile_filename = constant [25 x i8] c"pass2/default_%m.profraw\00", comdat
@__llvm_profile_raw_version = constant i64 216172782113783812, comdat
define dso_local void @foo() #0 !prof !29 {
entry:
br label %for.body
for.body:
%i.06 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
tail call void @bar(i32 %i.06)
%add = or i32 %i.06, 1
tail call void @bar(i32 %add)
%add1 = add nuw nsw i32 %i.06, 2
%cmp = icmp ult i32 %add1, 200000
br i1 %cmp, label %for.body, label %for.end, !prof !30
for.end:
ret void
}
declare dso_local void @bar(i32)
define dso_local i32 @main() !prof !29 {
entry:
tail call void @foo()
ret i32 0
}
attributes #0 = { "target-cpu"="x86-64" }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
!4 = !{!"TotalCount", i64 500002}
!5 = !{!"MaxCount", i64 200000}
!6 = !{!"MaxInternalCount", i64 100000}
!7 = !{!"MaxFunctionCount", i64 200000}
!8 = !{!"NumCounts", i64 6}
!9 = !{!"NumFunctions", i64 4}
!10 = !{!"DetailedSummary", !11}
!11 = !{!12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27}
!12 = !{i32 10000, i64 200000, i32 1}
!13 = !{i32 100000, i64 200000, i32 1}
!14 = !{i32 200000, i64 200000, i32 1}
!15 = !{i32 300000, i64 200000, i32 1}
!16 = !{i32 400000, i64 200000, i32 1}
!17 = !{i32 500000, i64 100000, i32 4}
!18 = !{i32 600000, i64 100000, i32 4}
!19 = !{i32 700000, i64 100000, i32 4}
!20 = !{i32 800000, i64 100000, i32 4}
!21 = !{i32 900000, i64 100000, i32 4}
!22 = !{i32 950000, i64 100000, i32 4}
!23 = !{i32 990000, i64 100000, i32 4}
!24 = !{i32 999000, i64 100000, i32 4}
!25 = !{i32 999900, i64 100000, i32 4}
!26 = !{i32 999990, i64 100000, i32 4}
!27 = !{i32 999999, i64 1, i32 6}
!29 = !{!"function_entry_count", i64 1}
!30 = !{!"branch_weights", i32 100000, i32 1}

View File

@ -0,0 +1,80 @@
; RUN: opt -module-summary %s -o %t1.bc
; RUN: opt -module-summary %S/Inputs/thinlto_cspgo_bar_use.ll -o %t2.bc
; RUN: llvm-profdata merge %S/Inputs/thinlto_cs.proftext -o %t3.profdata
; RUN: llvm-lto2 run -lto-cspgo-profile-file=%t3.profdata -save-temps -o %t %t1.bc %t2.bc \
; RUN: -r=%t1.bc,foo,pl \
; RUN: -r=%t1.bc,bar,l \
; RUN: -r=%t1.bc,main,plx \
; RUN: -r=%t2.bc,bar,pl \
; RUN: -r=%t2.bc,odd,pl \
; RUN: -r=%t2.bc,even,pl
; RUN: llvm-dis %t.1.4.opt.bc -o - | FileCheck %s --check-prefix=CSUSE
; CSUSE: {{![0-9]+}} = !{i32 1, !"ProfileSummary", {{![0-9]+}}}
; CSUSE: {{![0-9]+}} = !{i32 1, !"CSProfileSummary", {{![0-9]+}}}
; CSUSE-DAG: {{![0-9]+}} = !{!"branch_weights", i32 100000, i32 0}
; CSUSE-DAG: {{![0-9]+}} = !{!"branch_weights", i32 0, i32 100000}
source_filename = "cspgo.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define dso_local void @foo() #0 !prof !29 {
entry:
br label %for.body
for.body:
%i.06 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
tail call void @bar(i32 %i.06)
%add = or i32 %i.06, 1
tail call void @bar(i32 %add)
%add1 = add nuw nsw i32 %i.06, 2
%cmp = icmp ult i32 %add1, 200000
br i1 %cmp, label %for.body, label %for.end, !prof !30
for.end:
ret void
}
declare dso_local void @bar(i32)
define dso_local i32 @main() !prof !29 {
entry:
tail call void @foo()
ret i32 0
}
attributes #0 = { "target-cpu"="x86-64" }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
!4 = !{!"TotalCount", i64 500002}
!5 = !{!"MaxCount", i64 200000}
!6 = !{!"MaxInternalCount", i64 100000}
!7 = !{!"MaxFunctionCount", i64 200000}
!8 = !{!"NumCounts", i64 6}
!9 = !{!"NumFunctions", i64 4}
!10 = !{!"DetailedSummary", !11}
!11 = !{!12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27}
!12 = !{i32 10000, i64 200000, i32 1}
!13 = !{i32 100000, i64 200000, i32 1}
!14 = !{i32 200000, i64 200000, i32 1}
!15 = !{i32 300000, i64 200000, i32 1}
!16 = !{i32 400000, i64 200000, i32 1}
!17 = !{i32 500000, i64 100000, i32 4}
!18 = !{i32 600000, i64 100000, i32 4}
!19 = !{i32 700000, i64 100000, i32 4}
!20 = !{i32 800000, i64 100000, i32 4}
!21 = !{i32 900000, i64 100000, i32 4}
!22 = !{i32 950000, i64 100000, i32 4}
!23 = !{i32 990000, i64 100000, i32 4}
!24 = !{i32 999000, i64 100000, i32 4}
!25 = !{i32 999900, i64 100000, i32 4}
!26 = !{i32 999990, i64 100000, i32 4}
!27 = !{i32 999999, i64 1, i32 6}
!29 = !{!"function_entry_count", i64 1}
!30 = !{!"branch_weights", i32 100000, i32 1}

View File

@ -0,0 +1,39 @@
# CSIR level Instrumentation Flag
:csir
csfdo_bar.c:cond
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
200000
main
# Func Hash:
1152921517491748863
# Num Counters:
1
# Counter Values:
1
bar
# Func Hash:
1152921569533132113
# Num Counters:
5
# Counter Values:
100000
100000
166666
133333
100000
csfdo.c:foo
# Func Hash:
1152921527029665692
# Num Counters:
2
# Counter Values:
99999
1

View File

@ -0,0 +1,111 @@
source_filename = "csfdo_bar.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@odd = common dso_local local_unnamed_addr global i32 0, align 4
@even = common dso_local local_unnamed_addr global i32 0, align 4
@not_six = common dso_local local_unnamed_addr global i32 0, align 4
define void @bar(i32 %n) !prof !29 {
entry:
%call = tail call fastcc i32 @cond(i32 %n)
%tobool = icmp eq i32 %call, 0
br i1 %tobool, label %if.else, label %if.then, !prof !30
if.then:
%0 = load i32, i32* @odd, align 4
%inc = add i32 %0, 1
store i32 %inc, i32* @odd, align 4
br label %for.inc
if.else:
%1 = load i32, i32* @even, align 4
%inc1 = add i32 %1, 1
store i32 %inc1, i32* @even, align 4
br label %for.inc
for.inc:
%rem.1 = srem i32 %n, 6
%tobool2.1 = icmp eq i32 %rem.1, 0
br i1 %tobool2.1, label %for.inc.1, label %if.then3.1, !prof !35
if.then3.1:
%2 = load i32, i32* @not_six, align 4
%inc4.1 = add i32 %2, 1
store i32 %inc4.1, i32* @not_six, align 4
br label %for.inc.1
for.inc.1:
%mul.2 = shl nsw i32 %n, 1
%rem.2 = srem i32 %mul.2, 6
%tobool2.2 = icmp eq i32 %rem.2, 0
br i1 %tobool2.2, label %for.inc.2, label %if.then3.2, !prof !35
if.then3.2:
%3 = load i32, i32* @not_six, align 4
%inc4.2 = add i32 %3, 1
store i32 %inc4.2, i32* @not_six, align 4
br label %for.inc.2
for.inc.2:
%mul.3 = mul nsw i32 %n, 3
%rem.3 = srem i32 %mul.3, 6
%tobool2.3 = icmp eq i32 %rem.3, 0
br i1 %tobool2.3, label %for.inc.3, label %if.then3.3, !prof !35
if.then3.3:
%4 = load i32, i32* @not_six, align 4
%inc4.3 = add i32 %4, 1
store i32 %inc4.3, i32* @not_six, align 4
br label %for.inc.3
for.inc.3:
ret void
}
define internal fastcc i32 @cond(i32 %i) #1 !prof !29 !PGOFuncName !36 {
entry:
%rem = srem i32 %i, 2
ret i32 %rem
}
attributes #1 = { inlinehint noinline }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
!4 = !{!"TotalCount", i64 1700001}
!5 = !{!"MaxCount", i64 800000}
!6 = !{!"MaxInternalCount", i64 399999}
!7 = !{!"MaxFunctionCount", i64 800000}
!8 = !{!"NumCounts", i64 8}
!9 = !{!"NumFunctions", i64 4}
!10 = !{!"DetailedSummary", !11}
!11 = !{!12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27}
!12 = !{i32 10000, i64 800000, i32 1}
!13 = !{i32 100000, i64 800000, i32 1}
!14 = !{i32 200000, i64 800000, i32 1}
!15 = !{i32 300000, i64 800000, i32 1}
!16 = !{i32 400000, i64 800000, i32 1}
!17 = !{i32 500000, i64 399999, i32 2}
!18 = !{i32 600000, i64 399999, i32 2}
!19 = !{i32 700000, i64 399999, i32 2}
!20 = !{i32 800000, i64 200000, i32 3}
!21 = !{i32 900000, i64 100000, i32 6}
!22 = !{i32 950000, i64 100000, i32 6}
!23 = !{i32 990000, i64 100000, i32 6}
!24 = !{i32 999000, i64 100000, i32 6}
!25 = !{i32 999900, i64 100000, i32 6}
!26 = !{i32 999990, i64 100000, i32 6}
!27 = !{i32 999999, i64 100000, i32 6}
!29 = !{!"function_entry_count", i64 200000}
!30 = !{!"branch_weights", i32 100000, i32 100000}
!31 = !{!32, !32, i64 0}
!32 = !{!"int", !33, i64 0}
!33 = !{!"omnipotent char", !34, i64 0}
!34 = !{!"Simple C/C++ TBAA"}
!35 = !{!"branch_weights", i32 400001, i32 399999}
!36 = !{!"csfdo_bar.c:cond"}

View File

@ -0,0 +1,80 @@
; Generate summary sections
; RUN: opt -module-summary %s -o %t1.o
; RUN: opt -module-summary %p/Inputs/thinlto_cspgo_bar.ll -o %t2.o
; RUN: llvm-profdata merge -o %t.profdata %p/Inputs/cspgo.proftext
; RUN: rm -f %t1.o.4.opt.bc
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
; RUN: -m elf_x86_64 \
; RUN: --plugin-opt=thinlto \
; RUN: --plugin-opt=save-temps \
; RUN: --plugin-opt=cs-profile-path=%t.profdata \
; RUN: --plugin-opt=jobs=1 \
; RUN: %t1.o %t2.o -o %t3
; RUN: opt -S %t2.o.4.opt.bc | FileCheck %s
source_filename = "cspgo.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; CHECK: CSProfileSummary
define dso_local void @foo() #0 !prof !29 {
entry:
br label %for.body
for.body:
%i.06 = phi i32 [ 0, %entry ], [ %add1, %for.body ]
tail call void @bar(i32 %i.06)
%add = or i32 %i.06, 1
tail call void @bar(i32 %add)
%add1 = add nuw nsw i32 %i.06, 2
%cmp = icmp ult i32 %add1, 200000
br i1 %cmp, label %for.body, label %for.end, !prof !30
for.end:
ret void
}
declare dso_local void @bar(i32)
define i32 @main() !prof !29 {
entry:
tail call void @foo()
ret i32 0
}
attributes #0 = { "target-cpu"="x86-64" }
!llvm.module.flags = !{!0, !1}
!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 1, !"ProfileSummary", !2}
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10}
!3 = !{!"ProfileFormat", !"InstrProf"}
!4 = !{!"TotalCount", i64 1700001}
!5 = !{!"MaxCount", i64 800000}
!6 = !{!"MaxInternalCount", i64 399999}
!7 = !{!"MaxFunctionCount", i64 800000}
!8 = !{!"NumCounts", i64 8}
!9 = !{!"NumFunctions", i64 4}
!10 = !{!"DetailedSummary", !11}
!11 = !{!12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27}
!12 = !{i32 10000, i64 800000, i32 1}
!13 = !{i32 100000, i64 800000, i32 1}
!14 = !{i32 200000, i64 800000, i32 1}
!15 = !{i32 300000, i64 800000, i32 1}
!16 = !{i32 400000, i64 800000, i32 1}
!17 = !{i32 500000, i64 399999, i32 2}
!18 = !{i32 600000, i64 399999, i32 2}
!19 = !{i32 700000, i64 399999, i32 2}
!20 = !{i32 800000, i64 200000, i32 3}
!21 = !{i32 900000, i64 100000, i32 6}
!22 = !{i32 950000, i64 100000, i32 6}
!23 = !{i32 990000, i64 100000, i32 6}
!24 = !{i32 999000, i64 100000, i32 6}
!25 = !{i32 999900, i64 100000, i32 6}
!26 = !{i32 999990, i64 100000, i32 6}
!27 = !{i32 999999, i64 100000, i32 6}
!29 = !{!"function_entry_count", i64 1}
!30 = !{!"branch_weights", i32 100000, i32 1}

View File

@ -0,0 +1,11 @@
# CSIR level Instrumentation Flag
:csir
bar
# Func Hash:
1152921534274394772
# Num Counters:
2
# Counter Values:
99938
62

View File

@ -0,0 +1,10 @@
# CSIR level Instrumentation Flag
:csir
bar
# Func Hash:
1152921534274394772
# Num Counters:
2
# Counter Values:
99938
62

View File

@ -0,0 +1,11 @@
# IR level Instrumentation Flag
:ir
bar
# Func Hash:
29667547796
# Num Counters:
2
# Counter Values:
99938
62

View File

@ -0,0 +1,31 @@
Basic test for option -showcs:
RUN: llvm-profdata show %p/Inputs/cs.proftext | FileCheck %s -check-prefix=ZEROSUMMARY
RUN: llvm-profdata show %p/Inputs/noncs.proftext | FileCheck %s -check-prefix=SUMMARY
RUN: llvm-profdata show -showcs %p/Inputs/cs.proftext | FileCheck %s -check-prefix=SUMMARY
RUN: llvm-profdata show -showcs %p/Inputs/noncs.proftext | FileCheck %s -check-prefix=ZEROSUMMARY
ZEROSUMMARY: Instrumentation level: IR
ZEROSUMMARY: Total functions: 0
ZEROSUMMARY: Maximum function count: 0
ZEROSUMMARY: Maximum internal block count: 0
SUMMARY: Instrumentation level: IR
SUMMARY: Total functions: 1
SUMMARY: Maximum function count: 99938
SUMMARY: Maximum internal block count: 62
Basic tests for context sensitive profile dump functions:
RUN: llvm-profdata merge -o %t-combined.profdata %p/Inputs/cs.proftext %p/Inputs/noncs.proftext
RUN: llvm-profdata show --all-functions -counts -showcs %p/Inputs/cs.proftext > %t-text.csdump
RUN: llvm-profdata show --all-functions -counts -showcs %t-combined.profdata > %t-index.csdump
RUN: diff %t-text.csdump %t-index.csdump
RUN: llvm-profdata show --all-functions -counts %p/Inputs/noncs.proftext > %t-text.noncsdump
RUN: llvm-profdata show --all-functions -counts %t-combined.profdata > %t-index.noncsdump
RUN: diff %t-text.noncsdump %t-index.noncsdump
Roundtrip test:
RUN: llvm-profdata merge -o %t.0.profdata %S/Inputs/CSIR_profile.proftext
RUN: llvm-profdata merge -text -o %t.0.proftext %t.0.profdata
RUN: diff %t.0.proftext %S/Inputs/CSIR_profile.proftext