diff options
author | FYK <fanyikang@bosc.ac.cn> | 2025-05-30 22:13:53 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-30 08:13:53 -0600 |
commit | d27a210a77af63568db9f829702b4b2c98473a46 (patch) | |
tree | 1a0eaad35f43f0f779590abe2c9508ac466211b3 /flang/lib | |
parent | 4d650ef4b3d7a0f21f8681e73586d0319fc3953b (diff) | |
download | llvm-d27a210a77af63568db9f829702b4b2c98473a46.zip llvm-d27a210a77af63568db9f829702b4b2c98473a46.tar.gz llvm-d27a210a77af63568db9f829702b4b2c98473a46.tar.bz2 |
Add IR Profile-Guided Optimization (IR PGO) support to the Flang compiler (#136098)
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
Resolves #74216 (implements IR PGO support phase)
**Key changes:**
- Frontend flag handling aligned with Clang/GCC semantics
- Instrumentation hooks into LLVM PGO infrastructure
- LIT tests verifying:
- Instrumentation metadata generation
- Profile loading from specified path
- Branch weight attribution (IR checks)
**Tests:**
- Added gcc-flag-compatibility.f90 test module verifying:
- Flag parsing boundary conditions
- IR-level profile annotation consistency
- Profile input path normalization rules
- SPEC2006 benchmark results will be shared in comments
For details on LLVM's PGO framework, refer to [Clang PGO
Documentation](https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization).
This implementation was developed by [XSCC Compiler
Team](https://github.com/orgs/OpenXiangShan/teams/xscc).
---------
Co-authored-by: ict-ql <168183727+ict-ql@users.noreply.github.com>
Co-authored-by: Tom Eccles <t@freedommail.info>
Diffstat (limited to 'flang/lib')
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 10 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 26 |
2 files changed, 36 insertions, 0 deletions
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 90a0029..0571aea 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 012d0fd..da8fa51 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); |