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 @@ -508,9 +508,6 @@ /// kmp_int64 st; // stride /// }; QualType KmpDimTy; - /// Entity that registers the offloading constants that were emitted so - /// far. - llvm::OffloadEntriesInfoManager OffloadEntriesInfoManager; bool ShouldMarkAsGlobal = true; /// List of the emitted declarations. 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 @@ -1054,7 +1054,7 @@ } CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM) - : CGM(CGM), OMPBuilder(CGM.getModule()), OffloadEntriesInfoManager() { + : CGM(CGM), OMPBuilder(CGM.getModule()) { KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8); llvm::OpenMPIRBuilderConfig Config(CGM.getLangOpts().OpenMPIsDevice, false, hasRequiresUnifiedSharedMemory(), @@ -1062,7 +1062,6 @@ // Initialize Types used in OpenMPIRBuilder from OMPKinds.def OMPBuilder.initialize(); OMPBuilder.setConfig(Config); - OffloadEntriesInfoManager.setConfig(Config); loadOffloadInfoMetadata(); } @@ -1852,7 +1851,7 @@ auto EntryInfo = getTargetEntryUniqueInfo(CGM.getContext(), Loc, VD->getName()); SmallString<128> Buffer, Out; - OffloadEntriesInfoManager.getTargetRegionEntryFnName(Buffer, EntryInfo); + OMPBuilder.OffloadInfoManager.getTargetRegionEntryFnName(Buffer, EntryInfo); const Expr *Init = VD->getAnyInitializer(); if (CGM.getLangOpts().CPlusPlus && PerformInit) { @@ -1900,7 +1899,7 @@ Out.clear(); auto CtorEntryInfo = EntryInfo; CtorEntryInfo.ParentName = Twine(Buffer, "_ctor").toStringRef(Out); - OffloadEntriesInfoManager.registerTargetRegionEntryInfo( + OMPBuilder.OffloadInfoManager.registerTargetRegionEntryInfo( CtorEntryInfo, Ctor, ID, llvm::OffloadEntriesInfoManager::OMPTargetRegionEntryCtor); } @@ -1949,7 +1948,7 @@ Out.clear(); auto DtorEntryInfo = EntryInfo; DtorEntryInfo.ParentName = Twine(Buffer, "_dtor").toStringRef(Out); - OffloadEntriesInfoManager.registerTargetRegionEntryInfo( + OMPBuilder.OffloadInfoManager.registerTargetRegionEntryInfo( DtorEntryInfo, Dtor, ID, llvm::OffloadEntriesInfoManager::OMPTargetRegionEntryDtor); } @@ -2942,7 +2941,7 @@ void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() { // If we are in simd mode or there are no entries, we don't need to do // anything. - if (CGM.getLangOpts().OpenMPSimd || OffloadEntriesInfoManager.empty()) + if (CGM.getLangOpts().OpenMPSimd || OMPBuilder.OffloadInfoManager.empty()) return; llvm::OpenMPIRBuilder::EmitMetadataErrorReportFunctionTy &&ErrorReportFn = @@ -2986,8 +2985,7 @@ } }; - OMPBuilder.createOffloadEntriesAndInfoMetadata(OffloadEntriesInfoManager, - ErrorReportFn); + OMPBuilder.createOffloadEntriesAndInfoMetadata(ErrorReportFn); } /// Loads all the offload entries information from the host IR @@ -3021,7 +3019,7 @@ return; } - OMPBuilder.loadOffloadInfoMetadata(*ME.get(), OffloadEntriesInfoManager); + OMPBuilder.loadOffloadInfoMetadata(*ME.get()); } void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) { @@ -6109,10 +6107,9 @@ getNumTeamsExprForTargetDirective(CGF, D, DefaultValTeams); getNumThreadsExprForTargetDirective(CGF, D, DefaultValThreads); - OMPBuilder.emitTargetRegionFunction(OffloadEntriesInfoManager, EntryInfo, - GenerateOutlinedFunction, DefaultValTeams, - DefaultValThreads, IsOffloadEntry, - OutlinedFn, OutlinedFnID); + OMPBuilder.emitTargetRegionFunction(EntryInfo, GenerateOutlinedFunction, + DefaultValTeams, DefaultValThreads, + IsOffloadEntry, OutlinedFn, OutlinedFnID); if (OutlinedFn != nullptr) CGM.getTargetCodeGenInfo().setTargetAttributes(nullptr, OutlinedFn, CGM); @@ -10136,7 +10133,7 @@ // Is this a target region that should not be emitted as an entry point? If // so just signal we are done with this target region. - if (!OffloadEntriesInfoManager.hasTargetRegionEntryInfo(EntryInfo)) + if (!OMPBuilder.OffloadInfoManager.hasTargetRegionEntryInfo(EntryInfo)) return; switch (E.getDirectiveKind()) { @@ -10392,7 +10389,7 @@ Linkage == llvm::GlobalValue::LinkOnceODRLinkage)) { // Do not create a "ref-variable" if the original is not also available // on the host. - if (!OffloadEntriesInfoManager.hasDeviceGlobalVarEntryInfo(VarName)) + if (!OMPBuilder.OffloadInfoManager.hasDeviceGlobalVarEntryInfo(VarName)) return; std::string RefName = getName({VarName, "ref"}); if (!CGM.GetGlobalValue(RefName)) { @@ -10427,7 +10424,7 @@ Linkage = llvm::GlobalValue::WeakAnyLinkage; } - OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo( + OMPBuilder.OffloadInfoManager.registerDeviceGlobalVarEntryInfo( VarName, Addr, VarSize, Flags, Linkage); } @@ -10562,9 +10559,8 @@ // don't need to do anything. if (CGM.getLangOpts().OMPTargetTriples.empty() || CGM.getLangOpts().OpenMPSimd || CGM.getLangOpts().OpenMPIsDevice || - (OffloadEntriesInfoManager.empty() && - !HasEmittedDeclareTargetRegion && - !HasEmittedTargetRegion)) + (OMPBuilder.OffloadInfoManager.empty() && + !HasEmittedDeclareTargetRegion && !HasEmittedTargetRegion)) return nullptr; // Create and register the function that handles the requires directives. @@ -10585,9 +10581,8 @@ // passed to the runtime. This avoids the runtime from throwing an error // for mismatching requires clauses across compilation units that don't // contain at least 1 target region. - assert((HasEmittedTargetRegion || - HasEmittedDeclareTargetRegion || - !OffloadEntriesInfoManager.empty()) && + assert((HasEmittedTargetRegion || HasEmittedDeclareTargetRegion || + !OMPBuilder.OffloadInfoManager.empty()) && "Target or declare target region expected."); if (HasRequiresUnifiedSharedMemory) Flags = OMP_REQ_UNIFIED_SHARED_MEMORY; diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -863,7 +863,6 @@ hasRequiresUnifiedSharedMemory(), CGM.getLangOpts().OpenMPOffloadMandatory); OMPBuilder.setConfig(Config); - OffloadEntriesInfoManager.setConfig(Config); if (!CGM.getLangOpts().OpenMPIsDevice) llvm_unreachable("OpenMP can only handle device code."); 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 @@ -27,6 +27,7 @@ class CanonicalLoopInfo; struct TargetRegionEntryInfo; class OffloadEntriesInfoManager; +class OpenMPIRBuilder; /// Move the instruction after an InsertPoint to the beginning of another /// BasicBlock. @@ -160,6 +161,251 @@ void setSeparator(StringRef S) { Separator = S; } }; +/// Data structure to contain the information needed to uniquely identify +/// a target entry. +struct TargetRegionEntryInfo { + std::string ParentName; + unsigned DeviceID; + unsigned FileID; + unsigned Line; + unsigned Count; + + TargetRegionEntryInfo() + : ParentName(""), DeviceID(0), FileID(0), Line(0), Count(0) {} + TargetRegionEntryInfo(StringRef ParentName, unsigned DeviceID, + unsigned FileID, unsigned Line, unsigned Count = 0) + : ParentName(ParentName), DeviceID(DeviceID), FileID(FileID), Line(Line), + Count(Count) {} + + static void getTargetRegionEntryFnName(SmallVectorImpl &Name, + StringRef ParentName, + unsigned DeviceID, unsigned FileID, + unsigned Line, unsigned Count); + + bool operator<(const TargetRegionEntryInfo RHS) const { + return std::make_tuple(ParentName, DeviceID, FileID, Line, Count) < + std::make_tuple(RHS.ParentName, RHS.DeviceID, RHS.FileID, RHS.Line, + RHS.Count); + } +}; + +/// Class that manages information about offload code regions and data +class OffloadEntriesInfoManager { + /// Number of entries registered so far. + OpenMPIRBuilder *OMPBuilder; + unsigned OffloadingEntriesNum = 0; + +public: + /// Base class of the entries info. + class OffloadEntryInfo { + public: + /// Kind of a given entry. + enum OffloadingEntryInfoKinds : unsigned { + /// Entry is a target region. + OffloadingEntryInfoTargetRegion = 0, + /// Entry is a declare target variable. + OffloadingEntryInfoDeviceGlobalVar = 1, + /// Invalid entry info. + OffloadingEntryInfoInvalid = ~0u + }; + + protected: + OffloadEntryInfo() = delete; + explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind) : Kind(Kind) {} + explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order, + uint32_t Flags) + : Flags(Flags), Order(Order), Kind(Kind) {} + ~OffloadEntryInfo() = default; + + public: + bool isValid() const { return Order != ~0u; } + unsigned getOrder() const { return Order; } + OffloadingEntryInfoKinds getKind() const { return Kind; } + uint32_t getFlags() const { return Flags; } + void setFlags(uint32_t NewFlags) { Flags = NewFlags; } + Constant *getAddress() const { return cast_or_null(Addr); } + void setAddress(Constant *V) { + assert(!Addr.pointsToAliveValue() && "Address has been set before!"); + Addr = V; + } + static bool classof(const OffloadEntryInfo *Info) { return true; } + + private: + /// Address of the entity that has to be mapped for offloading. + WeakTrackingVH Addr; + + /// Flags associated with the device global. + uint32_t Flags = 0u; + + /// Order this entry was emitted. + unsigned Order = ~0u; + + OffloadingEntryInfoKinds Kind = OffloadingEntryInfoInvalid; + }; + + /// Return true if a there are no entries defined. + bool empty() const; + /// Return number of entries defined so far. + unsigned size() const { return OffloadingEntriesNum; } + + OffloadEntriesInfoManager(OpenMPIRBuilder *builder) : OMPBuilder(builder) {} + + // + // Target region entries related. + // + + /// Kind of the target registry entry. + enum OMPTargetRegionEntryKind : uint32_t { + /// Mark the entry as target region. + OMPTargetRegionEntryTargetRegion = 0x0, + /// Mark the entry as a global constructor. + OMPTargetRegionEntryCtor = 0x02, + /// Mark the entry as a global destructor. + OMPTargetRegionEntryDtor = 0x04, + }; + + /// Target region entries info. + class OffloadEntryInfoTargetRegion final : public OffloadEntryInfo { + /// Address that can be used as the ID of the entry. + Constant *ID = nullptr; + + public: + OffloadEntryInfoTargetRegion() + : OffloadEntryInfo(OffloadingEntryInfoTargetRegion) {} + explicit OffloadEntryInfoTargetRegion(unsigned Order, Constant *Addr, + Constant *ID, + OMPTargetRegionEntryKind Flags) + : OffloadEntryInfo(OffloadingEntryInfoTargetRegion, Order, Flags), + ID(ID) { + setAddress(Addr); + } + + Constant *getID() const { return ID; } + void setID(Constant *V) { + assert(!ID && "ID has been set before!"); + ID = V; + } + static bool classof(const OffloadEntryInfo *Info) { + return Info->getKind() == OffloadingEntryInfoTargetRegion; + } + }; + + /// Initialize target region entry. + /// This is ONLY needed for DEVICE compilation. + void initializeTargetRegionEntryInfo(const TargetRegionEntryInfo &EntryInfo, + unsigned Order); + /// Register target region entry. + void registerTargetRegionEntryInfo(TargetRegionEntryInfo EntryInfo, + Constant *Addr, Constant *ID, + OMPTargetRegionEntryKind Flags); + /// Return true if a target region entry with the provided information + /// exists. + bool hasTargetRegionEntryInfo(TargetRegionEntryInfo EntryInfo, + bool IgnoreAddressId = false) const; + + // Return the Name based on \a EntryInfo using the next available Count. + void getTargetRegionEntryFnName(SmallVectorImpl &Name, + const TargetRegionEntryInfo &EntryInfo); + + /// brief Applies action \a Action on all registered entries. + typedef function_ref + OffloadTargetRegionEntryInfoActTy; + void + actOnTargetRegionEntriesInfo(const OffloadTargetRegionEntryInfoActTy &Action); + + // + // Device global variable entries related. + // + + /// Kind of the global variable entry.. + enum OMPTargetGlobalVarEntryKind : uint32_t { + /// Mark the entry as a to declare target. + OMPTargetGlobalVarEntryTo = 0x0, + /// Mark the entry as a to declare target link. + OMPTargetGlobalVarEntryLink = 0x1, + }; + + /// Device global variable entries info. + class OffloadEntryInfoDeviceGlobalVar final : public OffloadEntryInfo { + /// Type of the global variable. + int64_t VarSize; + GlobalValue::LinkageTypes Linkage; + + public: + OffloadEntryInfoDeviceGlobalVar() + : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar) {} + explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order, + OMPTargetGlobalVarEntryKind Flags) + : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags) {} + explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order, Constant *Addr, + int64_t VarSize, + OMPTargetGlobalVarEntryKind Flags, + GlobalValue::LinkageTypes Linkage) + : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags), + VarSize(VarSize), Linkage(Linkage) { + setAddress(Addr); + } + + int64_t getVarSize() const { return VarSize; } + void setVarSize(int64_t Size) { VarSize = Size; } + GlobalValue::LinkageTypes getLinkage() const { return Linkage; } + void setLinkage(GlobalValue::LinkageTypes LT) { Linkage = LT; } + static bool classof(const OffloadEntryInfo *Info) { + return Info->getKind() == OffloadingEntryInfoDeviceGlobalVar; + } + }; + + /// Initialize device global variable entry. + /// This is ONLY used for DEVICE compilation. + void initializeDeviceGlobalVarEntryInfo(StringRef Name, + OMPTargetGlobalVarEntryKind Flags, + unsigned Order); + + /// Register device global variable entry. + void registerDeviceGlobalVarEntryInfo(StringRef VarName, Constant *Addr, + int64_t VarSize, + OMPTargetGlobalVarEntryKind Flags, + GlobalValue::LinkageTypes Linkage); + /// Checks if the variable with the given name has been registered already. + bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const { + return OffloadEntriesDeviceGlobalVar.count(VarName) > 0; + } + /// Applies action \a Action on all registered entries. + typedef function_ref + OffloadDeviceGlobalVarEntryInfoActTy; + void actOnDeviceGlobalVarEntriesInfo( + const OffloadDeviceGlobalVarEntryInfoActTy &Action); + +private: + /// Return the count of entries at a particular source location. + unsigned + getTargetRegionEntryInfoCount(const TargetRegionEntryInfo &EntryInfo) const; + + /// Update the count of entries at a particular source location. + void + incrementTargetRegionEntryInfoCount(const TargetRegionEntryInfo &EntryInfo); + + static TargetRegionEntryInfo + getTargetRegionEntryCountKey(const TargetRegionEntryInfo &EntryInfo) { + return TargetRegionEntryInfo(EntryInfo.ParentName, EntryInfo.DeviceID, + EntryInfo.FileID, EntryInfo.Line, 0); + } + + // Count of entries at a location. + std::map OffloadEntriesTargetRegionCount; + + // Storage for target region entries kind. + typedef std::map + OffloadEntriesTargetRegionTy; + OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion; + /// Storage for device global variable entries kind. The storage is to be + /// indexed by mangled name. + typedef StringMap + OffloadEntriesDeviceGlobalVarTy; + OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar; +}; + /// An interface to create LLVM-IR for OpenMP directives. /// /// Each OpenMP directive has a corresponding public generator method. @@ -167,7 +413,8 @@ public: /// Create a new OpenMPIRBuilder operating on the given module \p M. This will /// not have an effect on \p M (see initialize) - OpenMPIRBuilder(Module &M) : M(M), Builder(M.getContext()) {} + OpenMPIRBuilder(Module &M) + : M(M), Builder(M.getContext()), OffloadInfoManager(this) {} ~OpenMPIRBuilder(); /// Initialize the internal state, this will put structures types and @@ -1063,6 +1310,9 @@ /// Map to remember existing ident_t*. DenseMap, Constant *> IdentMap; + /// Info manager to keep track of target regions. + OffloadEntriesInfoManager OffloadInfoManager; + /// Helper that contains information about regions we need to outline /// during finalization. struct OutlineInfo { @@ -1231,7 +1481,6 @@ // // We only generate metadata for function that contain target regions. void createOffloadEntriesAndInfoMetadata( - OffloadEntriesInfoManager &OffloadEntriesInfoManager, EmitMetadataErrorReportFunctionTy &ErrorReportFunction); public: @@ -1531,8 +1780,7 @@ /// \param NumThreads Number default threads /// \param OutlinedFunction Pointer to the outlined function /// \param EntryFnIDName Name of the ID o be created - void emitTargetRegionFunction(OffloadEntriesInfoManager &InfoManager, - TargetRegionEntryInfo &EntryInfo, + void emitTargetRegionFunction(TargetRegionEntryInfo &EntryInfo, FunctionGenCallback &GenerateFunctionCallback, int32_t NumTeams, int32_t NumThreads, bool IsOffloadEntry, Function *&OutlinedFn, @@ -1548,8 +1796,7 @@ /// \param EntryFnIDName Name of the ID o be created /// \param NumTeams Number default teams /// \param NumThreads Number default threads - Constant *registerTargetRegionFunction(OffloadEntriesInfoManager &InfoManager, - TargetRegionEntryInfo &EntryInfo, + Constant *registerTargetRegionFunction(TargetRegionEntryInfo &EntryInfo, Function *OutlinedFunction, StringRef EntryFnName, StringRef EntryFnIDName, @@ -1918,10 +2165,7 @@ /// /// \param M Module to load Metadata info from. Module passed maybe /// loaded from bitcode file, i.e, different from OpenMPIRBuilder::M module. - /// \param OffloadEntriesInfoManager Initialize Offload Entry information. - void - loadOffloadInfoMetadata(Module &M, - OffloadEntriesInfoManager &OffloadEntriesInfoManager); + void loadOffloadInfoMetadata(Module &M); /// Gets (if variable with the given name already exist) or creates /// internal global variable with the specified Name. The created variable has @@ -1933,253 +2177,6 @@ unsigned AddressSpace = 0); }; -/// Data structure to contain the information needed to uniquely identify -/// a target entry. -struct TargetRegionEntryInfo { - std::string ParentName; - unsigned DeviceID; - unsigned FileID; - unsigned Line; - unsigned Count; - - TargetRegionEntryInfo() - : ParentName(""), DeviceID(0), FileID(0), Line(0), Count(0) {} - TargetRegionEntryInfo(StringRef ParentName, unsigned DeviceID, - unsigned FileID, unsigned Line, unsigned Count = 0) - : ParentName(ParentName), DeviceID(DeviceID), FileID(FileID), Line(Line), - Count(Count) {} - - static void getTargetRegionEntryFnName(SmallVectorImpl &Name, - StringRef ParentName, - unsigned DeviceID, unsigned FileID, - unsigned Line, unsigned Count); - - bool operator<(const TargetRegionEntryInfo RHS) const { - return std::make_tuple(ParentName, DeviceID, FileID, Line, Count) < - std::make_tuple(RHS.ParentName, RHS.DeviceID, RHS.FileID, RHS.Line, - RHS.Count); - } -}; - -/// Class that manages information about offload code regions and data -class OffloadEntriesInfoManager { - /// Number of entries registered so far. - OpenMPIRBuilderConfig Config; - unsigned OffloadingEntriesNum = 0; - -public: - void setConfig(OpenMPIRBuilderConfig C) { Config = C; } - - /// Base class of the entries info. - class OffloadEntryInfo { - public: - /// Kind of a given entry. - enum OffloadingEntryInfoKinds : unsigned { - /// Entry is a target region. - OffloadingEntryInfoTargetRegion = 0, - /// Entry is a declare target variable. - OffloadingEntryInfoDeviceGlobalVar = 1, - /// Invalid entry info. - OffloadingEntryInfoInvalid = ~0u - }; - - protected: - OffloadEntryInfo() = delete; - explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind) : Kind(Kind) {} - explicit OffloadEntryInfo(OffloadingEntryInfoKinds Kind, unsigned Order, - uint32_t Flags) - : Flags(Flags), Order(Order), Kind(Kind) {} - ~OffloadEntryInfo() = default; - - public: - bool isValid() const { return Order != ~0u; } - unsigned getOrder() const { return Order; } - OffloadingEntryInfoKinds getKind() const { return Kind; } - uint32_t getFlags() const { return Flags; } - void setFlags(uint32_t NewFlags) { Flags = NewFlags; } - Constant *getAddress() const { return cast_or_null(Addr); } - void setAddress(Constant *V) { - assert(!Addr.pointsToAliveValue() && "Address has been set before!"); - Addr = V; - } - static bool classof(const OffloadEntryInfo *Info) { return true; } - - private: - /// Address of the entity that has to be mapped for offloading. - WeakTrackingVH Addr; - - /// Flags associated with the device global. - uint32_t Flags = 0u; - - /// Order this entry was emitted. - unsigned Order = ~0u; - - OffloadingEntryInfoKinds Kind = OffloadingEntryInfoInvalid; - }; - - /// Return true if a there are no entries defined. - bool empty() const; - /// Return number of entries defined so far. - unsigned size() const { return OffloadingEntriesNum; } - - OffloadEntriesInfoManager() : Config() {} - - // - // Target region entries related. - // - - /// Kind of the target registry entry. - enum OMPTargetRegionEntryKind : uint32_t { - /// Mark the entry as target region. - OMPTargetRegionEntryTargetRegion = 0x0, - /// Mark the entry as a global constructor. - OMPTargetRegionEntryCtor = 0x02, - /// Mark the entry as a global destructor. - OMPTargetRegionEntryDtor = 0x04, - }; - - /// Target region entries info. - class OffloadEntryInfoTargetRegion final : public OffloadEntryInfo { - /// Address that can be used as the ID of the entry. - Constant *ID = nullptr; - - public: - OffloadEntryInfoTargetRegion() - : OffloadEntryInfo(OffloadingEntryInfoTargetRegion) {} - explicit OffloadEntryInfoTargetRegion(unsigned Order, Constant *Addr, - Constant *ID, - OMPTargetRegionEntryKind Flags) - : OffloadEntryInfo(OffloadingEntryInfoTargetRegion, Order, Flags), - ID(ID) { - setAddress(Addr); - } - - Constant *getID() const { return ID; } - void setID(Constant *V) { - assert(!ID && "ID has been set before!"); - ID = V; - } - static bool classof(const OffloadEntryInfo *Info) { - return Info->getKind() == OffloadingEntryInfoTargetRegion; - } - }; - - /// Initialize target region entry. - /// This is ONLY needed for DEVICE compilation. - void initializeTargetRegionEntryInfo(const TargetRegionEntryInfo &EntryInfo, - unsigned Order); - /// Register target region entry. - void registerTargetRegionEntryInfo(TargetRegionEntryInfo EntryInfo, - Constant *Addr, Constant *ID, - OMPTargetRegionEntryKind Flags); - /// Return true if a target region entry with the provided information - /// exists. - bool hasTargetRegionEntryInfo(TargetRegionEntryInfo EntryInfo, - bool IgnoreAddressId = false) const; - - // Return the Name based on \a EntryInfo using the next available Count. - void getTargetRegionEntryFnName(SmallVectorImpl &Name, - const TargetRegionEntryInfo &EntryInfo); - - /// brief Applies action \a Action on all registered entries. - typedef function_ref - OffloadTargetRegionEntryInfoActTy; - void - actOnTargetRegionEntriesInfo(const OffloadTargetRegionEntryInfoActTy &Action); - - // - // Device global variable entries related. - // - - /// Kind of the global variable entry.. - enum OMPTargetGlobalVarEntryKind : uint32_t { - /// Mark the entry as a to declare target. - OMPTargetGlobalVarEntryTo = 0x0, - /// Mark the entry as a to declare target link. - OMPTargetGlobalVarEntryLink = 0x1, - }; - - /// Device global variable entries info. - class OffloadEntryInfoDeviceGlobalVar final : public OffloadEntryInfo { - /// Type of the global variable. - int64_t VarSize; - GlobalValue::LinkageTypes Linkage; - - public: - OffloadEntryInfoDeviceGlobalVar() - : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar) {} - explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order, - OMPTargetGlobalVarEntryKind Flags) - : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags) {} - explicit OffloadEntryInfoDeviceGlobalVar(unsigned Order, Constant *Addr, - int64_t VarSize, - OMPTargetGlobalVarEntryKind Flags, - GlobalValue::LinkageTypes Linkage) - : OffloadEntryInfo(OffloadingEntryInfoDeviceGlobalVar, Order, Flags), - VarSize(VarSize), Linkage(Linkage) { - setAddress(Addr); - } - - int64_t getVarSize() const { return VarSize; } - void setVarSize(int64_t Size) { VarSize = Size; } - GlobalValue::LinkageTypes getLinkage() const { return Linkage; } - void setLinkage(GlobalValue::LinkageTypes LT) { Linkage = LT; } - static bool classof(const OffloadEntryInfo *Info) { - return Info->getKind() == OffloadingEntryInfoDeviceGlobalVar; - } - }; - - /// Initialize device global variable entry. - /// This is ONLY used for DEVICE compilation. - void initializeDeviceGlobalVarEntryInfo(StringRef Name, - OMPTargetGlobalVarEntryKind Flags, - unsigned Order); - - /// Register device global variable entry. - void registerDeviceGlobalVarEntryInfo(StringRef VarName, Constant *Addr, - int64_t VarSize, - OMPTargetGlobalVarEntryKind Flags, - GlobalValue::LinkageTypes Linkage); - /// Checks if the variable with the given name has been registered already. - bool hasDeviceGlobalVarEntryInfo(StringRef VarName) const { - return OffloadEntriesDeviceGlobalVar.count(VarName) > 0; - } - /// Applies action \a Action on all registered entries. - typedef function_ref - OffloadDeviceGlobalVarEntryInfoActTy; - void actOnDeviceGlobalVarEntriesInfo( - const OffloadDeviceGlobalVarEntryInfoActTy &Action); - -private: - /// Return the count of entries at a particular source location. - unsigned - getTargetRegionEntryInfoCount(const TargetRegionEntryInfo &EntryInfo) const; - - /// Update the count of entries at a particular source location. - void - incrementTargetRegionEntryInfoCount(const TargetRegionEntryInfo &EntryInfo); - - static TargetRegionEntryInfo - getTargetRegionEntryCountKey(const TargetRegionEntryInfo &EntryInfo) { - return TargetRegionEntryInfo(EntryInfo.ParentName, EntryInfo.DeviceID, - EntryInfo.FileID, EntryInfo.Line, 0); - } - - // Count of entries at a location. - std::map OffloadEntriesTargetRegionCount; - - // Storage for target region entries kind. - typedef std::map - OffloadEntriesTargetRegionTy; - OffloadEntriesTargetRegionTy OffloadEntriesTargetRegion; - /// Storage for device global variable entries kind. The storage is to be - /// indexed by mangled name. - typedef StringMap - OffloadEntriesDeviceGlobalVarTy; - OffloadEntriesDeviceGlobalVarTy OffloadEntriesDeviceGlobalVar; -}; - /// Class to represented the control flow structure of an OpenMP canonical loop. /// /// The control-flow structure is standardized for easy consumption by 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 @@ -3999,13 +3999,13 @@ } void OpenMPIRBuilder::emitTargetRegionFunction( - OffloadEntriesInfoManager &InfoManager, TargetRegionEntryInfo &EntryInfo, + TargetRegionEntryInfo &EntryInfo, FunctionGenCallback &GenerateFunctionCallback, int32_t NumTeams, int32_t NumThreads, bool IsOffloadEntry, Function *&OutlinedFn, Constant *&OutlinedFnID) { SmallString<64> EntryFnName; - InfoManager.getTargetRegionEntryFnName(EntryFnName, EntryInfo); + OffloadInfoManager.getTargetRegionEntryFnName(EntryFnName, EntryInfo); OutlinedFn = Config.isEmbedded() || !Config.openMPOffloadMandatory() ? GenerateFunctionCallback(EntryFnName) @@ -4023,19 +4023,18 @@ : createPlatformSpecificName({EntryFnName, "region_id"}); OutlinedFnID = registerTargetRegionFunction( - InfoManager, EntryInfo, OutlinedFn, EntryFnName, EntryFnIDName, NumTeams, - NumThreads); + EntryInfo, OutlinedFn, EntryFnName, EntryFnIDName, NumTeams, NumThreads); } Constant *OpenMPIRBuilder::registerTargetRegionFunction( - OffloadEntriesInfoManager &InfoManager, TargetRegionEntryInfo &EntryInfo, - Function *OutlinedFn, StringRef EntryFnName, StringRef EntryFnIDName, - int32_t NumTeams, int32_t NumThreads) { + TargetRegionEntryInfo &EntryInfo, Function *OutlinedFn, + StringRef EntryFnName, StringRef EntryFnIDName, int32_t NumTeams, + int32_t NumThreads) { if (OutlinedFn) setOutlinedTargetRegionFunctionAttributes(OutlinedFn, NumTeams, NumThreads); auto OutlinedFnID = createOutlinedFunctionID(OutlinedFn, EntryFnIDName); auto EntryAddr = createTargetRegionEntryAddr(OutlinedFn, EntryFnName); - InfoManager.registerTargetRegionEntryInfo( + OffloadInfoManager.registerTargetRegionEntryInfo( EntryInfo, EntryAddr, OutlinedFnID, OffloadEntriesInfoManager::OMPTargetRegionEntryTargetRegion); return OutlinedFnID; @@ -4897,18 +4896,17 @@ // We only generate metadata for function that contain target regions. void OpenMPIRBuilder::createOffloadEntriesAndInfoMetadata( - OffloadEntriesInfoManager &OffloadEntriesInfoManager, EmitMetadataErrorReportFunctionTy &ErrorFn) { // If there are no entries, we don't need to do anything. - if (OffloadEntriesInfoManager.empty()) + if (OffloadInfoManager.empty()) return; LLVMContext &C = M.getContext(); SmallVector, 16> - OrderedEntries(OffloadEntriesInfoManager.size()); + OrderedEntries(OffloadInfoManager.size()); // Auxiliary methods to create metadata values and strings. auto &&GetMDInt = [this](unsigned V) { @@ -4947,8 +4945,7 @@ MD->addOperand(MDNode::get(C, Ops)); }; - OffloadEntriesInfoManager.actOnTargetRegionEntriesInfo( - TargetRegionMetadataEmitter); + OffloadInfoManager.actOnTargetRegionEntriesInfo(TargetRegionMetadataEmitter); // Create function that emits metadata for each device global variable entry; auto &&DeviceGlobalVarMetadataEmitter = @@ -4973,7 +4970,7 @@ MD->addOperand(MDNode::get(C, Ops)); }; - OffloadEntriesInfoManager.actOnDeviceGlobalVarEntriesInfo( + OffloadInfoManager.actOnDeviceGlobalVarEntriesInfo( DeviceGlobalVarMetadataEmitter); for (const auto &E : OrderedEntries) { @@ -5061,8 +5058,7 @@ /// Loads all the offload entries information from the host IR /// metadata. -void OpenMPIRBuilder::loadOffloadInfoMetadata( - Module &M, OffloadEntriesInfoManager &OffloadEntriesInfoManager) { +void OpenMPIRBuilder::loadOffloadInfoMetadata(Module &M) { // If we are in target mode, load the metadata from the host IR. This code has // to match the metadata creation in createOffloadEntriesAndInfoMetadata(). @@ -5092,13 +5088,13 @@ /*FileID=*/GetMDInt(2), /*Line=*/GetMDInt(4), /*Count=*/GetMDInt(5)); - OffloadEntriesInfoManager.initializeTargetRegionEntryInfo( - EntryInfo, /*Order=*/GetMDInt(6)); + OffloadInfoManager.initializeTargetRegionEntryInfo(EntryInfo, + /*Order=*/GetMDInt(6)); break; } case OffloadEntriesInfoManager::OffloadEntryInfo:: OffloadingEntryInfoDeviceGlobalVar: - OffloadEntriesInfoManager.initializeDeviceGlobalVarEntryInfo( + OffloadInfoManager.initializeDeviceGlobalVarEntryInfo( /*MangledName=*/GetMDString(1), static_cast( /*Flags=*/GetMDInt(2)), @@ -5147,7 +5143,7 @@ // If we are emitting code for a target, the entry is already initialized, // only has to be registered. - if (Config.isEmbedded()) { + if (OMPBuilder->Config.isEmbedded()) { // This could happen if the device compilation is invoked standalone. if (!hasTargetRegionEntryInfo(EntryInfo)) { return; @@ -5202,7 +5198,7 @@ void OffloadEntriesInfoManager::registerDeviceGlobalVarEntryInfo( StringRef VarName, Constant *Addr, int64_t VarSize, OMPTargetGlobalVarEntryKind Flags, GlobalValue::LinkageTypes Linkage) { - if (Config.isEmbedded()) { + if (OMPBuilder->Config.isEmbedded()) { // This could happen if the device compilation is invoked standalone. if (!hasDeviceGlobalVarEntryInfo(VarName)) return; diff --git a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp --- a/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp +++ b/llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp @@ -5730,8 +5730,9 @@ } TEST_F(OpenMPIRBuilderTest, OffloadEntriesInfoManager) { - OffloadEntriesInfoManager InfoManager; - InfoManager.setConfig(OpenMPIRBuilderConfig(true, false, false, false)); + OpenMPIRBuilder OMPBuilder(*M); + OMPBuilder.setConfig(OpenMPIRBuilderConfig(true, false, false, false)); + OffloadEntriesInfoManager &InfoManager = OMPBuilder.OffloadInfoManager; TargetRegionEntryInfo EntryInfo("parent", 1, 2, 4, 0); InfoManager.initializeTargetRegionEntryInfo(EntryInfo, 0); EXPECT_TRUE(InfoManager.hasTargetRegionEntryInfo(EntryInfo));