Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3033,6 +3033,14 @@ indexed format, regardeless whether it is produced by frontend or the IR pass.
overhead. ``prefer-atomic`` will be transformed to ``atomic`` when supported
by the target, or ``single`` otherwise.

.. option:: -fprofile-continuous

Enables continuous PGO mode where profile counter updates are continuously
synced to a file. This option sets any neccessary modifiers (currently ``%c``)
in the default profile filename and passes any necessary flags to the
middle-end to support this mode. Value profiling is not supported in
continuous mode.

.. option:: -ftemporal-profile

Enables the temporal profiling extension for IRPGO to improve startup time by
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ AFFECTING_VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option spec
AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.

CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic
CODEGENOPT(ContinuousProfileSync, 1, 0) ///< Enable continuous PGO mode
/// Choose profile instrumenation kind or no instrumentation.
ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone)
/// Choose profile kind for PGO use compilation.
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,11 @@ def fprofile_update_EQ : Joined<["-"], "fprofile-update=">,
Values<"atomic,prefer-atomic,single">,
MetaVarName<"<method>">, HelpText<"Set update method of profile counters">,
MarshallingInfoFlag<CodeGenOpts<"AtomicProfileUpdate">>;
def fprofile_continuous : Flag<["-"], "fprofile-continuous">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable Continuous PGO mode">,
MarshallingInfoFlag<CodeGenOpts<"ContinuousProfileSync">>;

defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling",
CodeGenOpts<"PseudoProbeForProfiling">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption], "Emit">,
Expand Down
42 changes: 24 additions & 18 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ std::string getDefaultProfileGenName() {
: "default_%m.profraw";
}

// Path and name of file used for profile generation
std::string getProfileGenName(const CodeGenOptions &CodeGenOpts) {
std::string FileName = CodeGenOpts.InstrProfileOutput.empty()
? getDefaultProfileGenName()
: CodeGenOpts.InstrProfileOutput;
if (CodeGenOpts.ContinuousProfileSync)
FileName = "%c" + FileName;
return FileName;
}

