[flang-commits] [clang] [flang] [flang] Add -mlink-builtin-bitcode option to fc1 (PR #94763)
via flang-commits
flang-commits at lists.llvm.org
Fri Jun 7 08:37:48 PDT 2024
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
More information about the flang-commits
mailing list