diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -551,10 +551,6 @@ /// Device routines are specific to the bool HasEmittedDeclareTargetRegion = false; - /// Loads all the offload entries information from the host IR - /// metadata. - void loadOffloadInfoMetadata(); - /// Start scanning from statement \a S and emit all target regions /// found along the way. /// \param S Starting statement. diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1059,10 +1059,12 @@ llvm::OpenMPIRBuilderConfig Config(CGM.getLangOpts().OpenMPIsDevice, false, hasRequiresUnifiedSharedMemory(), CGM.getLangOpts().OpenMPOffloadMandatory); - // Initialize Types used in OpenMPIRBuilder from OMPKinds.def - OMPBuilder.initialize(); + // Initialize Types used in OpenMPIRBuilder from OMPKinds.def as well as load + // offload metadata for device from an OpenMP host IR file. + OMPBuilder.initialize(CGM.getLangOpts().OpenMPIsDevice + ? CGM.getLangOpts().OMPHostIRFile + : StringRef{}); OMPBuilder.setConfig(Config); - loadOffloadInfoMetadata(); } void CGOpenMPRuntime::clear() { @@ -3006,40 +3008,6 @@ OMPBuilder.createOffloadEntriesAndInfoMetadata(ErrorReportFn); } -/// Loads all the offload entries information from the host IR -/// metadata. -void CGOpenMPRuntime::loadOffloadInfoMetadata() { - // If we are in target mode, load the metadata from the host IR. This code has - // to match the metadaata creation in createOffloadEntriesAndInfoMetadata(). - - if (!CGM.getLangOpts().OpenMPIsDevice) - return; - - if (CGM.getLangOpts().OMPHostIRFile.empty()) - return; - - auto Buf = llvm::MemoryBuffer::getFile(CGM.getLangOpts().OMPHostIRFile); - if (auto EC = Buf.getError()) { - CGM.getDiags().Report(diag::err_cannot_open_file) - << CGM.getLangOpts().OMPHostIRFile << EC.message(); - return; - } - - llvm::LLVMContext C; - auto ME = expectedToErrorOrAndEmitErrors( - C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C)); - - if (auto EC = ME.getError()) { - unsigned DiagID = CGM.getDiags().getCustomDiagID( - DiagnosticsEngine::Error, "Unable to parse host IR file '%0':'%1'"); - CGM.getDiags().Report(DiagID) - << CGM.getLangOpts().OMPHostIRFile << EC.message(); - return; - } - - OMPBuilder.loadOffloadInfoMetadata(*ME.get()); -} - void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) { if (!KmpRoutineEntryPtrTy) { // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type. diff --git a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h --- a/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h +++ b/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h @@ -419,7 +419,7 @@ /// Initialize the internal state, this will put structures types and /// potentially other helpers into the underlying module. Must be called /// before any other method and only once! - void initialize(); + void initialize(StringRef HostFilePath = {}); void setConfig(OpenMPIRBuilderConfig C) { Config = C; } diff --git a/llvm/lib/Frontend/OpenMP/CMakeLists.txt b/llvm/lib/Frontend/OpenMP/CMakeLists.txt --- a/llvm/lib/Frontend/OpenMP/CMakeLists.txt +++ b/llvm/lib/Frontend/OpenMP/CMakeLists.txt @@ -19,4 +19,5 @@ Analysis MC Scalar + BitReader ) diff --git a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp --- a/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp +++ b/llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -445,7 +446,28 @@ return Fn; } -void OpenMPIRBuilder::initialize() { initializeTypes(M); } +void OpenMPIRBuilder::initialize(StringRef HostFilePath) { + initializeTypes(M); + + if (!HostFilePath.empty()) { + auto Buf = llvm::MemoryBuffer::getFile(HostFilePath); + if (auto Err = Buf.getError()) + assert(false && ("error opening host file from host file path inside of " + "OpenMPIRBuilder" + + Err.message()) + .c_str()); + + llvm::LLVMContext Ctx; + auto M = llvm::expectedToErrorOrAndEmitErrors( + Ctx, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), Ctx)); + if (auto Err = M.getError()) + assert(false && ("error parsing host file inside of OpenMPIRBuilder " + + Err.message()) + .c_str()); + + loadOffloadInfoMetadata(*M.get()); + } +} void OpenMPIRBuilder::finalize(Function *Fn) { SmallPtrSet ParallelRegionBlockSet; @@ -534,6 +556,17 @@ // Remove work items that have been completed. OutlineInfos = std::move(DeferredOutlines); + + llvm::OpenMPIRBuilder::EmitMetadataErrorReportFunctionTy &&errorReportFn = + [](llvm::OpenMPIRBuilder::EmitMetadataErrorKind kind, + const llvm::TargetRegionEntryInfo &entryInfo) -> void { + llvm::errs() << "Error of kind: " << kind + << " when emitting offload entries and metadata during " + "OMPIRBuilder finalization \n"; + }; + + if (!OffloadInfoManager.empty()) + createOffloadEntriesAndInfoMetadata(errorReportFn); } OpenMPIRBuilder::~OpenMPIRBuilder() { diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -15,6 +15,7 @@ #define MLIR_TARGET_LLVMIR_MODULETRANSLATION_H #include "mlir/Dialect/LLVMIR/LLVMInterfaces.h" +#include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/IR/Operation.h" #include "mlir/IR/SymbolTable.h" #include "mlir/IR/Value.h" diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1259,19 +1259,23 @@ llvm::OpenMPIRBuilder *ModuleTranslation::getOpenMPBuilder() { if (!ompBuilder) { ompBuilder = std::make_unique(*llvmModule); - ompBuilder->initialize(); bool isDevice = false; + llvm::StringRef hostIRFilePath = ""; if (auto offloadMod = - dyn_cast(mlirModule)) + dyn_cast(mlirModule)) { isDevice = offloadMod.getIsDevice(); + hostIRFilePath = offloadMod.getHostIRFilePath(); + } + + ompBuilder->initialize(hostIRFilePath); // TODO: set the flags when available - llvm::OpenMPIRBuilderConfig Config( + llvm::OpenMPIRBuilderConfig config( isDevice, /* IsTargetCodegen */ false, /* HasRequiresUnifiedSharedMemory */ false, /* OpenMPOffloadMandatory */ false); - ompBuilder->setConfig(Config); + ompBuilder->setConfig(config); } return ompBuilder.get(); }