Skip to content

Commit 8fa16cc

Browse files
yolanda15MaskRay
authored andcommitted
[LTO][lld] Add lto-pgo-warn-mismatch option
When enable CSPGO for ThinLTO, there are profile cfg mismatch warnings that will cause lld-link errors (with /WX) due to source changes (e.g. `#if` code runs for profile generation but not for profile use) To disable it we have to use an internal "/mllvm:-no-pgo-warn-mismatch" option. In contrast clang uses option ”-Wno-backend-plugin“ to avoid such warnings and gcc has an explicit "-Wno-coverage-mismatch" option. Add "lto-pgo-warn-mismatch" option to lld COFF/ELF to help turn on/off the profile mismatch warnings explicitly when build with ThinLTO and CSPGO. Differential Revision: https://reviews.llvm.org/D104431
1 parent 32adf10 commit 8fa16cc

File tree

14 files changed

+169
-1
lines changed

14 files changed

+169
-1
lines changed

lld/COFF/Config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ struct Configuration {
223223
// Used for /lto-cs-profile-path
224224
llvm::StringRef ltoCSProfileFile;
225225

226+
// Used for /lto-pgo-warn-mismatch:
227+
bool ltoPGOWarnMismatch = true;
228+
226229
// Used for /call-graph-ordering-file:
227230
llvm::MapVector<std::pair<const SectionChunk *, const SectionChunk *>,
228231
uint64_t>

lld/COFF/Driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,6 +1750,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
17501750
config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
17511751
config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
17521752
// Handle miscellaneous boolean flags.
1753+
config->ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch,
1754+
OPT_lto_pgo_warn_mismatch_no, true);
17531755
config->allowBind = args.hasFlag(OPT_allowbind, OPT_allowbind_no, true);
17541756
config->allowIsolation =
17551757
args.hasFlag(OPT_allowisolation, OPT_allowisolation_no, true);

