diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2759,9 +2759,6 @@ overhead. ``prefer-atomic`` will be transformed to ``atomic`` when supported by the target, or ``single`` otherwise. - This option currently works with ``-fprofile-arcs`` and ``-fprofile-instr-generate``, - but not with ``-fprofile-generate``. - Disabling Instrumentation ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -768,7 +768,8 @@ CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName() : CodeGenOpts.InstrProfileOutput, "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr, - PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling); + PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling, + /* PseudoProbeForProfiling */ false, CodeGenOpts.AtomicProfileUpdate); else if (CodeGenOpts.hasProfileIRUse()) { // -fprofile-use. auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse diff --git a/clang/test/CodeGen/tsan-instrprof-atomic.c b/clang/test/CodeGen/tsan-instrprof-atomic.c --- a/clang/test/CodeGen/tsan-instrprof-atomic.c +++ b/clang/test/CodeGen/tsan-instrprof-atomic.c @@ -1,4 +1,6 @@ // RUN: %clang_cc1 %s -emit-llvm -fprofile-instrument=clang -fprofile-update=atomic -o - | FileCheck %s +// RUN: %clang %s -S -emit-llvm -fprofile-generate -fprofile-update=atomic -o - | FileCheck %s +// RUN: %clang -O3 %s -S -emit-llvm -fprofile-generate -fprofile-update=atomic -o - | FileCheck %s // CHECK: define {{.*}}@foo // CHECK-NOT: load {{.*}}foo diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -560,7 +560,8 @@ /// Add PGOInstrumenation passes for O0 only. void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen, - bool IsCS, std::string ProfileFile, + bool IsCS, bool AtomicCounterUpdate, + std::string ProfileFile, std::string ProfileRemappingFile, IntrusiveRefCntPtr FS); @@ -628,7 +629,8 @@ ArrayRef Pipeline); void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level, - bool RunProfileGen, bool IsCS, std::string ProfileFile, + bool RunProfileGen, bool IsCS, + bool AtomicCounterUpdate, std::string ProfileFile, std::string ProfileRemappingFile, ThinOrFullLTOPhase LTOPhase, IntrusiveRefCntPtr FS); diff --git a/llvm/include/llvm/Support/PGOOptions.h b/llvm/include/llvm/Support/PGOOptions.h --- a/llvm/include/llvm/Support/PGOOptions.h +++ b/llvm/include/llvm/Support/PGOOptions.h @@ -32,7 +32,8 @@ IntrusiveRefCntPtr FS, PGOAction Action = NoAction, CSPGOAction CSAction = NoCSAction, bool DebugInfoForProfiling = false, - bool PseudoProbeForProfiling = false); + bool PseudoProbeForProfiling = false, + bool AtomicCounterUpdate = false); PGOOptions(const PGOOptions &); ~PGOOptions(); PGOOptions &operator=(const PGOOptions &); @@ -45,6 +46,7 @@ CSPGOAction CSAction; bool DebugInfoForProfiling; bool PseudoProbeForProfiling; + bool AtomicCounterUpdate; IntrusiveRefCntPtr FS; }; } // namespace llvm diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -724,7 +724,8 @@ void PassBuilder::addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level, bool RunProfileGen, - bool IsCS, std::string ProfileFile, + bool IsCS, bool AtomicCounterUpdate, + std::string ProfileFile, std::string ProfileRemappingFile, ThinOrFullLTOPhase LTOPhase, IntrusiveRefCntPtr FS) { @@ -793,13 +794,14 @@ // Do counter promotion at Level greater than O0. Options.DoCounterPromotion = true; Options.UseBFIInPromotion = IsCS; + Options.Atomic = AtomicCounterUpdate; MPM.addPass(InstrProfiling(Options, IsCS)); } void PassBuilder::addPGOInstrPassesForO0( ModulePassManager &MPM, bool RunProfileGen, bool IsCS, - std::string ProfileFile, std::string ProfileRemappingFile, - IntrusiveRefCntPtr FS) { + bool AtomicCounterUpdate, std::string ProfileFile, + std::string ProfileRemappingFile, IntrusiveRefCntPtr FS) { if (!RunProfileGen) { assert(!ProfileFile.empty() && "Profile use expecting a profile file!"); MPM.addPass( @@ -819,6 +821,7 @@ // Do not do counter promotion at O0. Options.DoCounterPromotion = false; Options.UseBFIInPromotion = IsCS; + Options.Atomic = AtomicCounterUpdate; MPM.addPass(InstrProfiling(Options, IsCS)); } @@ -1094,8 +1097,9 @@ PGOOpt->Action == PGOOptions::IRUse)) { addPGOInstrPasses(MPM, Level, /* RunProfileGen */ PGOOpt->Action == PGOOptions::IRInstr, - /* IsCS */ false, PGOOpt->ProfileFile, - PGOOpt->ProfileRemappingFile, Phase, PGOOpt->FS); + /* IsCS */ false, PGOOpt->AtomicCounterUpdate, + PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile, Phase, + PGOOpt->FS); MPM.addPass(PGOIndirectCallPromotion(false, false)); } if (PGOOpt && Phase != ThinOrFullLTOPhase::ThinLTOPostLink && @@ -1307,12 +1311,14 @@ if (!LTOPreLink && PGOOpt) { if (PGOOpt->CSAction == PGOOptions::CSIRInstr) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ true, - /* IsCS */ true, PGOOpt->CSProfileGenFile, - PGOOpt->ProfileRemappingFile, LTOPhase, PGOOpt->FS); + /* IsCS */ true, PGOOpt->AtomicCounterUpdate, + PGOOpt->CSProfileGenFile, PGOOpt->ProfileRemappingFile, + LTOPhase, PGOOpt->FS); else if (PGOOpt->CSAction == PGOOptions::CSIRUse) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ false, - /* IsCS */ true, PGOOpt->ProfileFile, - PGOOpt->ProfileRemappingFile, LTOPhase, PGOOpt->FS); + /* IsCS */ true, PGOOpt->AtomicCounterUpdate, + PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile, + LTOPhase, PGOOpt->FS); } // Re-compute GlobalsAA here prior to function passes. This is particularly @@ -1788,13 +1794,13 @@ if (PGOOpt) { if (PGOOpt->CSAction == PGOOptions::CSIRInstr) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ true, - /* IsCS */ true, PGOOpt->CSProfileGenFile, - PGOOpt->ProfileRemappingFile, + /* IsCS */ true, PGOOpt->AtomicCounterUpdate, + PGOOpt->CSProfileGenFile, PGOOpt->ProfileRemappingFile, ThinOrFullLTOPhase::FullLTOPostLink, PGOOpt->FS); else if (PGOOpt->CSAction == PGOOptions::CSIRUse) addPGOInstrPasses(MPM, Level, /* RunProfileGen */ false, - /* IsCS */ true, PGOOpt->ProfileFile, - PGOOpt->ProfileRemappingFile, + /* IsCS */ true, PGOOpt->AtomicCounterUpdate, + PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile, ThinOrFullLTOPhase::FullLTOPostLink, PGOOpt->FS); } @@ -1940,8 +1946,8 @@ addPGOInstrPassesForO0( MPM, /* RunProfileGen */ (PGOOpt->Action == PGOOptions::IRInstr), - /* IsCS */ false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile, - PGOOpt->FS); + /* IsCS */ false, PGOOpt->AtomicCounterUpdate, PGOOpt->ProfileFile, + PGOOpt->ProfileRemappingFile, PGOOpt->FS); invokePipelineStartEPCallbacks(MPM, Level); diff --git a/llvm/lib/Support/PGOOptions.cpp b/llvm/lib/Support/PGOOptions.cpp --- a/llvm/lib/Support/PGOOptions.cpp +++ b/llvm/lib/Support/PGOOptions.cpp @@ -16,13 +16,14 @@ std::string MemoryProfile, IntrusiveRefCntPtr FS, PGOAction Action, CSPGOAction CSAction, bool DebugInfoForProfiling, - bool PseudoProbeForProfiling) + bool PseudoProbeForProfiling, bool AtomicCounterUpdate) : ProfileFile(ProfileFile), CSProfileGenFile(CSProfileGenFile), ProfileRemappingFile(ProfileRemappingFile), MemoryProfile(MemoryProfile), Action(Action), CSAction(CSAction), DebugInfoForProfiling(DebugInfoForProfiling || (Action == SampleUse && !PseudoProbeForProfiling)), - PseudoProbeForProfiling(PseudoProbeForProfiling), FS(std::move(FS)) { + PseudoProbeForProfiling(PseudoProbeForProfiling), + AtomicCounterUpdate(AtomicCounterUpdate), FS(std::move(FS)) { // Note, we do allow ProfileFile.empty() for Action=IRUse LTO can // callback with IRUse action without ProfileFile.