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,10 @@ llvm::OpenMPIRBuilderConfig Config(CGM.getLangOpts().OpenMPIsDevice, false, hasRequiresUnifiedSharedMemory(), CGM.getLangOpts().OpenMPOffloadMandatory); - // Initialize Types used in OpenMPIRBuilder from OMPKinds.def - OMPBuilder.initialize(); + OMPBuilder.initialize(CGM.getLangOpts().OpenMPIsDevice + ? CGM.getLangOpts().OMPHostIRFile + : StringRef{}); OMPBuilder.setConfig(Config); - loadOffloadInfoMetadata(); } void CGOpenMPRuntime::clear() { @@ -3006,40 +3006,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 @@ -418,8 +418,14 @@ /// 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(); + /// before any other method and only once! This internal state includes + /// Types used in the OpenMPIRBuilder generated from OMPKinds.def as well + /// as loading offload metadata for device from the OpenMP host IR file + /// passed in as the HostFilePath argument. + /// \param HostFilePath The path to the host IR file, used to load in + /// offload metadata for the device, allowing host and device to + /// maintain the same metadata mapping. + 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,31 @@ return Fn; } -void OpenMPIRBuilder::initialize() { initializeTypes(M); } +void OpenMPIRBuilder::initialize(StringRef HostFilePath) { + initializeTypes(M); + + if (HostFilePath.empty()) + return; + + auto Buf = MemoryBuffer::getFile(HostFilePath); + if (std::error_code Err = Buf.getError()) { + report_fatal_error(("error opening host file from host file path inside of " + "OpenMPIRBuilder: " + + Err.message()) + .c_str()); + } + + LLVMContext Ctx; + auto M = expectedToErrorOrAndEmitErrors( + Ctx, parseBitcodeFile(Buf.get()->getMemBufferRef(), Ctx)); + if (std::error_code Err = M.getError()) { + report_fatal_error( + ("error parsing host file inside of OpenMPIRBuilder: " + Err.message()) + .c_str()); + } + + loadOffloadInfoMetadata(*M.get()); +} void OpenMPIRBuilder::finalize(Function *Fn) { SmallPtrSet ParallelRegionBlockSet; @@ -534,6 +559,17 @@ // Remove work items that have been completed. OutlineInfos = std::move(DeferredOutlines); + + EmitMetadataErrorReportFunctionTy &&ErrorReportFn = + [](EmitMetadataErrorKind Kind, + const TargetRegionEntryInfo &EntryInfo) -> void { + 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/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 @@ -1274,19 +1274,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(); }