class EmitAssemblyHelper {
CompilerInstance &CI;
DiagnosticsEngine &Diags;
Expand Down Expand Up @@ -550,7 +560,9 @@ getInstrProfOptions(const CodeGenOptions &CodeGenOpts,
return std::nullopt;
InstrProfOptions Options;
Options.NoRedZone = CodeGenOpts.DisableRedZone;
Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
Options.InstrProfileOutput = CodeGenOpts.ContinuousProfileSync
? ("%c" + CodeGenOpts.InstrProfileOutput)
: CodeGenOpts.InstrProfileOutput;
Options.Atomic = CodeGenOpts.AtomicProfileUpdate;
return Options;
}
Expand Down Expand Up @@ -811,13 +823,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline(

if (CodeGenOpts.hasProfileIRInstr())
// -fprofile-generate.
PGOOpt = PGOOptions(
CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName()
: CodeGenOpts.InstrProfileOutput,
"", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr,
PGOOptions::NoCSAction, ClPGOColdFuncAttr,
CodeGenOpts.DebugInfoForProfiling,
/*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate);
PGOOpt = PGOOptions(getProfileGenName(CodeGenOpts), "", "",
CodeGenOpts.MemoryProfileUsePath, nullptr,
PGOOptions::IRInstr, PGOOptions::NoCSAction,
ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling,
/*PseudoProbeForProfiling=*/false,
CodeGenOpts.AtomicProfileUpdate);
else if (CodeGenOpts.hasProfileIRUse()) {
// -fprofile-use.
auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse
Expand Down Expand Up @@ -861,18 +872,13 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
PGOOpt->Action != PGOOptions::SampleUse &&
"Cannot run CSProfileGen pass with ProfileGen or SampleUse "
" pass");
PGOOpt->CSProfileGenFile = CodeGenOpts.InstrProfileOutput.empty()
? getDefaultProfileGenName()
: CodeGenOpts.InstrProfileOutput;
PGOOpt->CSProfileGenFile = getProfileGenName(CodeGenOpts);
PGOOpt->CSAction = PGOOptions::CSIRInstr;
} else
PGOOpt = PGOOptions("",
CodeGenOpts.InstrProfileOutput.empty()
? getDefaultProfileGenName()
: CodeGenOpts.InstrProfileOutput,
"", /*MemoryProfile=*/"", nullptr,
PGOOptions::NoAction, PGOOptions::CSIRInstr,
ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling);
PGOOpt = PGOOptions("", getProfileGenName(CodeGenOpts), "",
/*MemoryProfile=*/"", nullptr, PGOOptions::NoAction,
PGOOptions::CSIRInstr, ClPGOColdFuncAttr,
CodeGenOpts.DebugInfoForProfiling);
}
if (TM)
TM->setPGOOption(PGOOpt);
Expand Down
29 changes: 29 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
const ArgList &Args, SanitizerArgs &SanArgs,
ArgStringList &CmdArgs) {
const Driver &D = TC.getDriver();
const llvm::Triple &T = TC.getTriple();
auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate,
options::OPT_fprofile_generate_EQ,
options::OPT_fno_profile_generate);
Expand Down Expand Up @@ -785,6 +786,34 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getSpelling() << Val;
}
if (const auto *A = Args.getLastArg(options::OPT_fprofile_continuous)) {
if (!PGOGenerateArg && !CSPGOGenerateArg && !ProfileGenerateArg)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< A->getSpelling()
<< "-fprofile-generate, -fprofile-instr-generate, or "
"-fcs-profile-generate";
else {
CmdArgs.push_back("-fprofile-continuous");
// Platforms that require a bias variable:
if (T.isOSFuchsia() || T.isOSBinFormatELF() || T.isOSAIX()) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-runtime-counter-relocation");
}
// -fprofile-instr-generate does not decide the profile file name in the
// FE, and so it does not define the filename symbol
// (__llvm_profile_filename). Instead, the runtime uses the name
// "default.profraw" for the profile file. When continuous mode is ON, we
// will create the filename symbol so that we can insert the "%c"
// modifier.
if (ProfileGenerateArg &&
(ProfileGenerateArg->getOption().matches(
options::OPT_fprofile_instr_generate) ||
(ProfileGenerateArg->getOption().matches(
options::OPT_fprofile_instr_generate_EQ) &&
strlen(ProfileGenerateArg->getValue()) == 0)))
CmdArgs.push_back("-fprofile-instrument-path=default.profraw");
}
}

int FunctionGroups = 1;
int SelectedFunctionGroup = 0;
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CodeGen/profile-continuous.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %clang %s -S -emit-llvm -fprofile-generate -fprofile-continuous -o - | FileCheck %s --check-prefix=IRPGO
// RUN: %clang %s -S -emit-llvm -fprofile-generate=mydir -fprofile-continuous -o - | FileCheck %s --check-prefix=IRPGO_EQ
// RUN: %clang %s -S -emit-llvm -fcs-profile-generate -fprofile-continuous -O -o - | FileCheck %s --check-prefix=CSIRPGO
// RUN: %clang %s -S -emit-llvm -fprofile-instr-generate -fprofile-continuous -o - | FileCheck %s --check-prefix=CLANG_PGO
// RUN: %clang %s -S -emit-llvm -fprofile-instr-generate= -fprofile-continuous -o - | FileCheck %s --check-prefix=CLANG_PGO
// RUN: %clang %s -S -emit-llvm -fprofile-instr-generate=foo.profraw -fprofile-continuous -o - | FileCheck %s --check-prefix=CLANG_PGO_EQ

// RUN: not %clang -### %s -fprofile-continuous -c 2>&1 | FileCheck %s --check-prefix=ERROR

// IRPGO: @__llvm_profile_filename = {{.*}} c"%cdefault_%m.profraw\00"
// IRPGO_EQ: @__llvm_profile_filename = {{.*}} c"%cmydir/default_%m.profraw\00"
// CSIRPGO: @__llvm_profile_filename = {{.*}} c"%cdefault_%m.profraw\00"
// CLANG_PGO: @__llvm_profile_filename = {{.*}} c"%cdefault.profraw\00"
// CLANG_PGO_EQ: @__llvm_profile_filename = {{.*}} c"%cfoo.profraw\00"
// ERROR: clang: error: invalid argument '-fprofile-continuous' only allowed with '-fprofile-generate, -fprofile-instr-generate, or -fcs-profile-generate'
void foo(){}
Loading