Add GCC-compatible flags -fprofile-generate and -fprofile-use.
This patch adds support for specifying where the profile is emitted in a
way similar to GCC. These flags are used to specify directories instead
of filenames. When -fprofile-generate=DIR is used, the compiler will
generate code to write to <DIR>/default.profraw.
The patch also adds a couple of extensions: LLVM_PROFILE_FILE can still be
used to override the directory and file name to use and -fprofile-use
accepts both directories and filenames.
To simplify the set of flags used in the backend, all the flags get
canonicalized to -fprofile-instr-{generate,use} when passed to the
backend. The decision to use a default name for the profile is done
in the driver.
llvm-svn: 241825
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 1795ccf..6a1ac11 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -2298,6 +2298,7 @@
if (!(Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
false) ||
Args.hasArg(options::OPT_fprofile_generate) ||
+ Args.hasArg(options::OPT_fprofile_generate_EQ) ||
Args.hasArg(options::OPT_fprofile_instr_generate) ||
Args.hasArg(options::OPT_fprofile_instr_generate_EQ) ||
Args.hasArg(options::OPT_fcreate_profile) ||
@@ -3532,23 +3533,47 @@
Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
- if ((Args.hasArg(options::OPT_fprofile_instr_generate) ||
- Args.hasArg(options::OPT_fprofile_instr_generate_EQ)) &&
- (Args.hasArg(options::OPT_fprofile_instr_use) ||
- Args.hasArg(options::OPT_fprofile_instr_use_EQ)))
- D.Diag(diag::err_drv_argument_not_allowed_with)
- << "-fprofile-instr-generate"
- << "-fprofile-instr-use";
+ auto *ProfileGenerateArg = Args.getLastArg(
+ options::OPT_fprofile_instr_generate,
+ options::OPT_fprofile_instr_generate_EQ, options::OPT_fprofile_generate,
+ options::OPT_fprofile_generate_EQ);
- if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_generate_EQ))
- A->render(Args, CmdArgs);
- else
+ auto *ProfileUseArg = Args.getLastArg(
+ options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ,
+ options::OPT_fprofile_use, options::OPT_fprofile_use_EQ);
+
+ if (ProfileGenerateArg && ProfileUseArg)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << ProfileGenerateArg->getSpelling()
+ << ProfileUseArg->getSpelling();
+
+ if (ProfileGenerateArg &&
+ ProfileGenerateArg->getOption().matches(
+ options::OPT_fprofile_instr_generate_EQ))
+ ProfileGenerateArg->render(Args, CmdArgs);
+ else if (ProfileGenerateArg &&
+ ProfileGenerateArg->getOption().matches(
+ options::OPT_fprofile_generate_EQ)) {
+ SmallString<128> Path(ProfileGenerateArg->getValue());
+ llvm::sys::path::append(Path, "default.profraw");
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("-fprofile-instr-generate=") + Path));
+ } else
Args.AddAllArgs(CmdArgs, options::OPT_fprofile_instr_generate);
- if (Arg *A = Args.getLastArg(options::OPT_fprofile_instr_use_EQ))
- A->render(Args, CmdArgs);
- else if (Args.hasArg(options::OPT_fprofile_instr_use))
- CmdArgs.push_back("-fprofile-instr-use=pgo-data");
+ if (ProfileUseArg &&
+ ProfileUseArg->getOption().matches(options::OPT_fprofile_instr_use_EQ))
+ ProfileUseArg->render(Args, CmdArgs);
+ else if (ProfileUseArg &&
+ (ProfileUseArg->getOption().matches(options::OPT_fprofile_use_EQ) ||
+ ProfileUseArg->getOption().matches(
+ options::OPT_fprofile_instr_use))) {
+ SmallString<128> Path(
+ ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue());
+ if (Path.empty() || llvm::sys::fs::is_directory(Path))
+ llvm::sys::path::append(Path, "default.profdata");
+ CmdArgs.push_back(Args.MakeArgString(Twine("-fprofile-instr-use=") + Path));
+ }
if (Args.hasArg(options::OPT_ftest_coverage) ||
Args.hasArg(options::OPT_coverage))
@@ -3558,9 +3583,7 @@
Args.hasArg(options::OPT_coverage))
CmdArgs.push_back("-femit-coverage-data");
- if (Args.hasArg(options::OPT_fcoverage_mapping) &&
- !(Args.hasArg(options::OPT_fprofile_instr_generate) ||
- Args.hasArg(options::OPT_fprofile_instr_generate_EQ)))
+ if (Args.hasArg(options::OPT_fcoverage_mapping) && !ProfileGenerateArg)
D.Diag(diag::err_drv_argument_only_allowed_with)
<< "-fcoverage-mapping"
<< "-fprofile-instr-generate";