Skip to content

Commit 08bc2e1

Browse files
committed
Add IRPGO and CSIRPGO options to Swift
Updated config
1 parent e5b732d commit 08bc2e1

File tree

11 files changed

+129
-5
lines changed

11 files changed

+129
-5
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,16 @@ class IRGenOptions {
552552
/// or the empty string.
553553
std::string UseSampleProfile = "";
554554

555+
/// Path to the context-sensitive profile file to be used for CS-IR PGO,
556+
/// or the default string.
557+
std::string CSProfileGenFile = "default_%m.profraw";
558+
559+
/// Whether to enable context-sensitive IR PGO generation.
560+
bool EnableCSIRProfileGen = false;
561+
562+
/// Whether to enable IR level instrumentation.
563+
bool EnableIRProfileGen = false;
564+
555565
/// Controls whether DWARF discriminators are added to the IR.
556566
unsigned DebugInfoForProfiling : 1;
557567

include/swift/Option/Options.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,19 @@ def profile_sample_use : Joined<["-"], "profile-sample-use=">,
16081608
MetaVarName<"<profile data>">,
16091609
HelpText<"Supply sampling-based profiling data from llvm-profdata to enable profile-guided optimization">;
16101610

1611+
def cs_profile_generate : Flag<["-"], "cs-profile-generate">,
1612+
Flags<[FrontendOption, NoInteractiveOption]>,
1613+
HelpText<"Generate instrumented code to collect context sensitive execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
1614+
1615+
def cs_profile_generate_EQ : Joined<["-"], "cs-profile-generate=">,
1616+
Flags<[FrontendOption, NoInteractiveOption]>,
1617+
MetaVarName<"<directory>">,
1618+
HelpText<"Generate instrumented code to collect context sensitive execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
1619+
1620+
def ir_profile_generate: Flag<["-"], "ir-profile-generate">,
1621+
Flags<[FrontendOption, NoInteractiveOption]>,
1622+
HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
1623+
16111624
def embed_bitcode : Flag<["-"], "embed-bitcode">,
16121625
Flags<[FrontendOption, NoInteractiveOption]>,
16131626
HelpText<"Embed LLVM IR bitcode as data">;

lib/Driver/DarwinToolChains.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
using namespace swift;
4343
using namespace swift::driver;
4444
using namespace llvm::opt;
45+
using namespace swift::driver::toolchains;
4546

4647
std::string
4748
toolchains::Darwin::findProgramRelativeToSwiftImpl(StringRef name) const {
@@ -470,7 +471,7 @@ void
470471
toolchains::Darwin::addProfileGenerationArgs(ArgStringList &Arguments,
471472
const JobContext &context) const {
472473
const llvm::Triple &Triple = getTriple();
473-
if (context.Args.hasArg(options::OPT_profile_generate)) {
474+
if (needsInstrProfileRuntime(context.Args)) {
474475
SmallString<128> LibProfile;
475476
getClangLibraryPath(context.Args, LibProfile);
476477

lib/Driver/Driver.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,58 @@ static void validateWarningControlArgs(DiagnosticEngine &diags,
175175
}
176176
}
177177

178+
/// Validates only *generate* profiling flags and their mutual conflicts.
179+
static void validateProfilingGenerateArgs(DiagnosticEngine &diags,
180+
const ArgList &args) {
181+
const Arg *ProfileGenerate = args.getLastArg(options::OPT_profile_generate);
182+
const Arg *IRProfileGenerate =
183+
args.getLastArg(options::OPT_ir_profile_generate);
184+
const Arg *CSProfileGenerate =
185+
args.getLastArg(options::OPT_cs_profile_generate);
186+
const Arg *CSProfileGenerateEQ =
187+
args.getLastArg(options::OPT_cs_profile_generate_EQ);
188+
189+
// If both CS Profile forms were specified, report a clear conflict.
190+
if (CSProfileGenerate && CSProfileGenerateEQ) {
191+
diags.diagnose(SourceLoc(), diag::error_conflicting_options,
192+
"-cs-profile-generate", "-cs-profile-generate=");
193+
CSProfileGenerateEQ = nullptr;
194+
}
195+
196+
llvm::SmallVector<std::pair<const Arg *, const char *>, 3> gens;
197+
if (ProfileGenerate)
198+
gens.push_back({ProfileGenerate, "-profile-generate"});
199+
if (IRProfileGenerate)
200+
gens.push_back({IRProfileGenerate, "-ir-profile-generate"});
201+
if (CSProfileGenerate)
202+
gens.push_back({CSProfileGenerate, "-cs-profile-generate"});
203+
else if (CSProfileGenerateEQ)
204+
gens.push_back({CSProfileGenerateEQ, "-cs-profile-generate="});
205+
206+
// Emit pairwise conflicts if more than one generate-mode was selected
207+
for (size_t i = 0; i + 1 < gens.size(); ++i) {
208+
for (size_t j = i + 1; j < gens.size(); ++j) {
209+
diags.diagnose(SourceLoc(), diag::error_conflicting_options,
210+
gens[i].second, gens[j].second);
211+
}
212+
}
213+
}
214+
178215
static void validateProfilingArgs(DiagnosticEngine &diags,
179216
const ArgList &args) {
217+
validateProfilingGenerateArgs(diags, args);
180218
const Arg *ProfileGenerate = args.getLastArg(options::OPT_profile_generate);
181219
const Arg *ProfileUse = args.getLastArg(options::OPT_profile_use);
220+
const Arg *IRProfileGenerate =
221+
args.getLastArg(options::OPT_ir_profile_generate);
182222
if (ProfileGenerate && ProfileUse) {
183223
diags.diagnose(SourceLoc(), diag::error_conflicting_options,
184224
"-profile-generate", "-profile-use");
185225
}
226+
if (IRProfileGenerate && ProfileUse) {
227+
diags.diagnose(SourceLoc(), diag::error_conflicting_options,
228+
"-ir-profile-generate", "-profile-use");
229+
}
186230

187231
// Check if the profdata is missing
188232
if (ProfileUse && !llvm::sys::fs::exists(ProfileUse->getValue())) {

lib/Driver/ToolChains.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,15 @@ bool containsValue(
160160

161161
}
162162

163+
namespace swift::driver::toolchains {
164+
bool needsInstrProfileRuntime(const llvm::opt::ArgList &Args) {
165+
return Args.hasArg(options::OPT_profile_generate) ||
166+
Args.hasArg(options::OPT_cs_profile_generate) ||
167+
Args.hasArg(options::OPT_cs_profile_generate_EQ) ||
168+
Args.hasArg(options::OPT_ir_profile_generate);
169+
}
170+
} // namespace swift::driver::toolchains
171+
163172
void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
164173
const CommandOutput &output,
165174
const ArgList &inputArgs,
@@ -323,6 +332,8 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
323332
inputArgs.AddLastArg(arguments, options::OPT_PackageCMO);
324333
inputArgs.AddLastArg(arguments, options::OPT_profile_generate);
325334
inputArgs.AddLastArg(arguments, options::OPT_profile_use);
335+
inputArgs.AddLastArg(arguments, options::OPT_ir_profile_generate);
336+
inputArgs.AddLastArg(arguments, options::OPT_cs_profile_generate);
326337
inputArgs.AddLastArg(arguments, options::OPT_profile_coverage_mapping);
327338
inputArgs.AddAllArgs(arguments, options::OPT_warning_treating_Group);
328339
inputArgs.AddLastArg(arguments, options::OPT_sanitize_EQ);

lib/Driver/ToolChains.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ class DiagnosticEngine;
2525
namespace driver {
2626
namespace toolchains {
2727

28+
/// True if any *generation* mode of instrumentation-based profile is enabled.
29+
///
30+
/// This is used to determine if the profiler runtime should be linked.
31+
bool needsInstrProfileRuntime(const llvm::opt::ArgList &Args);
32+
2833
class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
2934
protected:
3035

lib/Driver/UnixToolChains.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
using namespace swift;
4141
using namespace swift::driver;
4242
using namespace llvm::opt;
43+
using namespace swift::driver::toolchains;
4344

4445
std::string
4546
toolchains::GenericUnix::sanitizerRuntimeLibName(StringRef Sanitizer,
@@ -330,7 +331,7 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
330331
}
331332
}
332333

333-
if (context.Args.hasArg(options::OPT_profile_generate)) {
334+
if (needsInstrProfileRuntime(context.Args)) {
334335
SmallString<128> LibProfile(SharedResourceDirPath);
335336
llvm::sys::path::remove_filename(LibProfile); // remove platform name
336337
llvm::sys::path::append(LibProfile, "clang", "lib");

lib/Driver/WebAssemblyToolChains.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
using namespace swift;
3939
using namespace swift::driver;
4040
using namespace llvm::opt;
41+
using namespace swift::driver::toolchains;
4142

4243
std::string
4344
toolchains::WebAssembly::sanitizerRuntimeLibName(StringRef Sanitizer,
@@ -168,7 +169,7 @@ toolchains::WebAssembly::constructInvocation(const DynamicLinkJobAction &job,
168169
"-fsanitize=" + getSanitizerList(context.OI.SelectedSanitizers)));
169170
}
170171

171-
if (context.Args.hasArg(options::OPT_profile_generate)) {
172+
if (needsInstrProfileRuntime(context.Args)) {
172173
SmallString<128> LibProfile(SharedResourceDirPath);
173174
llvm::sys::path::remove_filename(LibProfile); // remove platform name
174175
llvm::sys::path::append(LibProfile, "clang", "lib");

lib/Driver/WindowsToolChains.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
using namespace swift;
3737
using namespace swift::driver;
3838
using namespace llvm::opt;
39+
using namespace swift::driver::toolchains;
3940

4041
std::string toolchains::Windows::sanitizerRuntimeLibName(StringRef Sanitizer,
4142
bool shared) const {
@@ -89,7 +90,7 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
8990
// for now, which supports the behavior via a flag.
9091
// TODO: Once we've changed coverage to no longer rely on emitting
9192
// duplicate weak symbols (rdar://131295678), we can remove this.
92-
if (context.Args.getLastArg(options::OPT_profile_generate)) {
93+
if (swift::driver::toolchains::needsInstrProfileRuntime(context.Args)) {
9394
return true;
9495
}
9596
return false;
@@ -186,7 +187,7 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
186187
sanitizerRuntimeLibName("ubsan"));
187188
}
188189

189-
if (context.Args.hasArg(options::OPT_profile_generate)) {
190+
if (needsInstrProfileRuntime(context.Args)) {
190191
Arguments.push_back(context.Args.MakeArgString("-Xlinker"));
191192
Arguments.push_back(context.Args.MakeArgString(
192193
Twine({"-include:", llvm::getInstrProfRuntimeHookVarName()})));

lib/Frontend/CompilerInvocation.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3497,6 +3497,12 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
34973497
const Arg *ProfileSampleUse = Args.getLastArg(OPT_profile_sample_use);
34983498
Opts.UseSampleProfile = ProfileSampleUse ? ProfileSampleUse->getValue() : "";
34993499

3500+
Opts.EnableIRProfileGen = Args.hasArg(OPT_ir_profile_generate);
3501+
Opts.EnableCSIRProfileGen = Args.hasArg(OPT_cs_profile_generate) ||
3502+
Args.hasArg(OPT_cs_profile_generate_EQ);
3503+
if (auto V = Args.getLastArgValue(OPT_cs_profile_generate_EQ); !V.empty())
3504+
Opts.CSProfileGenFile = V.str();
3505+
35003506
Opts.DebugInfoForProfiling |= Args.hasArg(OPT_debug_info_for_profiling);
35013507

35023508

0 commit comments

Comments
 (0)