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 @@ -1630,42 +1630,76 @@ PLoc.getLine()); } -Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { - if (CGM.getLangOpts().OpenMPSimd) - return Address::invalid(); - std::optional Res = - OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); - if (Res && (*Res == OMPDeclareTargetDeclAttr::MT_Link || - ((*Res == OMPDeclareTargetDeclAttr::MT_To || - *Res == OMPDeclareTargetDeclAttr::MT_Enter) && - HasRequiresUnifiedSharedMemory))) { - SmallString<64> PtrName; - { - llvm::raw_svector_ostream OS(PtrName); - OS << CGM.getMangledName(GlobalDecl(VD)); - if (!VD->isExternallyVisible()) { - auto EntryInfo = getTargetEntryUniqueInfo( - CGM.getContext(), VD->getCanonicalDecl()->getBeginLoc()); - OS << llvm::format("_%x", EntryInfo.FileID); - } - OS << "_decl_tgt_ref_ptr"; - } - llvm::Value *Ptr = CGM.getModule().getNamedValue(PtrName); - QualType PtrTy = CGM.getContext().getPointerType(VD->getType()); - llvm::Type *LlvmPtrTy = CGM.getTypes().ConvertTypeForMem(PtrTy); - if (!Ptr) { - Ptr = OMPBuilder.getOrCreateInternalVariable(LlvmPtrTy, PtrName); +llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseKind +convertDeviceClause(const VarDecl *VD) { + std::optional DevTy = + OMPDeclareTargetDeclAttr::getDeviceType(VD); + if (!DevTy) + return llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseNone; - auto *GV = cast(Ptr); - GV->setLinkage(llvm::GlobalValue::WeakAnyLinkage); + switch (*DevTy) { + case OMPDeclareTargetDeclAttr::DT_Host: + return llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseHost; + break; + case OMPDeclareTargetDeclAttr::DT_NoHost: + return llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseNoHost; + break; + case OMPDeclareTargetDeclAttr::DT_Any: + return llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseAny; + break; + default: + return llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseNone; + break; + } +} - if (!CGM.getLangOpts().OpenMPIsDevice) - GV->setInitializer(CGM.GetAddrOfGlobal(VD)); - registerTargetGlobalVariable(VD, cast(Ptr)); - } - return Address(Ptr, LlvmPtrTy, CGM.getContext().getDeclAlign(VD)); +llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind +convertCaptureClause(const VarDecl *VD) { + std::optional MapType = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); + if (!MapType) + return llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryNone; + switch (*MapType) { + case OMPDeclareTargetDeclAttr::MapTypeTy::MT_To: + return llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo; + break; + case OMPDeclareTargetDeclAttr::MapTypeTy::MT_Enter: + return llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryEnter; + break; + case OMPDeclareTargetDeclAttr::MapTypeTy::MT_Link: + return llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryLink; + break; + default: + return llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryNone; + break; } - return Address::invalid(); +} + +Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) { + auto AddrOfGlobal = [&VD, this]() { return CGM.GetAddrOfGlobal(VD); }; + + auto LinkageForVariable = [&VD, this]() { + return CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false); + }; + + std::vector GeneratedRefs; + auto loc = CGM.getContext().getSourceManager().getPresumedLoc( + VD->getCanonicalDecl()->getBeginLoc()); + + llvm::Type *LlvmPtrTy = CGM.getTypes().ConvertTypeForMem( + CGM.getContext().getPointerType(VD->getType())); + llvm::Constant *addr = OMPBuilder.getAddrOfDeclareTargetVar( + convertCaptureClause(VD), convertDeviceClause(VD), + VD->hasDefinition(CGM.getContext()) == VarDecl::DeclarationOnly, + VD->isExternallyVisible(), loc.getFilename(), loc.getLine(), + CGM.getMangledName(VD), &CGM.getModule(), GeneratedRefs, + CGM.getLangOpts().OpenMPSimd, CGM.getLangOpts().OpenMPIsDevice, + CGM.getLangOpts().OMPTargetTriples, LlvmPtrTy, + AddrOfGlobal, LinkageForVariable); + + if (!addr) + return Address::invalid(); + return Address(addr, LlvmPtrTy, CGM.getContext().getDeclAlign(VD)); } llvm::Constant * @@ -10367,12 +10401,6 @@ !CGM.getLangOpts().OpenMPIsDevice) return; - // If we have host/nohost variables, they do not need to be registered. - std::optional DevTy = - OMPDeclareTargetDeclAttr::getDeviceType(VD); - if (DevTy && *DevTy != OMPDeclareTargetDeclAttr::DT_Any) - return; - std::optional Res = OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); if (!Res) { @@ -10384,68 +10412,30 @@ } return; } - // Register declare target variables. - llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind Flags; - StringRef VarName; - int64_t VarSize; - llvm::GlobalValue::LinkageTypes Linkage; - - if ((*Res == OMPDeclareTargetDeclAttr::MT_To || - *Res == OMPDeclareTargetDeclAttr::MT_Enter) && - !HasRequiresUnifiedSharedMemory) { - Flags = llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo; - VarName = CGM.getMangledName(VD); - if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) { - VarSize = - CGM.getContext().getTypeSizeInChars(VD->getType()).getQuantity(); - assert(VarSize != 0 && "Expected non-zero size of the variable"); - } else { - VarSize = 0; - } - Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false); - // Temp solution to prevent optimizations of the internal variables. - if (CGM.getLangOpts().OpenMPIsDevice && - (!VD->isExternallyVisible() || - Linkage == llvm::GlobalValue::LinkOnceODRLinkage)) { - // Do not create a "ref-variable" if the original is not also available - // on the host. - if (!OMPBuilder.OffloadInfoManager.hasDeviceGlobalVarEntryInfo(VarName)) - return; - std::string RefName = getName({VarName, "ref"}); - if (!CGM.GetGlobalValue(RefName)) { - llvm::Constant *AddrRef = - OMPBuilder.getOrCreateInternalVariable(Addr->getType(), RefName); - auto *GVAddrRef = cast(AddrRef); - GVAddrRef->setConstant(/*Val=*/true); - GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage); - GVAddrRef->setInitializer(Addr); - CGM.addCompilerUsedGlobal(GVAddrRef); - } - } - } else { - assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) || - ((*Res == OMPDeclareTargetDeclAttr::MT_To || - *Res == OMPDeclareTargetDeclAttr::MT_Enter) && - HasRequiresUnifiedSharedMemory)) && - "Declare target attribute must link or to with unified memory."); - if (*Res == OMPDeclareTargetDeclAttr::MT_Link) - Flags = llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryLink; - else - Flags = llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo; - if (CGM.getLangOpts().OpenMPIsDevice) { - VarName = Addr->getName(); - Addr = nullptr; - } else { - VarName = getAddrOfDeclareTargetVar(VD).getName(); - Addr = cast(getAddrOfDeclareTargetVar(VD).getPointer()); - } - VarSize = CGM.getPointerSize().getQuantity(); - Linkage = llvm::GlobalValue::WeakAnyLinkage; - } + auto AddrOfGlobal = [&VD, this]() { return CGM.GetAddrOfGlobal(VD); }; + auto LinkageForVariable = [&VD, this]() { + return CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false); + }; - OMPBuilder.OffloadInfoManager.registerDeviceGlobalVarEntryInfo( - VarName, Addr, VarSize, Flags, Linkage); + std::vector GeneratedRefs; + auto loc = CGM.getContext().getSourceManager().getPresumedLoc( + VD->getCanonicalDecl()->getBeginLoc()); + OMPBuilder.registerTargetGlobalVariable( + convertCaptureClause(VD), convertDeviceClause(VD), + VD->hasDefinition(CGM.getContext()) == VarDecl::DeclarationOnly, + VD->isExternallyVisible(), loc.getFilename(), loc.getLine(), + CGM.getMangledName(VD), &CGM.getModule(), GeneratedRefs, + CGM.getLangOpts().OpenMPSimd, CGM.getLangOpts().OpenMPIsDevice, + CGM.getLangOpts().OMPTargetTriples, AddrOfGlobal, LinkageForVariable, + CGM.getTypes().ConvertTypeForMem( + CGM.getContext().getPointerType(VD->getType())), + Addr); + + for (auto *ref : GeneratedRefs) + CGM.addCompilerUsedGlobal(ref); + + return; } bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) { 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 @@ -323,6 +323,26 @@ OMPTargetGlobalVarEntryTo = 0x0, /// Mark the entry as a to declare target link. OMPTargetGlobalVarEntryLink = 0x1, + /// Mark the entry as a declare target enter. + OMPTargetGlobalVarEntryEnter = 0x2, + /// Mark the entry as having no declare target entry kind. + OMPTargetGlobalVarEntryNone = 0x3, + }; + + /// Kind of device clause for declare target variables + /// and functions + /// NOTE: Currently not used as a part of a variable entry + /// used for Flang and Clang to interface with the variable + /// related registration functions + enum OMPTargetDeviceClauseKind : uint32_t { + /// The target is marked for all devices + OMPTargetDeviceClauseAny = 0x0, + /// The target is marked for non-host devices + OMPTargetDeviceClauseNoHost = 0x1, + /// The target is marked for host devices + OMPTargetDeviceClauseHost = 0x2, + /// The target is marked as having no clause + OMPTargetDeviceClauseNone = 0x3 }; /// Device global variable entries info. @@ -755,6 +775,110 @@ static unsigned getOpenMPDefaultSimdAlign(const Triple &TargetTriple, const StringMap &Features); + /// Retrieve (or create if non-existent) the address of a declare + /// target variable, used in conjunction with registerTargetGlobalVariable + /// to create declare target global variables. + /// + /// \param CaptureClause - enumerator corresponding to the OpenMP capture + /// clause used in conjunction with the variable being registered (link, + /// to, enter). + /// \param DeviceClause - enumerator corresponding to the OpenMP capture + /// clause used in conjunction with the variable being registered (nohost, + /// host, any) + /// \param IsDeclaration - boolean stating if the variable being registered + /// is a declaration-only and not a definition + /// \param IsExternallyVisible - boolean stating if the variable is externally + /// visible + /// \param Filename - the path of the file the variable being registered + /// resides in + /// \param Line - the line number in the file the variable being registered + /// resides in + /// \param MangledName - the mangled name of the variable being registered + /// \param LlvmModule - the llvm module being built that the variable is a + /// part of + /// \param GeneratedRefs - references generated by invocations of + /// registerTargetGlobalVariable invoked from getAddrOfDeclareTargetVar, + /// these are required by Clang for book keeping. + /// \param OpenMPSIMD - if OpenMP SIMD mode is currently enabled + /// \param OpenMPIsDevice - if OpenMP device compilation mode is currently + /// enabled + /// \param TargetTriple - The OpenMP device target triple we are compiling + /// for + /// \param LlvmPtrTy - The type of the variable we are generating or + /// retrieving an address for + /// \param GlobalInitializer - a lambda function which creates a constant + /// used for initializing a pointer reference to the variable in certain + /// cases. If a nullptr is passed, it will default to utilising the original + /// variable to initialize the pointer reference. + /// \param VariableLinkage - a lambda function which returns the variables + /// linkage type, if unspecified and a nullptr is given, it will instead + /// utilise the linkage stored on the existing global variable in the + /// LLVMModule. + llvm::Constant *getAddrOfDeclareTargetVar( + llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind + CaptureClause, + llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseKind + DeviceClause, + bool IsDeclaration, bool IsExternallyVisible, llvm::StringRef Filename, + uint64_t Line, llvm::StringRef MangledName, llvm::Module *LlvmModule, + std::vector &GeneratedRefs, bool OpenMPSIMD, + bool OpenMPIsDevice, std::vector TargetTriple, + llvm::Type *LlvmPtrTy, + std::function GlobalInitializer, + std::function VariableLinkage); + + /// Registers a target variable for device or host. + /// + /// \param CaptureClause - enumerator corresponding to the OpenMP capture + /// clause used in conjunction with the variable being registered (link, + /// to, enter). + /// \param DeviceClause - enumerator corresponding to the OpenMP capture + /// clause used in conjunction with the variable being registered (nohost, + /// host, any) + /// \param IsDeclaration - boolean stating if the variable being registered + /// is a declaration-only and not a definition + /// \param IsExternallyVisible - boolean stating if the variable is externally + /// visible + /// \param Filename - the path of the file the variable being registered + /// resides in + /// \param Line - the line number in the file the variable being registered + /// resides in + /// \param MangledName - the mangled name of the variable being registered + /// \param LlvmModule - the llvm module being built that the variable is a + /// part of + /// \param GeneratedRefs - references generated by invocations of + /// registerTargetGlobalVariable these are required by Clang for book + /// keeping. + /// \param OpenMPSIMD - if OpenMP SIMD mode is currently enabled + /// \param OpenMPIsDevice - if OpenMP device compilation mode is currently + /// enabled + /// \param TargetTriple - The OpenMP device target triple we are compiling + /// for + /// \param GlobalInitializer - a lambda function which creates a constant + /// used for initializing a pointer reference to the variable in certain + /// cases. If a nullptr is passed, it will default to utilising the original + /// variable to initialize the pointer reference. + /// \param VariableLinkage - a lambda function which returns the variables + /// linkage type, if unspecified and a nullptr is given, it will instead + /// utilise the linkage stored on the existing global variable in the + /// LLVMModule. + /// \param LlvmPtrTy - The type of the variable we are generating or + /// retrieving an address for + /// \param Addr - the original llvm value (addr) of the variable to be + /// registered + void registerTargetGlobalVariable( + llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind + CaptureClause, + llvm::OffloadEntriesInfoManager::OMPTargetDeviceClauseKind + DeviceClause, + bool IsDeclaration, bool IsExternallyVisible, llvm::StringRef Filename, + uint64_t Line, llvm::StringRef MangledName, llvm::Module *LlvmModule, + std::vector &GeneratedRefs, bool OpenMPSIMD, + bool OpenMPIsDevice, std::vector TargetTriple, + std::function GlobalInitializer, + std::function VariableLinkage, + llvm::Type *LlvmPtrTy, llvm::Constant *Addr); + private: /// Modifies the canonical loop to be a statically-scheduled workshare loop. /// @@ -1040,6 +1164,17 @@ InsertPointTy AllocaIP, BodyGenCallbackTy BodyGenCB); + /// Creates a unique info for a target entry when provided a filename and + /// line number from. + /// + /// \param FileName The name of the file the target entry resides in + /// \param Line The line number where the target entry resides + /// \param ParentName The name of the parent the target entry resides in, if + /// any. + static llvm::TargetRegionEntryInfo + getTargetEntryUniqueInfo(StringRef FileName, uint64_t Line, + llvm::StringRef ParentName = ""); + /// Functions used to generate reductions. Such functions take two Values /// representing LHS and RHS of the reduction, respectively, and a reference /// to the value that is updated to refer to the reduction result. 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 @@ -32,6 +32,7 @@ #include "llvm/IR/Value.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -4999,7 +5000,8 @@ static_cast( CE->getFlags()); switch (Flags) { - case OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo: { + case OffloadEntriesInfoManager::OMPTargetGlobalVarEntryEnter: + case OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo: if (Config.isEmbedded() && Config.hasRequiresUnifiedSharedMemory()) continue; if (!CE->getAddress()) { @@ -5010,7 +5012,6 @@ if (CE->getVarSize() == 0) continue; break; - } case OffloadEntriesInfoManager::OMPTargetGlobalVarEntryLink: assert(((Config.isEmbedded() && !CE->getAddress()) || (!Config.isEmbedded() && CE->getAddress())) && @@ -5022,6 +5023,8 @@ continue; } break; + default: + break; } // Hidden or internal symbols on the device are not externally visible. @@ -5058,6 +5061,164 @@ EntryInfo.Line, NewCount); } +llvm::TargetRegionEntryInfo +OpenMPIRBuilder::getTargetEntryUniqueInfo(StringRef FileName, uint64_t Line, + llvm::StringRef ParentName) { + llvm::sys::fs::UniqueID ID; + if (auto EC = llvm::sys::fs::getUniqueID(FileName, ID)) { + assert(EC && + "Unable to get unique ID for file, during getTargetEntryUniqueInfo"); + } + return llvm::TargetRegionEntryInfo(ParentName, ID.getDevice(), ID.getFile(), + Line); +} + + +llvm::Constant *OpenMPIRBuilder::getAddrOfDeclareTargetVar( + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind CaptureClause, + OffloadEntriesInfoManager::OMPTargetDeviceClauseKind DeviceClause, + bool IsDeclaration, bool IsExternallyVisible, llvm::StringRef Filename, + uint64_t Line, llvm::StringRef MangledName, llvm::Module *LlvmModule, + std::vector &GeneratedRefs, bool OpenMPSIMD, + bool OpenMPIsDevice, std::vector TargetTriple, + llvm::Type *LlvmPtrTy, std::function GlobalInitializer, + std::function VariableLinkage) { + // TODO: convert this to utilise the IRBuilder Config rather than + // a passed down argument. + if (OpenMPSIMD) + return nullptr; + + if (CaptureClause == + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryLink || + ((CaptureClause == + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo || + CaptureClause == + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryEnter) && + Config.hasRequiresUnifiedSharedMemory())) { + SmallString<64> PtrName; + { + llvm::raw_svector_ostream OS(PtrName); + OS << MangledName; + if (!IsExternallyVisible) { + auto EntryInfo = getTargetEntryUniqueInfo(Filename, Line); + OS << llvm::format("_%x", EntryInfo.FileID); + } + OS << "_decl_tgt_ref_ptr"; + } + + llvm::Value *Ptr = LlvmModule->getNamedValue(PtrName); + + if (!Ptr) { + llvm::GlobalValue *GlobalValue = LlvmModule->getNamedValue(MangledName); + Ptr = getOrCreateInternalVariable(LlvmPtrTy, PtrName); + + auto *GV = cast(Ptr); + GV->setLinkage(llvm::GlobalValue::WeakAnyLinkage); + + if (!OpenMPIsDevice) { + if (GlobalInitializer) + GV->setInitializer(GlobalInitializer()); + else + GV->setInitializer(GlobalValue); + } + + registerTargetGlobalVariable( + CaptureClause, DeviceClause, IsDeclaration, IsExternallyVisible, + Filename, Line, MangledName, LlvmModule, GeneratedRefs, OpenMPSIMD, + OpenMPIsDevice, TargetTriple, GlobalInitializer, VariableLinkage, + LlvmPtrTy, cast(Ptr)); + } + + return cast(Ptr); + } + + return nullptr; +} + +void OpenMPIRBuilder::registerTargetGlobalVariable( + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind CaptureClause, + OffloadEntriesInfoManager::OMPTargetDeviceClauseKind DeviceClause, + bool IsDeclaration, bool IsExternallyVisible, llvm::StringRef Filename, + uint64_t Line, llvm::StringRef MangledName, llvm::Module *LlvmModule, + std::vector &GeneratedRefs, bool OpenMPSIMD, + bool OpenMPIsDevice, std::vector TargetTriple, + std::function GlobalInitializer, + std::function VariableLinkage, + llvm::Type *LlvmPtrTy, llvm::Constant *Addr) { + if (DeviceClause != + OffloadEntriesInfoManager::OMPTargetDeviceClauseAny || + (TargetTriple.empty() && !OpenMPIsDevice)) + return; + + llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryKind Flags; + StringRef VarName; + int64_t VarSize; + llvm::GlobalValue::LinkageTypes Linkage; + + if ((CaptureClause == + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo || + CaptureClause == + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryEnter) && + !Config.hasRequiresUnifiedSharedMemory()) { + Flags = llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo; + VarName = MangledName; + llvm::GlobalValue *LlvmVal = LlvmModule->getNamedValue(VarName); + + if (!IsDeclaration) + VarSize = llvm::divideCeil(LlvmModule->getDataLayout().getTypeSizeInBits( + LlvmVal->getValueType()), + 8); + else + VarSize = 0; + Linkage = (VariableLinkage) ? VariableLinkage() : LlvmVal->getLinkage(); + + // This is a workaround carried over from Clang which prevents undesired + // optimisation of internal variables. + if (OpenMPIsDevice && (!IsExternallyVisible || + Linkage == llvm::GlobalValue::LinkOnceODRLinkage)) { + // Do not create a "ref-variable" if the original is not also available + // on the host. + if (!OffloadInfoManager.hasDeviceGlobalVarEntryInfo(VarName)) + return; + + std::string RefName = createPlatformSpecificName({VarName, "ref"}); + + if (!LlvmModule->getNamedValue(RefName)) { + llvm::Constant *AddrRef = + getOrCreateInternalVariable(Addr->getType(), RefName); + auto *GvAddrRef = cast(AddrRef); + GvAddrRef->setConstant(true); + GvAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage); + GvAddrRef->setInitializer(Addr); + GeneratedRefs.push_back(GvAddrRef); + } + } + } else { + if (CaptureClause == + OffloadEntriesInfoManager::OMPTargetGlobalVarEntryLink) + Flags = llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryLink; + else + Flags = llvm::OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo; + + if (OpenMPIsDevice) { + VarName = (Addr) ? Addr->getName() : ""; + Addr = nullptr; + } else { + Addr = getAddrOfDeclareTargetVar( + CaptureClause, DeviceClause, IsDeclaration, IsExternallyVisible, + Filename, Line, MangledName, LlvmModule, GeneratedRefs, OpenMPSIMD, + OpenMPIsDevice, TargetTriple, LlvmPtrTy, GlobalInitializer, + VariableLinkage); + VarName = (Addr) ? Addr->getName() : ""; + } + VarSize = LlvmModule->getDataLayout().getPointerSize(); + Linkage = llvm::GlobalValue::WeakAnyLinkage; + } + + OffloadInfoManager.registerDeviceGlobalVarEntryInfo(VarName, Addr, VarSize, + Flags, Linkage); +} + /// Loads all the offload entries information from the host IR /// metadata. void OpenMPIRBuilder::loadOffloadInfoMetadata(Module &M) {