Skip to content

Commit da65ed4

Browse files
committed
PGO: new -profile-sample-use= frontend option
This is meant to match clang's `-fprofile-sample-use=` rdar://135443278
1 parent 132726c commit da65ed4

File tree

6 files changed

+86
-0
lines changed

6 files changed

+86
-0
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,10 @@ class IRGenOptions {
500500
/// Path to the profdata file to be used for PGO, or the empty string.
501501
std::string UseProfile = "";
502502

503+
/// Path to the data file to be used for sampling-based PGO,
504+
/// or the empty string.
505+
std::string UseSampleProfile = "";
506+
503507
/// List of backend command-line options for -embed-bitcode.
504508
std::vector<uint8_t> CmdArgs;
505509

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,6 +1481,11 @@ def profile_coverage_mapping : Flag<["-"], "profile-coverage-mapping">,
14811481
Flags<[FrontendOption, NoInteractiveOption]>,
14821482
HelpText<"Generate coverage data for use with profiled execution counts">;
14831483

1484+
def profile_sample_use : CommaJoined<["-"], "profile-sample-use=">,
1485+
Flags<[FrontendOption, NoInteractiveOption, ArgumentIsPath]>,
1486+
MetaVarName<"<profile data>">,
1487+
HelpText<"Supply sampling-based profiling data from an external tool to enable profile-guided optimization">;
1488+
14841489
def embed_bitcode : Flag<["-"], "embed-bitcode">,
14851490
Flags<[FrontendOption, NoInteractiveOption]>,
14861491
HelpText<"Embed LLVM IR bitcode as data">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,9 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
31773177
const Arg *ProfileUse = Args.getLastArg(OPT_profile_use);
31783178
Opts.UseProfile = ProfileUse ? ProfileUse->getValue() : "";
31793179

3180+
const Arg *ProfileSampleUse = Args.getLastArg(OPT_profile_sample_use);
3181+
Opts.UseSampleProfile = ProfileSampleUse ? ProfileSampleUse->getValue() : "";
3182+
31803183
Opts.PrintInlineTree |= Args.hasArg(OPT_print_llvm_inline_tree);
31813184
// Always producing all outputs when caching is enabled.
31823185
Opts.AlwaysCompile |= Args.hasArg(OPT_always_compile_output_files) ||

lib/IRGen/IRGen.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,23 @@ static void align(llvm::Module *Module) {
200200
}
201201
}
202202

203+
static void populatePGOOptions(std::optional<PGOOptions> &Out,
204+
const IRGenOptions &Opts) {
205+
if (!Opts.UseSampleProfile.empty()) {
206+
Out = PGOOptions(
207+
/*ProfileFile=*/ Opts.UseSampleProfile,
208+
/*CSProfileGenFile=*/ "",
209+
/*ProfileRemappingFile=*/ "",
210+
/*MemoryProfile=*/ "",
211+
/*FS=*/ llvm::vfs::getRealFileSystem(), // TODO: is this fine?
212+
/*Action=*/ PGOOptions::SampleUse,
213+
/*CSPGOAction=*/ PGOOptions::NoCSAction,
214+
/*DebugInfoForProfiling=*/ false
215+
);
216+
return;
217+
}
218+
}
219+
203220
void swift::performLLVMOptimizations(const IRGenOptions &Opts,
204221
llvm::Module *Module,
205222
llvm::TargetMachine *TargetMachine,
@@ -222,6 +239,7 @@ void swift::performLLVMOptimizations(const IRGenOptions &Opts,
222239
PTO.LoopVectorization = true;
223240
PTO.SLPVectorization = true;
224241
PTO.MergeFunctions = true;
242+
populatePGOOptions(PGOOpt, Opts);
225243
// Splitting trades code size to enhance memory locality, avoid in -Osize.
226244
DoHotColdSplit = Opts.EnableHotColdSplit && !Opts.optimizeForSize();
227245
level = llvm::OptimizationLevel::Os;

lib/IRGen/IRGenSIL.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,6 +1939,13 @@ IRGenSILFunction::IRGenSILFunction(IRGenModule &IGM, SILFunction *f)
19391939
// LLVM doesn't have an attribute for -O
19401940
}
19411941

1942+
const bool optimizing = IGM.IRGen.Opts.shouldOptimize() &&
1943+
!IGM.IRGen.Opts.DisableLLVMOptzns;
1944+
if (optimizing && !IGM.IRGen.Opts.UseSampleProfile.empty()) {
1945+
// This attribute helps in LTO situations: https://reviews.llvm.org/D79959
1946+
CurFn->addFnAttr("use-sample-profile");
1947+
}
1948+
19421949
// Emit the thunk that calls the previous implementation if this is a dynamic
19431950
// replacement.
19441951
if (f->getDynamicallyReplacedFunction()) {

test/Profiler/samplepgo.swift

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// ----------------------------------------
5+
// Test the -profile-sample-use= flag using bogus data, to ensure it's actually
6+
// reaching LLVM in the expected way.
7+
8+
// RUN: %target-swift-frontend %t/program.swift -module-name test -emit-ir \
9+
// RUN: -O -profile-sample-use=%t/profile.txt -o %t/has-data.ll
10+
11+
// RUN: %FileCheck %s < %t/has-data.ll
12+
13+
// CHECK: define{{.*}} @"$s4test8anythingyyF"() #[[ATTRID:[0-9]+]]
14+
// CHECK: attributes #[[ATTRID]] = {{.*}} "use-sample-profile"
15+
16+
// CHECK-LABEL: !llvm.module.flags
17+
// CHECK: !{!"ProfileFormat", !"SampleProfile"}
18+
// CHECK: !{!"TotalCount", i64 2001}
19+
20+
// ----------------------------------------
21+
// Now, test cases where there there should not be any profile metadata,
22+
// such as when no optimizations are requested, or no data is provided
23+
24+
// RUN: %target-swift-frontend %t/program.swift -module-name test -emit-ir \
25+
// RUN: -profile-sample-use=%t/profile.txt -o %t/no-optimizations.ll
26+
27+
// RUN: %FileCheck --check-prefix CHECK-NODATA %s < %t/no-optimizations.ll
28+
29+
30+
// RUN: %target-swift-frontend %t/program.swift -module-name test -emit-ir \
31+
// RUN: -O -o %t/no-data.ll
32+
33+
// RUN: %FileCheck --check-prefix CHECK-NODATA %s < %t/no-data.ll
34+
35+
36+
// CHECK-NODATA: define{{.*}} @"$s4test8anythingyyF"() #[[ATTRID:[0-9]+]]
37+
// CHECK-NODATA-NOT: attributes #[[ATTRID]] = {{.*}} "use-sample-profile"
38+
39+
// CHECK-NODATA-LABEL: !llvm.module.flags
40+
// CHECK-NODATA-NOT: Profile
41+
42+
43+
//--- program.swift
44+
public func anything() {}
45+
46+
47+
//--- profile.txt
48+
bar:100:100
49+
1: 2001

0 commit comments

Comments
 (0)