diff options
Diffstat (limited to 'flang/lib/Frontend')
-rw-r--r-- | flang/lib/Frontend/CompilerInvocation.cpp | 5 | ||||
-rw-r--r-- | flang/lib/Frontend/FrontendActions.cpp | 26 |
2 files changed, 31 insertions, 0 deletions
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 0e9e945..9ab7030 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -129,6 +129,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) opts.LLVMPassPlugins.push_back(a->getValue()); + // -fembed-offload-object option + for (auto *a : + args.filtered(clang::driver::options::OPT_fembed_offload_object_EQ)) + opts.OffloadObjects.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 7e41565..7cb352a 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -47,12 +47,14 @@ #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Object/OffloadBinary.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include <memory> using namespace Fortran::frontend; @@ -727,6 +729,25 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { mpm.run(*llvmModule, mam); } +void CodeGenAction::embedOffloadObjects() { + CompilerInstance &ci = this->getInstance(); + const auto &cgOpts = ci.getInvocation().getCodeGenOpts(); + + for (llvm::StringRef offloadObject : cgOpts.OffloadObjects) { + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> objectOrErr = + llvm::MemoryBuffer::getFileOrSTDIN(offloadObject); + if (std::error_code ec = objectOrErr.getError()) { + auto diagID = ci.getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Error, "could not open '%0' for embedding"); + ci.getDiagnostics().Report(diagID) << offloadObject; + return; + } + llvm::embedBufferInModule( + *llvmModule, **objectOrErr, ".llvm.offloading", + llvm::Align(llvm::object::OffloadBinary::getAlignment())); + } +} + void CodeGenAction::executeAction() { CompilerInstance &ci = this->getInstance(); @@ -774,12 +795,17 @@ void CodeGenAction::executeAction() { ci.getDiagnostics().Report(clang::diag::warn_fe_override_module) << theTriple; } + // Always set the triple and data layout, to make sure they match and are set. // Note that this overwrites any datalayout stored in the LLVM-IR. This avoids // an assert for incompatible data layout when the code-generation happens. llvmModule->setTargetTriple(theTriple); llvmModule->setDataLayout(tm->createDataLayout()); + // Embed offload objects specified with -fembed-offload-object + if (!ci.getInvocation().getCodeGenOpts().OffloadObjects.empty()) + embedOffloadObjects(); + // Run LLVM's middle-end (i.e. the optimizer). runOptimizationPipeline(ci.isOutputStreamNull() ? *os : ci.getOutputStream()); |