https://github.com/fanju110 updated https://github.com/llvm/llvm-project/pull/142892
>From 22ff984bae53f2b51b6046c36077e2eb3a3a2b7c Mon Sep 17 00:00:00 2001 From: fanyikang <fanju...@163.com> Date: Thu, 5 Jun 2025 11:24:33 +0800 Subject: [PATCH] Fix and reapply IR PGO support for Flang Fix and reapply IR PGO support for Flang Co-Authored-By: ict-ql <168183727+ict...@users.noreply.github.com> Co-Authored-By: Chyaka <52224511+liliumsh...@users.noreply.github.com> --- clang/include/clang/Basic/CodeGenOptions.def | 6 ++- clang/include/clang/Basic/CodeGenOptions.h | 22 +++++++---- clang/include/clang/Basic/ProfileList.h | 9 ++--- clang/include/clang/Driver/Options.td | 4 +- clang/lib/Basic/ProfileList.cpp | 20 +++++----- clang/lib/CodeGen/BackendUtil.cpp | 9 +---- clang/lib/CodeGen/CodeGenAction.cpp | 4 +- clang/lib/CodeGen/CodeGenFunction.cpp | 3 +- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/Driver/ToolChains/Flang.cpp | 4 ++ clang/lib/Frontend/CompilerInvocation.cpp | 6 +-- .../include/flang/Frontend/CodeGenOptions.def | 7 ++++ flang/include/flang/Frontend/CodeGenOptions.h | 38 +++++++++++++++++++ flang/lib/Frontend/CompilerInvocation.cpp | 10 +++++ flang/lib/Frontend/FrontendActions.cpp | 26 +++++++++++++ flang/test/Driver/flang-f-opts.f90 | 5 +++ .../Inputs/gcc-flag-compatibility_IR.proftext | 18 +++++++++ .../gcc-flag-compatibility_IR_entry.proftext | 11 ++++++ flang/test/Profile/gcc-flag-compatibility.f90 | 32 ++++++++++++++++ .../llvm/Frontend/Driver/CodeGenOptions.h | 11 ++++++ llvm/lib/Frontend/Driver/CMakeLists.txt | 1 + llvm/lib/Frontend/Driver/CodeGenOptions.cpp | 13 +++++++ 22 files changed, 219 insertions(+), 42 deletions(-) create mode 100644 flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext create mode 100644 flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext create mode 100644 flang/test/Profile/gcc-flag-compatibility.f90 diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index aad4e107cbeb3..11dad53a52efe 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -223,9 +223,11 @@ AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic CODEGENOPT(ContinuousProfileSync, 1, 0) ///< Enable continuous instrumentation profiling /// Choose profile instrumenation kind or no instrumentation. -ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 4, ProfileNone) + +ENUM_CODEGENOPT(ProfileInstr, llvm::driver::ProfileInstrKind, 4, llvm::driver::ProfileInstrKind::ProfileNone) + /// Choose profile kind for PGO use compilation. -ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone) +ENUM_CODEGENOPT(ProfileUse, llvm::driver::ProfileInstrKind, 2, llvm::driver::ProfileInstrKind::ProfileNone) /// Partition functions into N groups and select only functions in group i to be /// instrumented. Selected group numbers can be 0 to N-1 inclusive. VALUE_CODEGENOPT(ProfileTotalFunctionGroups, 32, 1) diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 278803f7bb960..bffbd00b1bd72 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -518,35 +518,41 @@ class CodeGenOptions : public CodeGenOptionsBase { /// Check if Clang profile instrumenation is on. bool hasProfileClangInstr() const { - return getProfileInstr() == ProfileClangInstr; + return getProfileInstr() == + llvm::driver::ProfileInstrKind::ProfileClangInstr; } /// Check if IR level profile instrumentation is on. bool hasProfileIRInstr() const { - return getProfileInstr() == ProfileIRInstr; + return getProfileInstr() == llvm::driver::ProfileInstrKind::ProfileIRInstr; } /// Check if CS IR level profile instrumentation is on. bool hasProfileCSIRInstr() const { - return getProfileInstr() == ProfileCSIRInstr; + return getProfileInstr() == + llvm::driver::ProfileInstrKind::ProfileCSIRInstr; } /// Check if any form of instrumentation is on. - bool hasProfileInstr() const { return getProfileInstr() != ProfileNone; } + bool hasProfileInstr() const { + return getProfileInstr() != llvm::driver::ProfileInstrKind::ProfileNone; + } /// Check if Clang profile use is on. bool hasProfileClangUse() const { - return getProfileUse() == ProfileClangInstr; + return getProfileUse() == llvm::driver::ProfileInstrKind::ProfileClangInstr; } /// Check if IR level profile use is on. bool hasProfileIRUse() const { - return getProfileUse() == ProfileIRInstr || - getProfileUse() == ProfileCSIRInstr; + return getProfileUse() == llvm::driver::ProfileInstrKind::ProfileIRInstr || + getProfileUse() == llvm::driver::ProfileInstrKind::ProfileCSIRInstr; } /// Check if CSIR profile use is on. - bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; } + bool hasProfileCSIRUse() const { + return getProfileUse() == llvm::driver::ProfileInstrKind::ProfileCSIRInstr; + } /// Check if type and variable info should be emitted. bool hasReducedDebugInfo() const { diff --git a/clang/include/clang/Basic/ProfileList.h b/clang/include/clang/Basic/ProfileList.h index b4217e49c18a3..5338ef3992ade 100644 --- a/clang/include/clang/Basic/ProfileList.h +++ b/clang/include/clang/Basic/ProfileList.h @@ -49,17 +49,16 @@ class ProfileList { ~ProfileList(); bool isEmpty() const { return Empty; } - ExclusionType getDefault(CodeGenOptions::ProfileInstrKind Kind) const; + ExclusionType getDefault(llvm::driver::ProfileInstrKind Kind) const; std::optional<ExclusionType> isFunctionExcluded(StringRef FunctionName, - CodeGenOptions::ProfileInstrKind Kind) const; + llvm::driver::ProfileInstrKind Kind) const; std::optional<ExclusionType> isLocationExcluded(SourceLocation Loc, - CodeGenOptions::ProfileInstrKind Kind) const; + llvm::driver::ProfileInstrKind Kind) const; std::optional<ExclusionType> - isFileExcluded(StringRef FileName, - CodeGenOptions::ProfileInstrKind Kind) const; + isFileExcluded(StringRef FileName, llvm::driver::ProfileInstrKind Kind) const; }; } // namespace clang diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5ca31c253ed8f..5c79c66b55eb3 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1772,7 +1772,7 @@ def fmcdc_max_test_vectors_EQ : Joined<["-"], "fmcdc-max-test-vectors=">, HelpText<"Maximum number of test vectors in MC/DC coverage">, MarshallingInfoInt<CodeGenOpts<"MCDCMaxTVs">, "0x7FFFFFFE">; def fprofile_generate : Flag<["-"], "fprofile-generate">, - Group<f_Group>, Visibility<[ClangOption, CLOption]>, + Group<f_Group>, Visibility<[ClangOption, CLOption, FlangOption, FC1Option]>, HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">, Group<f_Group>, Visibility<[ClangOption, CLOption]>, @@ -1789,7 +1789,7 @@ def fprofile_use : Flag<["-"], "fprofile-use">, Group<f_Group>, Visibility<[ClangOption, CLOption]>, Alias<fprofile_instr_use>; def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<f_Group>, - Visibility<[ClangOption, CLOption]>, + Visibility<[ClangOption, CLOption, FlangOption, FC1Option]>, MetaVarName<"<pathname>">, HelpText<"Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from <pathname>/default.profdata. Otherwise, it reads from file <pathname>.">; def fno_profile_instr_generate : Flag<["-"], "fno-profile-instr-generate">, diff --git a/clang/lib/Basic/ProfileList.cpp b/clang/lib/Basic/ProfileList.cpp index aaea5a00ab6ae..a7deb589d280f 100644 --- a/clang/lib/Basic/ProfileList.cpp +++ b/clang/lib/Basic/ProfileList.cpp @@ -69,24 +69,24 @@ ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM) ProfileList::~ProfileList() = default; -static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) { +static StringRef getSectionName(llvm::driver::ProfileInstrKind Kind) { switch (Kind) { - case CodeGenOptions::ProfileNone: + case llvm::driver::ProfileInstrKind::ProfileNone: return ""; - case CodeGenOptions::ProfileClangInstr: + case llvm::driver::ProfileInstrKind::ProfileClangInstr: return "clang"; - case CodeGenOptions::ProfileIRInstr: + case llvm::driver::ProfileInstrKind::ProfileIRInstr: return "llvm"; - case CodeGenOptions::ProfileCSIRInstr: + case llvm::driver::ProfileInstrKind::ProfileCSIRInstr: return "csllvm"; case CodeGenOptions::ProfileIRSampleColdCov: return "sample-coldcov"; } - llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum"); + llvm_unreachable("Unhandled llvm::driver::ProfileInstrKind enum"); } ProfileList::ExclusionType -ProfileList::getDefault(CodeGenOptions::ProfileInstrKind Kind) const { +ProfileList::getDefault(llvm::driver::ProfileInstrKind Kind) const { StringRef Section = getSectionName(Kind); // Check for "default:<type>" if (SCL->inSection(Section, "default", "allow")) @@ -117,7 +117,7 @@ ProfileList::inSection(StringRef Section, StringRef Prefix, std::optional<ProfileList::ExclusionType> ProfileList::isFunctionExcluded(StringRef FunctionName, - CodeGenOptions::ProfileInstrKind Kind) const { + llvm::driver::ProfileInstrKind Kind) const { StringRef Section = getSectionName(Kind); // Check for "function:<regex>=<case>" if (auto V = inSection(Section, "function", FunctionName)) @@ -131,13 +131,13 @@ ProfileList::isFunctionExcluded(StringRef FunctionName, std::optional<ProfileList::ExclusionType> ProfileList::isLocationExcluded(SourceLocation Loc, - CodeGenOptions::ProfileInstrKind Kind) const { + llvm::driver::ProfileInstrKind Kind) const { return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind); } std::optional<ProfileList::ExclusionType> ProfileList::isFileExcluded(StringRef FileName, - CodeGenOptions::ProfileInstrKind Kind) const { + llvm::driver::ProfileInstrKind Kind) const { StringRef Section = getSectionName(Kind); // Check for "source:<regex>=<case>" if (auto V = inSection(Section, "source", FileName)) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index cd5fc48c4a22b..eeb35b53b3afc 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -123,17 +123,10 @@ namespace clang { extern llvm::cl::opt<bool> ClSanitizeGuardChecks; } -// Default filename used for profile generation. -static std::string getDefaultProfileGenName() { - return DebugInfoCorrelate || ProfileCorrelate != InstrProfCorrelator::NONE - ? "default_%m.proflite" - : "default_%m.profraw"; -} - // Path and name of file used for profile generation static std::string getProfileGenName(const CodeGenOptions &CodeGenOpts) { std::string FileName = CodeGenOpts.InstrProfileOutput.empty() - ? getDefaultProfileGenName() + ? llvm::driver::getDefaultProfileGenName() : CodeGenOpts.InstrProfileOutput; if (CodeGenOpts.ContinuousProfileSync) FileName = "%c" + FileName; diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 1f5eb427b566f..5493cc92bd8b0 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -273,8 +273,8 @@ void BackendConsumer::HandleTranslationUnit(ASTContext &C) { std::unique_ptr<llvm::ToolOutputFile> OptRecordFile = std::move(*OptRecordFileOrErr); - if (OptRecordFile && - CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) + if (OptRecordFile && CodeGenOpts.getProfileUse() != + llvm::driver::ProfileInstrKind::ProfileNone) Ctx.setDiagnosticsHotnessRequested(true); if (CodeGenOpts.MisExpect) { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 2ac7e9d498044..7d1f1744226e5 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -943,7 +943,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } } - if (CGM.getCodeGenOpts().getProfileInstr() != CodeGenOptions::ProfileNone) { + if (CGM.getCodeGenOpts().getProfileInstr() != + llvm::driver::ProfileInstrKind::ProfileNone) { switch (CGM.isFunctionBlockedFromProfileInstr(Fn, Loc)) { case ProfileList::Skip: Fn->addFnAttr(llvm::Attribute::SkipProfile); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 468fc6e0e5c56..dcc018c73caf2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3601,7 +3601,7 @@ CodeGenModule::isFunctionBlockedByProfileList(llvm::Function *Fn, // If the profile list is empty, then instrument everything. if (ProfileList.isEmpty()) return ProfileList::Allow; - CodeGenOptions::ProfileInstrKind Kind = getCodeGenOpts().getProfileInstr(); + llvm::driver::ProfileInstrKind Kind = getCodeGenOpts().getProfileInstr(); // First, check the function name. if (auto V = ProfileList.isFunctionExcluded(Fn->getName(), Kind)) return *V; diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index dcc46469df3e9..e303631cc1d57 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -883,6 +883,10 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, // TODO: Handle interactions between -w, -pedantic, -Wall, -WOption Args.AddLastArg(CmdArgs, options::OPT_w); + // recognise options: fprofile-generate -fprofile-use= + Args.addAllArgs( + CmdArgs, {options::OPT_fprofile_generate, options::OPT_fprofile_use_EQ}); + // Forward flags for OpenMP. We don't do this if the current action is an // device offloading action other than OpenMP. if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2c02719121c73..dd021ad2e441b 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1492,11 +1492,11 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts, // which is available (might be one or both). if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) { if (PGOReader->hasCSIRLevelProfile()) - Opts.setProfileUse(CodeGenOptions::ProfileCSIRInstr); + Opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileCSIRInstr); else - Opts.setProfileUse(CodeGenOptions::ProfileIRInstr); + Opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileIRInstr); } else - Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); + Opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileClangInstr); } void CompilerInvocation::setDefaultPointerAuthOptions( diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index a697872836569..ae12aec518108 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -24,8 +24,15 @@ CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. + +/// Choose profile instrumenation kind or no instrumentation. +ENUM_CODEGENOPT(ProfileInstr, llvm::driver::ProfileInstrKind, 2, llvm::driver::ProfileInstrKind::ProfileNone) +/// Choose profile kind for PGO use compilation. +ENUM_CODEGENOPT(ProfileUse, llvm::driver::ProfileInstrKind, 2, llvm::driver::ProfileInstrKind::ProfileNone) + CODEGENOPT(InstrumentFunctions, 1, 0) ///< Set when -finstrument_functions is ///< enabled on the compile step. + CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level. CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module. CODEGENOPT(PrepareForFullLTO , 1, 0) ///< Set when -flto is enabled on the diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 61e56e51c4bbb..06203670f97b9 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -151,6 +151,44 @@ class CodeGenOptions : public CodeGenOptionsBase { /// OpenMP is enabled. using DoConcurrentMappingKind = flangomp::DoConcurrentMappingKind; + /// Name of the profile file to use as output for -fprofile-instr-generate, + /// -fprofile-generate, and -fcs-profile-generate. + std::string InstrProfileOutput; + + /// Name of the profile file to use as input for -fmemory-profile-use. + std::string MemoryProfileUsePath; + + /// Name of the profile file to use as input for -fprofile-instr-use + std::string ProfileInstrumentUsePath; + + /// Name of the profile remapping file to apply to the profile data supplied + /// by -fprofile-sample-use or -fprofile-instr-use. + std::string ProfileRemappingFile; + + /// Check if Clang profile instrumenation is on. + bool hasProfileClangInstr() const { + return getProfileInstr() == llvm::driver::ProfileClangInstr; + } + + /// Check if IR level profile instrumentation is on. + bool hasProfileIRInstr() const { + return getProfileInstr() == llvm::driver::ProfileIRInstr; + } + + /// Check if CS IR level profile instrumentation is on. + bool hasProfileCSIRInstr() const { + return getProfileInstr() == llvm::driver::ProfileCSIRInstr; + } + /// Check if IR level profile use is on. + bool hasProfileIRUse() const { + return getProfileUse() == llvm::driver::ProfileIRInstr || + getProfileUse() == llvm::driver::ProfileCSIRInstr; + } + /// Check if CSIR profile use is on. + bool hasProfileCSIRUse() const { + return getProfileUse() == llvm::driver::ProfileCSIRInstr; + } + // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) #define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 89aaee9f13853..a5c014a8d40a0 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -30,6 +30,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Frontend/Debug/Options.h" +#include "llvm/Frontend/Driver/CodeGenOptions.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" @@ -452,6 +453,15 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.IsPIE = 1; } + if (args.hasArg(clang::driver::options::OPT_fprofile_generate)) { + opts.setProfileInstr(llvm::driver::ProfileInstrKind::ProfileIRInstr); + } + + if (auto A = args.getLastArg(clang::driver::options::OPT_fprofile_use_EQ)) { + opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileIRInstr); + opts.ProfileInstrumentUsePath = A->getValue(); + } + // -mcmodel option. if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mcmodel_EQ)) { diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 012d0fdfe645f..da8fa518ab3e1 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -56,10 +56,12 @@ #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" +#include "llvm/ProfileData/InstrProfCorrelator.h" #include "llvm/Support/AMDGPUAddrSpace.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/PGOOptions.h" #include "llvm/Support/Path.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/ToolOutputFile.h" @@ -67,6 +69,7 @@ #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include <memory> #include <system_error> @@ -918,6 +921,29 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { llvm::PassInstrumentationCallbacks pic; llvm::PipelineTuningOptions pto; std::optional<llvm::PGOOptions> pgoOpt; + + if (opts.hasProfileIRInstr()) { + // -fprofile-generate. + pgoOpt = llvm::PGOOptions(opts.InstrProfileOutput.empty() + ? llvm::driver::getDefaultProfileGenName() + : opts.InstrProfileOutput, + "", "", opts.MemoryProfileUsePath, nullptr, + llvm::PGOOptions::IRInstr, + llvm::PGOOptions::NoCSAction, + llvm::PGOOptions::ColdFuncOpt::Default, false, + /*PseudoProbeForProfiling=*/false, false); + } else if (opts.hasProfileIRUse()) { + llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = + llvm::vfs::getRealFileSystem(); + // -fprofile-use. + auto CSAction = opts.hasProfileCSIRUse() ? llvm::PGOOptions::CSIRUse + : llvm::PGOOptions::NoCSAction; + pgoOpt = llvm::PGOOptions( + opts.ProfileInstrumentUsePath, "", opts.ProfileRemappingFile, + opts.MemoryProfileUsePath, VFS, llvm::PGOOptions::IRUse, CSAction, + llvm::PGOOptions::ColdFuncOpt::Default, false); + } + llvm::StandardInstrumentations si(llvmModule->getContext(), opts.DebugPassManager); si.registerCallbacks(pic, &mam); diff --git a/flang/test/Driver/flang-f-opts.f90 b/flang/test/Driver/flang-f-opts.f90 index 4493a519e2010..b972b9b7b2a59 100644 --- a/flang/test/Driver/flang-f-opts.f90 +++ b/flang/test/Driver/flang-f-opts.f90 @@ -8,3 +8,8 @@ ! CHECK-LABEL: "-fc1" ! CHECK: -ffp-contract=off ! CHECK: -O3 + +! RUN: %flang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s +! CHECK-PROFILE-GENERATE-LLVM: "-fprofile-generate" +! RUN: %flang -### -S -fprofile-use=%S %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-USE-DIR %s +! CHECK-PROFILE-USE-DIR: "-fprofile-use={{.*}}" diff --git a/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext new file mode 100644 index 0000000000000..2650fb5ebfd35 --- /dev/null +++ b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext @@ -0,0 +1,18 @@ +# IR level Instrumentation Flag +:ir +_QQmain +# Func Hash: +146835646621254984 +# Num Counters: +2 +# Counter Values: +100 +1 + +main +# Func Hash: +742261418966908927 +# Num Counters: +1 +# Counter Values: +1 \ No newline at end of file diff --git a/flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext new file mode 100644 index 0000000000000..c4a2a26557e80 --- /dev/null +++ b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext @@ -0,0 +1,11 @@ +# IR level Instrumentation Flag +:ir +:entry_first +_QQmain +# Func Hash: +146835646621254984 +# Num Counters: +2 +# Counter Values: +100 +1 \ No newline at end of file diff --git a/flang/test/Profile/gcc-flag-compatibility.f90 b/flang/test/Profile/gcc-flag-compatibility.f90 new file mode 100644 index 0000000000000..4490c45232d28 --- /dev/null +++ b/flang/test/Profile/gcc-flag-compatibility.f90 @@ -0,0 +1,32 @@ +! Tests for -fprofile-generate and -fprofile-use flag compatibility. These two +! flags behave similarly to their GCC counterparts: +! +! -fprofile-generate Generates the profile file ./default.profraw +! -fprofile-use=<dir>/file Uses the profile file <dir>/file + +! On AIX, -flto used to be required with -fprofile-generate. gcc-flag-compatibility-aix.c is used to do the testing on AIX with -flto +! RUN: %flang %s -c -S -o - -emit-llvm -fprofile-generate | FileCheck -check-prefix=PROFILE-GEN %s +! PROFILE-GEN: @__profc_{{_?}}main = {{(private|internal)}} global [1 x i64] zeroinitializer, section +! PROFILE-GEN: @__profd_{{_?}}main = + +! Check that -fprofile-use=some/path/file.prof reads some/path/file.prof +! This uses LLVM IR format profile. +! RUN: rm -rf %t.dir +! RUN: mkdir -p %t.dir/some/path +! RUN: llvm-profdata merge %S/Inputs/gcc-flag-compatibility_IR.proftext -o %t.dir/some/path/file.prof +! RUN: %flang %s -o - -emit-llvm -S -fprofile-use=%t.dir/some/path/file.prof | FileCheck -check-prefix=PROFILE-USE-IR1 %s +! RUN: llvm-profdata merge %S/Inputs/gcc-flag-compatibility_IR_entry.proftext -o %t.dir/some/path/file.prof +! RUN: %flang %s -o - -emit-llvm -S -fprofile-use=%t.dir/some/path/file.prof | FileCheck -check-prefix=PROFILE-USE-IR2 %s +! PROFILE-USE-IR1: = !{!"branch_weights", i32 100, i32 1} +! PROFILE-USE-IR2: = !{!"branch_weights", i32 1, i32 100} + +program main + implicit none + integer :: i + integer :: X = 0 + + do i = 0, 99 + X = X + i + end do + +end program main diff --git a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h index e8e70c0e126a9..416c6fea138ad 100644 --- a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h +++ b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h @@ -14,6 +14,7 @@ #define LLVM_FRONTEND_DRIVER_CODEGENOPTIONS_H #include "llvm/Support/Compiler.h" +#include <string> namespace llvm { class Triple; @@ -51,6 +52,16 @@ enum class VectorLibrary { LLVM_ABI TargetLibraryInfoImpl *createTLII(const llvm::Triple &TargetTriple, VectorLibrary Veclib); +enum ProfileInstrKind { + ProfileNone, // Profile instrumentation is turned off. + ProfileClangInstr, // Clang instrumentation to generate execution counts + // to use with PGO. + ProfileIRInstr, // IR level PGO instrumentation in LLVM. + ProfileCSIRInstr, // IR level PGO context sensitive instrumentation in LLVM. +}; + +// Default filename used for profile generation. +std::string getDefaultProfileGenName(); } // end namespace llvm::driver #endif diff --git a/llvm/lib/Frontend/Driver/CMakeLists.txt b/llvm/lib/Frontend/Driver/CMakeLists.txt index 23de4994a300d..9feee6fe6929b 100644 --- a/llvm/lib/Frontend/Driver/CMakeLists.txt +++ b/llvm/lib/Frontend/Driver/CMakeLists.txt @@ -12,4 +12,5 @@ add_llvm_component_library(LLVMFrontendDriver Core Support Analysis + Instrumentation ) diff --git a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp index 52080dea93c98..df884908845d2 100644 --- a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp +++ b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp @@ -8,8 +8,15 @@ #include "llvm/Frontend/Driver/CodeGenOptions.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/ProfileData/InstrProfCorrelator.h" #include "llvm/TargetParser/Triple.h" +namespace llvm { +extern llvm::cl::opt<bool> DebugInfoCorrelate; +extern llvm::cl::opt<llvm::InstrProfCorrelator::ProfCorrelatorKind> + ProfileCorrelate; +} // namespace llvm + namespace llvm::driver { TargetLibraryInfoImpl *createTLII(const llvm::Triple &TargetTriple, @@ -56,4 +63,10 @@ TargetLibraryInfoImpl *createTLII(const llvm::Triple &TargetTriple, return TLII; } +std::string getDefaultProfileGenName() { + return llvm::DebugInfoCorrelate || + llvm::ProfileCorrelate != InstrProfCorrelator::NONE + ? "default_%m.proflite" + : "default_%m.profraw"; +} } // namespace llvm::driver _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits