llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-flang-driver @llvm/pr-subscribers-clang Author: Jan Leyonberg (jsjodin) <details> <summary>Changes</summary> This patch enables the -mlink-builtin-bitcode flag in fc1 so that bitcode libraries can be linked in. This is needed for OpenMP offloading libraries. --- Full diff: https://github.com/llvm/llvm-project/pull/94763.diff 7 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+6-3) - (modified) flang/include/flang/Frontend/CodeGenOptions.h (+4) - (modified) flang/include/flang/Frontend/FrontendActions.h (+4-1) - (modified) flang/lib/Frontend/CompilerInvocation.cpp (+5) - (modified) flang/lib/Frontend/FrontendActions.cpp (+56) - (added) flang/test/Driver/Inputs/bclib.bc () - (added) flang/test/Driver/mlink-builtin-bc.f90 (+18) ``````````diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d44faa55c456f..490538ce753e0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7028,6 +7028,12 @@ def as_secure_log_file : Separate<["-"], "as-secure-log-file">, } // let Visibility = [CC1Option, CC1AsOption] +let Visibility = [CC1Option, FC1Option] in { +def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, + HelpText<"Link and internalize needed symbols from the given bitcode file " + "before performing optimizations.">; +} // let Visibility = [CC1Option, FC1Option] + let Visibility = [CC1Option] in { def llvm_verify_each : Flag<["-"], "llvm-verify-each">, @@ -7130,9 +7136,6 @@ defm constructor_aliases : BoolMOption<"constructor-aliases", " emitting complete constructors and destructors as aliases when possible">>; def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, HelpText<"Link the given bitcode file before performing optimizations.">; -def mlink_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, - HelpText<"Link and internalize needed symbols from the given bitcode file " - "before performing optimizations.">; defm link_builtin_bitcode_postopt: BoolMOption<"link-builtin-bitcode-postopt", CodeGenOpts<"LinkBitcodePostopt">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption], "Link builtin bitcodes after the " diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 918192abae724..3bc5d93c4c43e 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -56,6 +56,10 @@ class CodeGenOptions : public CodeGenOptionsBase { /// are offloading binaries containing device images and metadata. std::vector<std::string> OffloadObjects; + /// List of filenames passed in using the -mlink-builtin-bitcode. These + /// are bc libraries that should be linked in and internalized; + std::vector<std::string> BuiltinBCLibs; + /// The directory where temp files are stored if specified by -save-temps std::optional<std::string> SaveTempsDir; diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h index 7823565eb815f..0a9a9c3401d1d 100644 --- a/flang/include/flang/Frontend/FrontendActions.h +++ b/flang/include/flang/Frontend/FrontendActions.h @@ -223,9 +223,12 @@ class CodeGenAction : public FrontendAction { std::unique_ptr<llvm::LLVMContext> llvmCtx; std::unique_ptr<llvm::Module> llvmModule; - /// Embeds offload objects given with specified with -fembed-offload-object + /// Embeds offload objects specified with -fembed-offload-object void embedOffloadObjects(); + /// Links in BC libraries spefified with -fmlink-builtin-bitcode + void linkBuiltinBCLibs(); + /// Runs pass pipeline to lower HLFIR into FIR void lowerHLFIRToFIR(); diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index f64a939b785ef..f96d72f1ad691 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -347,6 +347,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ)) opts.SaveTempsDir = a->getValue(); + // -mlink-builtin-bitcode + for (auto *a : + args.filtered(clang::driver::options::OPT_mlink_builtin_bitcode)) + opts.BuiltinBCLibs.push_back(a->getValue()); + // -mrelocation-model option. if (const llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_mrelocation_model)) { diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index b1b6391f1439c..c2e6af58ffd79 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -43,6 +43,8 @@ #include "mlir/Target/LLVMIR/ModuleTranslation.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" #include "clang/Driver/DriverDiagnostic.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" @@ -54,6 +56,7 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/Linker/Linker.h" #include "llvm/Object/OffloadBinary.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" @@ -68,6 +71,7 @@ #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 <memory> #include <system_error> @@ -1146,6 +1150,54 @@ void CodeGenAction::embedOffloadObjects() { } } +void CodeGenAction::linkBuiltinBCLibs() { + auto options = clang::FileSystemOptions(); + clang::FileManager fileManager(options); + CompilerInstance &ci = this->getInstance(); + const auto &cgOpts = ci.getInvocation().getCodeGenOpts(); + + std::vector<std::unique_ptr<llvm::Module>> modules; + + // Load LLVM modules + for (llvm::StringRef bcLib : cgOpts.BuiltinBCLibs) { + auto BCBuf = fileManager.getBufferForFile(bcLib); + if (!BCBuf) { + auto diagID = ci.getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "could not open '%0' for linking"); + ci.getDiagnostics().Report(diagID) << bcLib; + return; + } + + llvm::Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = + getOwningLazyBitcodeModule(std::move(*BCBuf), *llvmCtx); + if (!ModuleOrErr) { + auto diagID = ci.getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "error loading '%0' for linking"); + ci.getDiagnostics().Report(diagID) << bcLib; + return; + } + modules.push_back(std::move(ModuleOrErr.get())); + } + + // Link modules and internalize functions + for (auto &module : modules) { + bool Err; + Err = llvm::Linker::linkModules( + *llvmModule, std::move(module), llvm::Linker::Flags::LinkOnlyNeeded, + [](llvm::Module &M, const llvm::StringSet<> &GVS) { + llvm::internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) { + return !GV.hasName() || (GVS.count(GV.getName()) == 0); + }); + }); + if (Err) { + auto diagID = ci.getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "link error when linking '%0'"); + ci.getDiagnostics().Report(diagID) << module->getSourceFileName(); + return; + } + } +} + static void reportOptRecordError(llvm::Error e, clang::DiagnosticsEngine &diags, const CodeGenOptions &codeGenOpts) { handleAllErrors( @@ -1237,6 +1289,10 @@ void CodeGenAction::executeAction() { llvmModule->setTargetTriple(theTriple); llvmModule->setDataLayout(targetMachine.createDataLayout()); + // Link in builtin bitcode libraries + if (!codeGenOpts.BuiltinBCLibs.empty()) + linkBuiltinBCLibs(); + // Embed offload objects specified with -fembed-offload-object if (!codeGenOpts.OffloadObjects.empty()) embedOffloadObjects(); diff --git a/flang/test/Driver/Inputs/bclib.bc b/flang/test/Driver/Inputs/bclib.bc new file mode 100644 index 0000000000000..bf97a6cd3dbe1 Binary files /dev/null and b/flang/test/Driver/Inputs/bclib.bc differ diff --git a/flang/test/Driver/mlink-builtin-bc.f90 b/flang/test/Driver/mlink-builtin-bc.f90 new file mode 100644 index 0000000000000..0d655a24a7a63 --- /dev/null +++ b/flang/test/Driver/mlink-builtin-bc.f90 @@ -0,0 +1,18 @@ + +!---------- +! RUN lines +!---------- +! Embed something that can be easily checked +! RUN: %flang_fc1 -emit-llvm -triple x86_64-unknown-linux-gnu -o - -mlink-builtin-bitcode %S/Inputs/bclib.bc %s 2>&1 | FileCheck %s + +! CHECK: define internal void @libfun_ + +! RUN1: not %flang_fc1 -emit-llvm -triple x86_64-unknown-linux-gnu -o - -mlink-builtin-bitcode %S/Inputs/no-bclib.bc %s 2>&1 | FileCheck %s + +! ERROR1: error: could not open {{.*}} no-bclib.bc + +external libfun +parameter(i=1) +integer :: j +call libfun(j) +end program `````````` </details> https://github.com/llvm/llvm-project/pull/94763 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits