https://github.com/fanju110 updated https://github.com/llvm/llvm-project/pull/136098
>From 9494c9752400e4708dbc8b6a5ca4993ea9565e95 Mon Sep 17 00:00:00 2001 From: fanyikang <fanju...@163.com> Date: Thu, 17 Apr 2025 15:17:07 +0800 Subject: [PATCH 1/6] Add support for IR PGO (-fprofile-generate/-fprofile-use=<dir>/file) This patch implements IR-based Profile-Guided Optimization support in Flang through the following flags: -fprofile-generate for instrumentation-based profile generation -fprofile-use=<dir>/file for profile-guided optimization Co-Authored-By: ict-ql <168183727+ict...@users.noreply.github.com> --- clang/include/clang/Driver/Options.td | 4 +- clang/lib/Driver/ToolChains/Flang.cpp | 8 +++ .../include/flang/Frontend/CodeGenOptions.def | 5 ++ flang/include/flang/Frontend/CodeGenOptions.h | 49 +++++++++++++++++ flang/lib/Frontend/CompilerInvocation.cpp | 12 +++++ flang/lib/Frontend/FrontendActions.cpp | 54 +++++++++++++++++++ flang/test/Driver/flang-f-opts.f90 | 5 ++ .../Inputs/gcc-flag-compatibility_IR.proftext | 19 +++++++ .../gcc-flag-compatibility_IR_entry.proftext | 14 +++++ flang/test/Profile/gcc-flag-compatibility.f90 | 39 ++++++++++++++ 10 files changed, 207 insertions(+), 2 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/Driver/Options.td b/clang/include/clang/Driver/Options.td index affc076a876ad..0b0dbc467c1e0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1756,7 +1756,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]>, @@ -1773,7 +1773,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/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index a8b4688aed09c..fcdbe8a6aba5a 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -882,6 +882,14 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, // TODO: Handle interactions between -w, -pedantic, -Wall, -WOption Args.AddLastArg(CmdArgs, options::OPT_w); + + if (Args.hasArg(options::OPT_fprofile_generate)){ + CmdArgs.push_back("-fprofile-generate"); + } + if (const Arg *A = Args.getLastArg(options::OPT_fprofile_use_EQ)) { + CmdArgs.push_back(Args.MakeArgString(std::string("-fprofile-use=") + A->getValue())); + } + // 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/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index 57830bf51a1b3..4dec86cd8f51b 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -24,6 +24,11 @@ CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. +ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone) +ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone) +/// Whether emit extra debug info for sample pgo profile collection. +CODEGENOPT(DebugInfoForProfiling, 1, 0) +CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic 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 2b4e823b3fef4..e052250f97e75 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -148,6 +148,55 @@ class CodeGenOptions : public CodeGenOptionsBase { /// OpenMP is enabled. using DoConcurrentMappingKind = flangomp::DoConcurrentMappingKind; + 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. + }; + + + /// 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; + + unsigned int DebugInfoForProfiling; + + unsigned int AtomicProfileUpdate; + + /// 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() == ProfileClangInstr; + } + + /// Check if IR level profile instrumentation is on. + bool hasProfileIRInstr() const { + return getProfileInstr() == ProfileIRInstr; + } + + /// Check if CS IR level profile instrumentation is on. + bool hasProfileCSIRInstr() const { + return getProfileInstr() == ProfileCSIRInstr; + } + /// Check if IR level profile use is on. + bool hasProfileIRUse() const { + return getProfileUse() == ProfileIRInstr || + getProfileUse() == ProfileCSIRInstr; + } + /// Check if CSIR profile use is on. + bool hasProfileCSIRUse() const { return getProfileUse() == 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 6f87a18d69c3d..f013fce2f3cfc 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -27,6 +27,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/OptionUtils.h" #include "clang/Driver/Options.h" +#include "clang/Driver/Driver.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Frontend/Debug/Options.h" @@ -431,6 +432,17 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, opts.IsPIE = 1; } + if (args.hasArg(clang::driver::options::OPT_fprofile_generate)) { + opts.setProfileInstr(Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); + opts.DebugInfoForProfiling = args.hasArg(clang::driver::options::OPT_fdebug_info_for_profiling); + opts.AtomicProfileUpdate = args.hasArg(clang::driver::options::OPT_fprofile_update_EQ); + } + + if (auto A = args.getLastArg(clang::driver::options::OPT_fprofile_use_EQ)) { + opts.setProfileUse(Fortran::frontend::CodeGenOptions::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 c1f47b12abee2..68880bdeecf8d 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -63,11 +63,14 @@ #include "llvm/Support/Path.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/PGOOptions.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/Utils/ModuleUtils.h" +#include "llvm/Transforms/Instrumentation/InstrProfiling.h" +#include "llvm/ProfileData/InstrProfCorrelator.h" #include <memory> #include <system_error> @@ -130,6 +133,20 @@ static bool saveMLIRTempFile(const CompilerInvocation &ci, // Custom BeginSourceFileAction //===----------------------------------------------------------------------===// + +static llvm::cl::opt<llvm::PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr( + "pgo-cold-func-opt", llvm::cl::init(llvm::PGOOptions::ColdFuncOpt::Default), llvm::cl::Hidden, + llvm::cl::desc( + "Function attribute to apply to cold functions as determined by PGO"), + llvm::cl::values(clEnumValN(llvm::PGOOptions::ColdFuncOpt::Default, "default", + "Default (no attribute)"), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptSize, "optsize", + "Mark cold functions with optsize."), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::MinSize, "minsize", + "Mark cold functions with minsize."), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptNone, "optnone", + "Mark cold functions with optnone."))); + bool PrescanAction::beginSourceFileAction() { return runPrescan(); } bool PrescanAndParseAction::beginSourceFileAction() { @@ -892,6 +909,20 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, delete tlii; } + +// Default filename used for profile generation. +namespace llvm { + extern llvm::cl::opt<bool> DebugInfoCorrelate; + extern llvm::cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate; + + +std::string getDefaultProfileGenName() { + return DebugInfoCorrelate || ProfileCorrelate != llvm::InstrProfCorrelator::NONE + ? "default_%m.proflite" + : "default_%m.profraw"; +} +} + void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { CompilerInstance &ci = getInstance(); const CodeGenOptions &opts = ci.getInvocation().getCodeGenOpts(); @@ -909,6 +940,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::getDefaultProfileGenName() + : opts.InstrProfileOutput, + "", "", opts.MemoryProfileUsePath, nullptr, llvm::PGOOptions::IRInstr, + llvm::PGOOptions::NoCSAction, ClPGOColdFuncAttr, + opts.DebugInfoForProfiling, + /*PseudoProbeForProfiling=*/false, opts.AtomicProfileUpdate); + } + 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, ClPGOColdFuncAttr, + opts.DebugInfoForProfiling); + } + 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..6a6df8b1d4d5b --- /dev/null +++ b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext @@ -0,0 +1,19 @@ +# 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 + 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..9a46140286673 --- /dev/null +++ b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext @@ -0,0 +1,14 @@ +# IR level Instrumentation Flag +:ir +:entry_first +_QQmain +# Func Hash: +146835646621254984 +# Num Counters: +2 +# Counter Values: +100 +1 + + + diff --git a/flang/test/Profile/gcc-flag-compatibility.f90 b/flang/test/Profile/gcc-flag-compatibility.f90 new file mode 100644 index 0000000000000..0124bc79b87ef --- /dev/null +++ b/flang/test/Profile/gcc-flag-compatibility.f90 @@ -0,0 +1,39 @@ +! 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 >From b897c7aa1e21dfe46b4acf709f3ea38d9021c164 Mon Sep 17 00:00:00 2001 From: FYK <fanyik...@bosc.ac.cn> Date: Wed, 23 Apr 2025 09:56:14 +0800 Subject: [PATCH 2/6] Update flang/lib/Frontend/FrontendActions.cpp Remove redundant comment symbols Co-authored-by: Tom Eccles <t...@freedommail.info> --- flang/lib/Frontend/FrontendActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 68880bdeecf8d..cd13a6aca92cd 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -942,7 +942,7 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { std::optional<llvm::PGOOptions> pgoOpt; if (opts.hasProfileIRInstr()){ - // // -fprofile-generate. + // -fprofile-generate. pgoOpt = llvm::PGOOptions( opts.InstrProfileOutput.empty() ? llvm::getDefaultProfileGenName() : opts.InstrProfileOutput, >From bc5adfcc4ac3456f587bedd48c1a8892d27e53ae Mon Sep 17 00:00:00 2001 From: fanju110 <fanju...@163.com> Date: Fri, 25 Apr 2025 11:48:30 +0800 Subject: [PATCH 3/6] format code with clang-format --- flang/include/flang/Frontend/CodeGenOptions.h | 17 ++-- flang/lib/Frontend/CompilerInvocation.cpp | 15 ++-- flang/lib/Frontend/FrontendActions.cpp | 83 +++++++++---------- .../Inputs/gcc-flag-compatibility_IR.proftext | 3 +- .../gcc-flag-compatibility_IR_entry.proftext | 5 +- 5 files changed, 59 insertions(+), 64 deletions(-) diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index e052250f97e75..c9577862df832 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -156,7 +156,6 @@ class CodeGenOptions : public CodeGenOptionsBase { ProfileCSIRInstr, // IR level PGO context sensitive instrumentation in LLVM. }; - /// Name of the profile file to use as output for -fprofile-instr-generate, /// -fprofile-generate, and -fcs-profile-generate. std::string InstrProfileOutput; @@ -171,7 +170,7 @@ class CodeGenOptions : public CodeGenOptionsBase { /// 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 + /// Name of the profile remapping file to apply to the profile data supplied /// by -fprofile-sample-use or -fprofile-instr-use. std::string ProfileRemappingFile; @@ -181,19 +180,17 @@ class CodeGenOptions : public CodeGenOptionsBase { } /// Check if IR level profile instrumentation is on. - bool hasProfileIRInstr() const { - return getProfileInstr() == ProfileIRInstr; - } + bool hasProfileIRInstr() const { return getProfileInstr() == ProfileIRInstr; } /// Check if CS IR level profile instrumentation is on. bool hasProfileCSIRInstr() const { return getProfileInstr() == ProfileCSIRInstr; } - /// Check if IR level profile use is on. - bool hasProfileIRUse() const { - return getProfileUse() == ProfileIRInstr || - getProfileUse() == ProfileCSIRInstr; - } + /// Check if IR level profile use is on. + bool hasProfileIRUse() const { + return getProfileUse() == ProfileIRInstr || + getProfileUse() == ProfileCSIRInstr; + } /// Check if CSIR profile use is on. bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; } diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index f013fce2f3cfc..b28c2c0047579 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -27,7 +27,6 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/OptionUtils.h" #include "clang/Driver/Options.h" -#include "clang/Driver/Driver.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Frontend/Debug/Options.h" @@ -433,13 +432,17 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, } if (args.hasArg(clang::driver::options::OPT_fprofile_generate)) { - opts.setProfileInstr(Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); - opts.DebugInfoForProfiling = args.hasArg(clang::driver::options::OPT_fdebug_info_for_profiling); - opts.AtomicProfileUpdate = args.hasArg(clang::driver::options::OPT_fprofile_update_EQ); + opts.setProfileInstr( + Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); + opts.DebugInfoForProfiling = + args.hasArg(clang::driver::options::OPT_fdebug_info_for_profiling); + opts.AtomicProfileUpdate = + args.hasArg(clang::driver::options::OPT_fprofile_update_EQ); } - + if (auto A = args.getLastArg(clang::driver::options::OPT_fprofile_use_EQ)) { - opts.setProfileUse(Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); + opts.setProfileUse( + Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); opts.ProfileInstrumentUsePath = A->getValue(); } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index cd13a6aca92cd..8d1ab670e4db4 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -56,21 +56,21 @@ #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" -#include "llvm/Support/PGOOptions.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include "llvm/Transforms/IPO/Internalize.h" -#include "llvm/Transforms/Utils/ModuleUtils.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" -#include "llvm/ProfileData/InstrProfCorrelator.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include <memory> #include <system_error> @@ -133,19 +133,20 @@ static bool saveMLIRTempFile(const CompilerInvocation &ci, // Custom BeginSourceFileAction //===----------------------------------------------------------------------===// - static llvm::cl::opt<llvm::PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr( - "pgo-cold-func-opt", llvm::cl::init(llvm::PGOOptions::ColdFuncOpt::Default), llvm::cl::Hidden, - llvm::cl::desc( - "Function attribute to apply to cold functions as determined by PGO"), - llvm::cl::values(clEnumValN(llvm::PGOOptions::ColdFuncOpt::Default, "default", - "Default (no attribute)"), - clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptSize, "optsize", - "Mark cold functions with optsize."), - clEnumValN(llvm::PGOOptions::ColdFuncOpt::MinSize, "minsize", - "Mark cold functions with minsize."), - clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptNone, "optnone", - "Mark cold functions with optnone."))); + "pgo-cold-func-opt", llvm::cl::init(llvm::PGOOptions::ColdFuncOpt::Default), + llvm::cl::Hidden, + llvm::cl::desc( + "Function attribute to apply to cold functions as determined by PGO"), + llvm::cl::values(clEnumValN(llvm::PGOOptions::ColdFuncOpt::Default, + "default", "Default (no attribute)"), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptSize, + "optsize", "Mark cold functions with optsize."), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::MinSize, + "minsize", "Mark cold functions with minsize."), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptNone, + "optnone", + "Mark cold functions with optnone."))); bool PrescanAction::beginSourceFileAction() { return runPrescan(); } @@ -909,19 +910,18 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, delete tlii; } - // Default filename used for profile generation. namespace llvm { - extern llvm::cl::opt<bool> DebugInfoCorrelate; - extern llvm::cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate; - +extern llvm::cl::opt<bool> DebugInfoCorrelate; +extern llvm::cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate; std::string getDefaultProfileGenName() { - return DebugInfoCorrelate || ProfileCorrelate != llvm::InstrProfCorrelator::NONE + return DebugInfoCorrelate || + ProfileCorrelate != llvm::InstrProfCorrelator::NONE ? "default_%m.proflite" : "default_%m.profraw"; } -} +} // namespace llvm void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { CompilerInstance &ci = getInstance(); @@ -940,29 +940,28 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { llvm::PassInstrumentationCallbacks pic; llvm::PipelineTuningOptions pto; std::optional<llvm::PGOOptions> pgoOpt; - - if (opts.hasProfileIRInstr()){ + + if (opts.hasProfileIRInstr()) { // -fprofile-generate. pgoOpt = llvm::PGOOptions( - opts.InstrProfileOutput.empty() ? llvm::getDefaultProfileGenName() - : opts.InstrProfileOutput, - "", "", opts.MemoryProfileUsePath, nullptr, llvm::PGOOptions::IRInstr, - llvm::PGOOptions::NoCSAction, ClPGOColdFuncAttr, - opts.DebugInfoForProfiling, - /*PseudoProbeForProfiling=*/false, opts.AtomicProfileUpdate); - } - 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, ClPGOColdFuncAttr, - opts.DebugInfoForProfiling); - } - + opts.InstrProfileOutput.empty() ? llvm::getDefaultProfileGenName() + : opts.InstrProfileOutput, + "", "", opts.MemoryProfileUsePath, nullptr, llvm::PGOOptions::IRInstr, + llvm::PGOOptions::NoCSAction, ClPGOColdFuncAttr, + opts.DebugInfoForProfiling, + /*PseudoProbeForProfiling=*/false, opts.AtomicProfileUpdate); + } 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, + ClPGOColdFuncAttr, opts.DebugInfoForProfiling); + } + llvm::StandardInstrumentations si(llvmModule->getContext(), opts.DebugPassManager); si.registerCallbacks(pic, &mam); diff --git a/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext index 6a6df8b1d4d5b..2650fb5ebfd35 100644 --- a/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext +++ b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR.proftext @@ -15,5 +15,4 @@ main # Num Counters: 1 # Counter Values: -1 - +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 index 9a46140286673..c4a2a26557e80 100644 --- a/flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext +++ b/flang/test/Profile/Inputs/gcc-flag-compatibility_IR_entry.proftext @@ -8,7 +8,4 @@ _QQmain 2 # Counter Values: 100 -1 - - - +1 \ No newline at end of file >From d64d9d95fb97d6cfa4bf4192bfb20f5c8d6b3bc3 Mon Sep 17 00:00:00 2001 From: fanju110 <fanju...@163.com> Date: Fri, 25 Apr 2025 11:53:47 +0800 Subject: [PATCH 4/6] simplify push_back usage --- clang/lib/Driver/ToolChains/Flang.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index fcdbe8a6aba5a..9c7e87c455e44 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -882,13 +882,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, // TODO: Handle interactions between -w, -pedantic, -Wall, -WOption Args.AddLastArg(CmdArgs, options::OPT_w); - - if (Args.hasArg(options::OPT_fprofile_generate)){ - CmdArgs.push_back("-fprofile-generate"); - } - if (const Arg *A = Args.getLastArg(options::OPT_fprofile_use_EQ)) { - CmdArgs.push_back(Args.MakeArgString(std::string("-fprofile-use=") + A->getValue())); - } + // 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. >From 22475a85d24b22fb44ca5a5ce26542b556bae280 Mon Sep 17 00:00:00 2001 From: fanju110 <fanju...@163.com> Date: Mon, 28 Apr 2025 20:33:54 +0800 Subject: [PATCH 5/6] Port the getDefaultProfileGenName definition and the ProfileInstrKind definition from clang to the llvm namespace to allow flang to reuse these code. --- clang/include/clang/Basic/CodeGenOptions.def | 4 +- clang/include/clang/Basic/CodeGenOptions.h | 22 +++++--- clang/include/clang/Basic/ProfileList.h | 9 ++-- clang/include/clang/CodeGen/BackendUtil.h | 3 ++ clang/lib/Basic/ProfileList.cpp | 20 ++++---- clang/lib/CodeGen/BackendUtil.cpp | 50 ++++++------------- clang/lib/CodeGen/CodeGenAction.cpp | 4 +- clang/lib/CodeGen/CodeGenFunction.cpp | 3 +- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/Frontend/CompilerInvocation.cpp | 6 +-- .../include/flang/Frontend/CodeGenOptions.def | 8 +-- flang/include/flang/Frontend/CodeGenOptions.h | 28 ++++------- .../include/flang/Frontend/FrontendActions.h | 5 ++ flang/lib/Frontend/CompilerInvocation.cpp | 11 ++-- flang/lib/Frontend/FrontendActions.cpp | 28 +++-------- .../llvm/Frontend/Driver/CodeGenOptions.h | 15 +++++- llvm/lib/Frontend/Driver/CodeGenOptions.cpp | 25 ++++++++++ 17 files changed, 123 insertions(+), 120 deletions(-) diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index a436c0ec98d5b..3dbadc85f23cb 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -223,9 +223,9 @@ 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, 2, ProfileNone) +ENUM_CODEGENOPT(ProfileInstr, llvm::driver::ProfileInstrKind, 2, 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 e39a73bdb13ac..e4a74cd2c12cb 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -509,35 +509,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/CodeGen/BackendUtil.h b/clang/include/clang/CodeGen/BackendUtil.h index 92e0d13bf25b6..d9abf7bf962d2 100644 --- a/clang/include/clang/CodeGen/BackendUtil.h +++ b/clang/include/clang/CodeGen/BackendUtil.h @@ -8,6 +8,8 @@ #ifndef LLVM_CLANG_CODEGEN_BACKENDUTIL_H #define LLVM_CLANG_CODEGEN_BACKENDUTIL_H +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PGOOptions.h" #include "clang/Basic/LLVM.h" #include "llvm/IR/ModuleSummaryIndex.h" @@ -19,6 +21,7 @@ template <typename T> class Expected; template <typename T> class IntrusiveRefCntPtr; class Module; class MemoryBufferRef; +extern cl::opt<llvm::PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr; namespace vfs { class FileSystem; } // namespace vfs diff --git a/clang/lib/Basic/ProfileList.cpp b/clang/lib/Basic/ProfileList.cpp index 8fa16e2eb069a..0c5aa6de3f3c0 100644 --- a/clang/lib/Basic/ProfileList.cpp +++ b/clang/lib/Basic/ProfileList.cpp @@ -71,22 +71,22 @@ 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"; } - 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 7557cb8408921..963ed321b2cb9 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -103,38 +103,16 @@ static cl::opt<bool> ClSanitizeOnOptimizerEarlyEP( "sanitizer-early-opt-ep", cl::Optional, cl::desc("Insert sanitizers on OptimizerEarlyEP.")); -// Experiment to mark cold functions as optsize/minsize/optnone. -// TODO: remove once this is exposed as a proper driver flag. -static cl::opt<PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr( - "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden, - cl::desc( - "Function attribute to apply to cold functions as determined by PGO"), - cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default", - "Default (no attribute)"), - clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize", - "Mark cold functions with optsize."), - clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize", - "Mark cold functions with minsize."), - clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone", - "Mark cold functions with optnone."))); - extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate; } // namespace llvm 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; @@ -834,12 +812,12 @@ void EmitAssemblyHelper::RunOptimizationPipeline( if (CodeGenOpts.hasProfileIRInstr()) // -fprofile-generate. - PGOOpt = PGOOptions(getProfileGenName(CodeGenOpts), "", "", - 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, llvm::ClPGOColdFuncAttr, + CodeGenOpts.DebugInfoForProfiling, + /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate); else if (CodeGenOpts.hasProfileIRUse()) { // -fprofile-use. auto CSAction = CodeGenOpts.hasProfileCSIRUse() ? PGOOptions::CSIRUse @@ -847,14 +825,14 @@ void EmitAssemblyHelper::RunOptimizationPipeline( PGOOpt = PGOOptions(CodeGenOpts.ProfileInstrumentUsePath, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, - PGOOptions::IRUse, CSAction, ClPGOColdFuncAttr, + PGOOptions::IRUse, CSAction, llvm::ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling); } else if (!CodeGenOpts.SampleProfileFile.empty()) // -fprofile-sample-use PGOOpt = PGOOptions( CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse, - PGOOptions::NoCSAction, ClPGOColdFuncAttr, + PGOOptions::NoCSAction, llvm::ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling); else if (!CodeGenOpts.MemoryProfileUsePath.empty()) // -fmemory-profile-use (without any of the above options) @@ -863,15 +841,15 @@ void EmitAssemblyHelper::RunOptimizationPipeline( ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling); else if (CodeGenOpts.PseudoProbeForProfiling) // -fpseudo-probe-for-profiling - PGOOpt = - PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, - PGOOptions::NoAction, PGOOptions::NoCSAction, - ClPGOColdFuncAttr, CodeGenOpts.DebugInfoForProfiling, true); + PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, + PGOOptions::NoAction, PGOOptions::NoCSAction, + llvm::ClPGOColdFuncAttr, + CodeGenOpts.DebugInfoForProfiling, true); else if (CodeGenOpts.DebugInfoForProfiling) // -fdebug-info-for-profiling PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, PGOOptions::NoCSAction, - ClPGOColdFuncAttr, true); + llvm::ClPGOColdFuncAttr, true); // Check to see if we want to generate a CS profile. if (CodeGenOpts.hasProfileCSIRInstr()) { 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 4d29ceace646f..10f0a12773498 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -951,7 +951,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 0154799498f5e..2e8e90493c370 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3568,7 +3568,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/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index cfc5c069b0849..ece7e5cad774c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1514,11 +1514,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 4dec86cd8f51b..68396c4c40711 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -24,11 +24,11 @@ CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. -ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone) -ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone) +/// 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) /// Whether emit extra debug info for sample pgo profile collection. -CODEGENOPT(DebugInfoForProfiling, 1, 0) -CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic 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 c9577862df832..6a989f0c0775e 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -148,14 +148,6 @@ class CodeGenOptions : public CodeGenOptionsBase { /// OpenMP is enabled. using DoConcurrentMappingKind = flangomp::DoConcurrentMappingKind; - 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. - }; - /// Name of the profile file to use as output for -fprofile-instr-generate, /// -fprofile-generate, and -fcs-profile-generate. std::string InstrProfileOutput; @@ -163,10 +155,6 @@ class CodeGenOptions : public CodeGenOptionsBase { /// Name of the profile file to use as input for -fmemory-profile-use. std::string MemoryProfileUsePath; - unsigned int DebugInfoForProfiling; - - unsigned int AtomicProfileUpdate; - /// Name of the profile file to use as input for -fprofile-instr-use std::string ProfileInstrumentUsePath; @@ -176,23 +164,27 @@ class CodeGenOptions : public CodeGenOptionsBase { /// Check if Clang profile instrumenation is on. bool hasProfileClangInstr() const { - return getProfileInstr() == ProfileClangInstr; + return getProfileInstr() == llvm::driver::ProfileClangInstr; } /// Check if IR level profile instrumentation is on. - bool hasProfileIRInstr() const { return getProfileInstr() == ProfileIRInstr; } + bool hasProfileIRInstr() const { + return getProfileInstr() == llvm::driver::ProfileIRInstr; + } /// Check if CS IR level profile instrumentation is on. bool hasProfileCSIRInstr() const { - return getProfileInstr() == ProfileCSIRInstr; + return getProfileInstr() == llvm::driver::ProfileCSIRInstr; } /// Check if IR level profile use is on. bool hasProfileIRUse() const { - return getProfileUse() == ProfileIRInstr || - getProfileUse() == ProfileCSIRInstr; + return getProfileUse() == llvm::driver::ProfileIRInstr || + getProfileUse() == llvm::driver::ProfileCSIRInstr; } /// Check if CSIR profile use is on. - bool hasProfileCSIRUse() const { return getProfileUse() == ProfileCSIRInstr; } + bool hasProfileCSIRUse() const { + return getProfileUse() == llvm::driver::ProfileCSIRInstr; + } // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h index f9a45bd6c0a56..9ba74a9dad9be 100644 --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/include/flang/Frontend/FrontendActions.h @@ -20,8 +20,13 @@ #include "mlir/IR/OwningOpRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Module.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PGOOptions.h" #include <memory> +namespace llvm { +extern cl::opt<llvm::PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr; +} // namespace llvm namespace Fortran::frontend { //===----------------------------------------------------------------------===// diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index b28c2c0047579..43c8f4d596903 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" @@ -432,17 +433,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, } if (args.hasArg(clang::driver::options::OPT_fprofile_generate)) { - opts.setProfileInstr( - Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); - opts.DebugInfoForProfiling = - args.hasArg(clang::driver::options::OPT_fdebug_info_for_profiling); - opts.AtomicProfileUpdate = - args.hasArg(clang::driver::options::OPT_fprofile_update_EQ); + opts.setProfileInstr(llvm::driver::ProfileInstrKind::ProfileIRInstr); } if (auto A = args.getLastArg(clang::driver::options::OPT_fprofile_use_EQ)) { - opts.setProfileUse( - Fortran::frontend::CodeGenOptions::ProfileInstrKind::ProfileIRInstr); + opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileIRInstr); opts.ProfileInstrumentUsePath = A->getValue(); } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 8d1ab670e4db4..c758aa18fbb8e 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -28,6 +28,7 @@ #include "flang/Semantics/unparse-with-symbols.h" #include "flang/Support/default-kinds.h" #include "flang/Tools/CrossToolHelpers.h" +#include "clang/CodeGen/BackendUtil.h" #include "mlir/IR/Dialect.h" #include "mlir/Parser/Parser.h" @@ -133,21 +134,6 @@ static bool saveMLIRTempFile(const CompilerInvocation &ci, // Custom BeginSourceFileAction //===----------------------------------------------------------------------===// -static llvm::cl::opt<llvm::PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr( - "pgo-cold-func-opt", llvm::cl::init(llvm::PGOOptions::ColdFuncOpt::Default), - llvm::cl::Hidden, - llvm::cl::desc( - "Function attribute to apply to cold functions as determined by PGO"), - llvm::cl::values(clEnumValN(llvm::PGOOptions::ColdFuncOpt::Default, - "default", "Default (no attribute)"), - clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptSize, - "optsize", "Mark cold functions with optsize."), - clEnumValN(llvm::PGOOptions::ColdFuncOpt::MinSize, - "minsize", "Mark cold functions with minsize."), - clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptNone, - "optnone", - "Mark cold functions with optnone."))); - bool PrescanAction::beginSourceFileAction() { return runPrescan(); } bool PrescanAndParseAction::beginSourceFileAction() { @@ -944,12 +930,12 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { if (opts.hasProfileIRInstr()) { // -fprofile-generate. pgoOpt = llvm::PGOOptions( - opts.InstrProfileOutput.empty() ? llvm::getDefaultProfileGenName() - : opts.InstrProfileOutput, + opts.InstrProfileOutput.empty() + ? llvm::driver::getDefaultProfileGenName() + : opts.InstrProfileOutput, "", "", opts.MemoryProfileUsePath, nullptr, llvm::PGOOptions::IRInstr, - llvm::PGOOptions::NoCSAction, ClPGOColdFuncAttr, - opts.DebugInfoForProfiling, - /*PseudoProbeForProfiling=*/false, opts.AtomicProfileUpdate); + llvm::PGOOptions::NoCSAction, llvm::ClPGOColdFuncAttr, false, + /*PseudoProbeForProfiling=*/false, false); } else if (opts.hasProfileIRUse()) { llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = llvm::vfs::getRealFileSystem(); @@ -959,7 +945,7 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { pgoOpt = llvm::PGOOptions( opts.ProfileInstrumentUsePath, "", opts.ProfileRemappingFile, opts.MemoryProfileUsePath, VFS, llvm::PGOOptions::IRUse, CSAction, - ClPGOColdFuncAttr, opts.DebugInfoForProfiling); + llvm::ClPGOColdFuncAttr, false); } llvm::StandardInstrumentations si(llvmModule->getContext(), diff --git a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h index c51476e9ad3fe..6188c20cb29cf 100644 --- a/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h +++ b/llvm/include/llvm/Frontend/Driver/CodeGenOptions.h @@ -13,9 +13,14 @@ #ifndef LLVM_FRONTEND_DRIVER_CODEGENOPTIONS_H #define LLVM_FRONTEND_DRIVER_CODEGENOPTIONS_H +#include "llvm/ProfileData/InstrProfCorrelator.h" +#include <string> namespace llvm { class Triple; class TargetLibraryInfoImpl; +extern llvm::cl::opt<bool> DebugInfoCorrelate; +extern llvm::cl::opt<llvm::InstrProfCorrelator::ProfCorrelatorKind> + ProfileCorrelate; } // namespace llvm namespace llvm::driver { @@ -35,7 +40,15 @@ enum class VectorLibrary { 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/CodeGenOptions.cpp b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp index ed7c57a930aca..818dcd3752437 100644 --- a/llvm/lib/Frontend/Driver/CodeGenOptions.cpp +++ b/llvm/lib/Frontend/Driver/CodeGenOptions.cpp @@ -8,7 +8,26 @@ #include "llvm/Frontend/Driver/CodeGenOptions.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/ProfileData/InstrProfCorrelator.h" +#include "llvm/Support/PGOOptions.h" #include "llvm/TargetParser/Triple.h" +namespace llvm { +// Experiment to mark cold functions as optsize/minsize/optnone. +// TODO: remove once this is exposed as a proper driver flag. +cl::opt<llvm::PGOOptions::ColdFuncOpt> ClPGOColdFuncAttr( + "pgo-cold-func-opt", cl::init(llvm::PGOOptions::ColdFuncOpt::Default), + cl::Hidden, + cl::desc( + "Function attribute to apply to cold functions as determined by PGO"), + cl::values(clEnumValN(llvm::PGOOptions::ColdFuncOpt::Default, "default", + "Default (no attribute)"), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptSize, "optsize", + "Mark cold functions with optsize."), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::MinSize, "minsize", + "Mark cold functions with minsize."), + clEnumValN(llvm::PGOOptions::ColdFuncOpt::OptNone, "optnone", + "Mark cold functions with optnone."))); +} // namespace llvm namespace llvm::driver { @@ -56,4 +75,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 >From e53e689985088bbcdc253950a2ecc715592b5b3a Mon Sep 17 00:00:00 2001 From: fanju110 <fanju...@163.com> Date: Mon, 28 Apr 2025 21:49:36 +0800 Subject: [PATCH 6/6] Remove redundant function definitions --- flang/lib/Frontend/FrontendActions.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index c758aa18fbb8e..cdd2853bcd201 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -896,18 +896,6 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags, delete tlii; } -// Default filename used for profile generation. -namespace llvm { -extern llvm::cl::opt<bool> DebugInfoCorrelate; -extern llvm::cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate; - -std::string getDefaultProfileGenName() { - return DebugInfoCorrelate || - ProfileCorrelate != llvm::InstrProfCorrelator::NONE - ? "default_%m.proflite" - : "default_%m.profraw"; -} -} // namespace llvm void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { CompilerInstance &ci = getInstance(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits