[flang] Add -mlink-builtin-bitcode option to fc1 (#94763)
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.
This commit is contained in:
@@ -7036,6 +7036,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">,
|
||||
@@ -7138,9 +7144,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 "
|
||||
|
||||
@@ -56,6 +56,10 @@ public:
|
||||
/// 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;
|
||||
|
||||
|
||||
@@ -223,9 +223,12 @@ protected:
|
||||
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 -mlink-builtin-bitcode
|
||||
void linkBuiltinBCLibs();
|
||||
|
||||
/// Runs pass pipeline to lower HLFIR into FIR
|
||||
void lowerHLFIRToFIR();
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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"
|
||||
@@ -55,6 +57,7 @@
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/IRPrinter/IRPrintingPasses.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"
|
||||
@@ -69,6 +72,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>
|
||||
@@ -1149,6 +1153,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(
|
||||
@@ -1240,6 +1292,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();
|
||||
|
||||
4
flang/test/Driver/Inputs/libfun.f90
Normal file
4
flang/test/Driver/Inputs/libfun.f90
Normal file
@@ -0,0 +1,4 @@
|
||||
subroutine libfun(x)
|
||||
integer :: x
|
||||
end subroutine
|
||||
|
||||
15
flang/test/Driver/mlink-builtin-bc.f90
Normal file
15
flang/test/Driver/mlink-builtin-bc.f90
Normal file
@@ -0,0 +1,15 @@
|
||||
! Test -mlink-builtin-bitcode flag
|
||||
! RUN: %flang -emit-llvm -c -o %t.bc %S/Inputs/libfun.f90
|
||||
! RUN: %flang_fc1 -emit-llvm -o - -mlink-builtin-bitcode %t.bc %s 2>&1 | FileCheck %s
|
||||
|
||||
! CHECK: define internal void @libfun_
|
||||
|
||||
! RUN: not %flang_fc1 -emit-llvm -o - -mlink-builtin-bitcode %no-%t.bc %s 2>&1 | FileCheck %s --check-prefix=ERROR
|
||||
|
||||
! ERROR: error: could not open {{.*}}.bc
|
||||
|
||||
external libfun
|
||||
parameter(i=1)
|
||||
integer :: j
|
||||
call libfun(j)
|
||||
end program
|
||||
Reference in New Issue
Block a user