aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Frontend')
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp5
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp26
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());