NegFlag<SetFalse>>;
def fembed_offload_object_EQ : Joined<["-"], "fembed-offload-object=">,
- Group<f_Group>, Flags<[NoXarchOption, CC1Option]>,
+ Group<f_Group>, Flags<[NoXarchOption, CC1Option, FC1Option]>,
HelpText<"Embed Offloading device-side binary into host object file as a section.">,
MarshallingInfoStringVector<CodeGenOpts<"OffloadObjects">>;
def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">,
/// The paths to the pass plugins that were registered using -fpass-plugin.
std::vector<std::string> LLVMPassPlugins;
+ /// List of filenames passed in using the -fembed-offload-object option. These
+ /// are offloading binaries containing device images and metadata.
+ std::vector<std::string> OffloadObjects;
+
// Define accessors/mutators for code generation options of enumeration type.
#define CODEGENOPT(Name, Bits, Default)
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \
std::unique_ptr<llvm::LLVMContext> llvmCtx;
std::unique_ptr<llvm::Module> llvmModule;
+ /// Embeds offload objects given with specified with -fembed-offload-object
+ void embedOffloadObjects();
+
/// Generates an LLVM IR module from CodeGenAction::mlirModule and saves it
/// in CodeGenAction::llvmModule.
void generateLLVMIR();
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)) {
#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;
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();
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());
! HELP-FC1-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type
! HELP-FC1-NEXT: -fdefault-integer-8 Set the default integer kind to an 8 byte wide type
! HELP-FC1-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type
+! HELP-FC1-NEXT: -fembed-offload-object=<value>
+! HELP-FC1-NEXT: Embed Offloading device-side binary into host object file as a section.
! HELP-FC1-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations
! HELP-FC1-NEXT: -ffixed-form Process source files in fixed form
! HELP-FC1-NEXT: -ffixed-line-length=<value>
--- /dev/null
+
+!----------
+! RUN lines
+!----------
+! Try to embed missing file
+! RUN: not %flang_fc1 -emit-llvm -o - -fembed-offload-object=%S/Inputs/missing.f90 %s 2>&1 | FileCheck %s --check-prefix=ERROR
+
+! ERROR: error: could not open
+
+parameter(i=1)
+integer :: j
+end program
--- /dev/null
+
+!----------
+! RUN lines
+!----------
+! Embed something that can be easily checked
+! RUN: %flang_fc1 -emit-llvm -o - -fembed-offload-object=%S/Inputs/hello.f90 %s 2>&1 | FileCheck %s
+
+! RUN: %flang_fc1 -emit-llvm-bc -o %t.bc %s 2>&1
+! RUN: %flang_fc1 -emit-llvm -o - -fembed-offload-object=%S/Inputs/hello.f90 %t.bc 2>&1 | FileCheck %s
+
+! CHECK: @[[OBJECT_1:.+]] = private constant [61 x i8] c"program hello\0A write(*,*), \22Hello world!\22\0Aend program hello\0A", section ".llvm.offloading", align 8, !exclude !0
+! CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @[[OBJECT_1]]], section "llvm.metadata"
+
+
+! CHECK: !llvm.embedded.objects = !{![[METADATA_1:[0-9]+]]}
+! CHECK: ![[METADATA_1]] = !{ptr @[[OBJECT_1]], !".llvm.offloading"}
+
+parameter(i=1)
+integer :: j
+end program