lld/COFF/LTO.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ static lto::Config createConfig() {
8787
c.DebugPassManager = config->ltoDebugPassManager;
8888
c.CSIRProfile = std::string(config->ltoCSProfileFile);
8989
c.RunCSIRInstr = config->ltoCSProfileGenerate;
90+
c.PGOWarnMismatch = config->ltoPGOWarnMismatch;
9091

9192
if (config->saveTemps)
9293
checkError(c.addSaveTemps(std::string(config->outputFile) + ".",

lld/COFF/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ def lto_cs_profile_generate: F<"lto-cs-profile-generate">,
244244
HelpText<"Perform context sensitive PGO instrumentation">;
245245
def lto_cs_profile_file : P<"lto-cs-profile-file",
246246
"Context sensitive profile file path">;
247+
defm lto_pgo_warn_mismatch: B<
248+
"lto-pgo-warn-mismatch",
249+
"turn on warnings about profile cfg mismatch (default)>",
250+
"turn off warnings about profile cfg mismatch">;
247251
def dash_dash_version : Flag<["--"], "version">,
248252
HelpText<"Display the version number and exit">;
249253
def threads

lld/ELF/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct Configuration {
178178
bool ignoreDataAddressEquality;
179179
bool ignoreFunctionAddressEquality;
180180
bool ltoCSProfileGenerate;
181+
bool ltoPGOWarnMismatch;
181182
bool ltoDebugPassManager;
182183
bool ltoEmitAsm;
183184
bool ltoNewPassManager;

lld/ELF/Driver.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,8 @@ static void readConfigs(opt::InputArgList &args) {
10691069
config->ltoAAPipeline = args.getLastArgValue(OPT_lto_aa_pipeline);
10701070
config->ltoCSProfileGenerate = args.hasArg(OPT_lto_cs_profile_generate);
10711071
config->ltoCSProfileFile = args.getLastArgValue(OPT_lto_cs_profile_file);
1072+
config->ltoPGOWarnMismatch = args.hasFlag(OPT_lto_pgo_warn_mismatch,
1073+
OPT_no_lto_pgo_warn_mismatch, true);
10721074
config->ltoDebugPassManager = args.hasArg(OPT_lto_debug_pass_manager);
10731075
config->ltoEmitAsm = args.hasArg(OPT_lto_emit_asm);
10741076
config->ltoNewPassManager =

lld/ELF/LTO.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ static lto::Config createConfig() {
163163

164164
c.CSIRProfile = std::string(config->ltoCSProfileFile);
165165
c.RunCSIRInstr = config->ltoCSProfileGenerate;
166+
c.PGOWarnMismatch = config->ltoPGOWarnMismatch;
166167

167168
if (config->emitLLVM) {
168169
c.PostInternalizeModuleHook = [](size_t task, const Module &m) {

lld/ELF/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,9 @@ def lto_cs_profile_generate: FF<"lto-cs-profile-generate">,
563563
HelpText<"Perform context sensitive PGO instrumentation">;
564564
def lto_cs_profile_file: JJ<"lto-cs-profile-file=">,
565565
HelpText<"Context sensitive profile file path">;
566+
defm lto_pgo_warn_mismatch: BB<"lto-pgo-warn-mismatch",
567+
"turn on warnings about profile cfg mismatch (default)>",
568+
"turn off warnings about profile cfg mismatch">;
566569
def lto_obj_path_eq: JJ<"lto-obj-path=">;
567570
def lto_sample_profile: JJ<"lto-sample-profile=">,
568571
HelpText<"Sample profile file path">;

lld/test/COFF/pgo-warn-mismatch.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
; REQUIRES: x86
2+
3+
; RUN: rm -rf %t && split-file %s %t
4+
; RUN: opt -module-summary %t/a.ll -o %t/a.bc
5+
; RUN: llvm-profdata merge %t/cs.proftext -o %t/cs.profdata
6+
7+
; Ensure lld generates warnings for profile cfg mismatch.
8+
; RUN: lld-link /dll /noentry /export:f /lto-cs-profile-file:%t/cs.profdata /lto-pgo-warn-mismatch /opt:lldlto=2 %t/a.bc /out:%t/a.dll 2>&1 | FileCheck %s
9+
10+
; Ensure lld will not generate warnings for profile cfg mismatch.
11+
; RUN: lld-link /dll /noentry /export:f /lto-cs-profile-file:%t/cs.profdata /lto-pgo-warn-mismatch:no /opt:lldlto=2 %t/a.bc /out:%t/a.dll 2>&1 | count 0
12+
13+
; CHECK: warning: {{.*}} function control flow change detected (hash mismatch) f Hash = [[#]]
14+
15+
;--- a.ll
16+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
17+
target triple = "x86_64-pc-windows-msvc"
18+
19+
define i32 @f(i32 returned %a) #0 {
20+
entry:
21+
ret i32 %a
22+
}
23+
24+
attributes #0 = { "target-cpu"="x86-64" }
25+
26+
!llvm.module.flags = !{!0, !1}
27+
28+
!0 = !{i32 1, !"wchar_size", i32 4}
29+
!1 = !{i32 1, !"ProfileSummary", !2}
30+
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
31+
!3 = !{!"ProfileFormat", !"InstrProf"}
32+
!4 = !{!"TotalCount", i64 2}
33+
!5 = !{!"MaxCount", i64 1}
34+
!6 = !{!"MaxInternalCount", i64 0}
35+
!7 = !{!"MaxFunctionCount", i64 1}
36+
!8 = !{!"NumCounts", i64 3}
37+
!9 = !{!"NumFunctions", i64 2}
38+
!10 = !{!"IsPartialProfile", i64 0}
39+
!11 = !{!"PartialProfileRatio", double 0.000000e+00}
40+
!12 = !{!"DetailedSummary", !13}
41+
!13 = !{!14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29}
42+
!14 = !{i32 10000, i64 0, i32 0}
43+
!15 = !{i32 100000, i64 0, i32 0}
44+
!16 = !{i32 200000, i64 0, i32 0}
45+
!17 = !{i32 300000, i64 0, i32 0}
46+
!18 = !{i32 400000, i64 0, i32 0}
47+
!19 = !{i32 500000, i64 1, i32 2}
48+
!20 = !{i32 600000, i64 1, i32 2}
49+
!21 = !{i32 700000, i64 1, i32 2}
50+
!22 = !{i32 800000, i64 1, i32 2}
51+
!23 = !{i32 900000, i64 1, i32 2}
52+
!24 = !{i32 950000, i64 1, i32 2}
53+
!25 = !{i32 990000, i64 1, i32 2}
54+
!26 = !{i32 999000, i64 1, i32 2}
55+
!27 = !{i32 999900, i64 1, i32 2}
56+
!28 = !{i32 999990, i64 1, i32 2}
57+
!29 = !{i32 999999, i64 1, i32 2}
58+
59+
;--- cs.proftext
60+
# CSIR level Instrumentation Flag
61+
:csir
62+
f
63+
# Func Hash:
64+
1535914979662757887
65+
# Num Counters:
66+
2
67+
# Counter Values:
68+
1
69+
0
70+

lld/test/ELF/lto/pgo-warn-mismatch.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
; REQUIRES: x86
2+
3+
; RUN: rm -rf %t && split-file %s %t
4+
; RUN: opt -module-summary %t/a.ll -o %t/a.bc
5+
; RUN: llvm-profdata merge %t/cs.proftext -o %t/cs.profdata
6+
7+
;; Ensure lld generates warnings for profile cfg mismatch.
8+
; RUN: ld.lld --lto-cs-profile-file=%t/cs.profdata --lto-pgo-warn-mismatch -shared %t/a.bc -o /dev/null 2>&1 | FileCheck %s
9+
10+
;; Ensure lld will not generate warnings for profile cfg mismatch.
11+
; RUN: ld.lld --lto-cs-profile-file=%t/cs.profdata --no-lto-pgo-warn-mismatch -shared --fatal-warnings %t/a.bc -o /dev/null
12+
13+
; CHECK: warning: {{.*}} function control flow change detected (hash mismatch) f Hash = [[#]]
14+
15+
;--- a.ll
16+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
17+
target triple = "x86_64-unknown-linux-gnu"
18+
19+
define i32 @f(i32 returned %a) #0 {
20+
entry:
21+
ret i32 %a
22+
}
23+
24+
attributes #0 = { "target-cpu"="x86-64" }
25+
26+
!llvm.module.flags = !{!0, !1}
27+
28+
!0 = !{i32 1, !"wchar_size", i32 4}
29+
!1 = !{i32 1, !"ProfileSummary", !2}
30+
!2 = !{!3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
31+
!3 = !{!"ProfileFormat", !"InstrProf"}
32+
!4 = !{!"TotalCount", i64 2}
33+
!5 = !{!"MaxCount", i64 1}
34+
!6 = !{!"MaxInternalCount", i64 0}
35+
!7 = !{!"MaxFunctionCount", i64 1}
36+
!8 = !{!"NumCounts", i64 3}
37+
!9 = !{!"NumFunctions", i64 2}
38+
!10 = !{!"IsPartialProfile", i64 0}
39+
!11 = !{!"PartialProfileRatio", double 0.000000e+00}
40+
!12 = !{!"DetailedSummary", !13}
41+
!13 = !{!14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29}
42+
!14 = !{i32 10000, i64 0, i32 0}
43+
!15 = !{i32 100000, i64 0, i32 0}
44+
!16 = !{i32 200000, i64 0, i32 0}
45+
!17 = !{i32 300000, i64 0, i32 0}
46+
!18 = !{i32 400000, i64 0, i32 0}
47+
!19 = !{i32 500000, i64 1, i32 2}
48+
!20 = !{i32 600000, i64 1, i32 2}
49+
!21 = !{i32 700000, i64 1, i32 2}
50+
!22 = !{i32 800000, i64 1, i32 2}
51+
!23 = !{i32 900000, i64 1, i32 2}
52+
!24 = !{i32 950000, i64 1, i32 2}
53+
!25 = !{i32 990000, i64 1, i32 2}
54+
!26 = !{i32 999000, i64 1, i32 2}
55+
!27 = !{i32 999900, i64 1, i32 2}
56+
!28 = !{i32 999990, i64 1, i32 2}
57+
!29 = !{i32 999999, i64 1, i32 2}
58+
59+
;--- cs.proftext
60+
# CSIR level Instrumentation Flag
61+
:csir
62+
f
63+
# Func Hash:
64+
1535914979662757887
65+
# Num Counters:
66+
2
67+
# Counter Values:
68+
1
69+
0
70+

llvm/include/llvm/LTO/Config.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ struct Config {
7070
/// Run PGO context sensitive IR instrumentation.
7171
bool RunCSIRInstr = false;
7272

73+
/// Turn on/off the warning about a hash mismatch in the PGO profile data.
74+
bool PGOWarnMismatch = true;
75+
7376
/// Asserts whether we can assume whole program visibility during the LTO
7477
/// link.
7578
bool HasWholeProgramVisibility = false;

llvm/lib/LTO/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_llvm_component_library(LLVMLTO
2525
Extensions
2626
IPO
2727
InstCombine
28+
Instrumentation
2829
Linker
2930
MC
3031
ObjCARC

llvm/lib/LTO/LTOBackend.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ static cl::opt<bool> ThinLTOAssumeMerged(
7474
cl::desc("Assume the input has already undergone ThinLTO function "
7575
"importing and the other pre-optimization pipeline changes."));
7676

77+
namespace llvm {
78+
extern cl::opt<bool> NoPGOWarnMismatch;
79+
}
80+
7781
[[noreturn]] static void reportOpenError(StringRef Path, Twine Msg) {
7882
errs() << "failed to open " << Path << ": " << Msg << '\n';
7983
errs().flush();
@@ -221,6 +225,7 @@ static void runNewPMPasses(const Config &Conf, Module &Mod, TargetMachine *TM,
221225
PGOOpt = PGOOptions(Conf.CSIRProfile, "", Conf.ProfileRemapping,
222226
PGOOptions::IRUse, PGOOptions::CSIRUse,
223227
Conf.AddFSDiscriminator);
228+
NoPGOWarnMismatch = !Conf.PGOWarnMismatch;
224229
} else if (Conf.AddFSDiscriminator) {
225230
PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
226231
PGOOptions::NoCSAction, true);

llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,12 +198,14 @@ static cl::opt<bool>
198198
"warnings about missing profile data for "
199199
"functions."));
200200

201+
namespace llvm {
201202
// Command line option to enable/disable the warning about a hash mismatch in
202203
// the profile data.
203-
static cl::opt<bool>
204+
cl::opt<bool>
204205
NoPGOWarnMismatch("no-pgo-warn-mismatch", cl::init(false), cl::Hidden,
205206
cl::desc("Use this option to turn off/on "
206207
"warnings about profile cfg mismatch."));
208+
} // namespace llvm
207209

208210
// Command line option to enable/disable the warning about a hash mismatch in
209211
// the profile data for Comdat functions, which often turns out to be false

0 commit comments

Comments
 (0)