aboutsummaryrefslogtreecommitdiff
path: root/flang/lib
diff options
context:
space:
mode:
authorFYK <fanyikang@bosc.ac.cn>2025-05-30 22:13:53 +0800
committerGitHub <noreply@github.com>2025-05-30 08:13:53 -0600
commitd27a210a77af63568db9f829702b4b2c98473a46 (patch)
tree1a0eaad35f43f0f779590abe2c9508ac466211b3 /flang/lib
parent4d650ef4b3d7a0f21f8681e73586d0319fc3953b (diff)
downloadllvm-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.cpp10
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp26
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);