| //===-- llvm/GlobalValue.h - Class to represent a global value --*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file is a common base class of all globally definable objects. As such, |
| // it is subclassed by GlobalVariable, GlobalAlias and by Function. This is |
| // used because you can do certain things with these global objects that you |
| // can't do to anything else. For example, use the address of one as a |
| // constant. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_IR_GLOBALVALUE_H |
| #define LLVM_IR_GLOBALVALUE_H |
| |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/ADT/Twine.h" |
| #include "llvm/IR/Constant.h" |
| #include "llvm/IR/DerivedTypes.h" |
| #include "llvm/IR/Value.h" |
| #include "llvm/Support/MD5.h" |
| #include "llvm/Support/Casting.h" |
| #include "llvm/Support/ErrorHandling.h" |
| #include <cassert> |
| #include <cstdint> |
| #include <string> |
| |
| namespace llvm { |
| |
| class Comdat; |
| class ConstantRange; |
| class Error; |
| class GlobalObject; |
| class Module; |
| |
| namespace Intrinsic { |
| enum ID : unsigned; |
| } // end namespace Intrinsic |
| |
| class GlobalValue : public Constant { |
| public: |
| /// @brief An enumeration for the kinds of linkage for global values. |
| enum LinkageTypes { |
| ExternalLinkage = 0,///< Externally visible function |
| AvailableExternallyLinkage, ///< Available for inspection, not emission. |
| LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline) |
| LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent. |
| WeakAnyLinkage, ///< Keep one copy of named function when linking (weak) |
| WeakODRLinkage, ///< Same, but only replaced by something equivalent. |
| AppendingLinkage, ///< Special purpose, only applies to global arrays |
| InternalLinkage, ///< Rename collisions when linking (static functions). |
| PrivateLinkage, ///< Like Internal, but omit from symbol table. |
| ExternalWeakLinkage,///< ExternalWeak linkage description. |
| CommonLinkage ///< Tentative definitions. |
| }; |
| |
| /// @brief An enumeration for the kinds of visibility of global values. |
| enum VisibilityTypes { |
| DefaultVisibility = 0, ///< The GV is visible |
| HiddenVisibility, ///< The GV is hidden |
| ProtectedVisibility ///< The GV is protected |
| }; |
| |
| /// @brief Storage classes of global values for PE targets. |
| enum DLLStorageClassTypes { |
| DefaultStorageClass = 0, |
| DLLImportStorageClass = 1, ///< Function to be imported from DLL |
| DLLExportStorageClass = 2 ///< Function to be accessible from DLL. |
| }; |
| |
| protected: |
| GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, |
| LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace) |
| : Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps), |
| ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility), |
| UnnamedAddrVal(unsigned(UnnamedAddr::None)), |
| DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal), |
| IntID((Intrinsic::ID)0U), Parent(nullptr) { |
| setName(Name); |
| } |
| |
| Type *ValueType; |
| // All bitfields use unsigned as the underlying type so that MSVC will pack |
| // them. |
| unsigned Linkage : 4; // The linkage of this global |
| unsigned Visibility : 2; // The visibility style of this global |
| unsigned UnnamedAddrVal : 2; // This value's address is not significant |
| unsigned DllStorageClass : 2; // DLL storage class |
| |
| unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is |
| // the desired model? |
| static const unsigned GlobalValueSubClassDataBits = 19; |
| |
| private: |
| friend class Constant; |
| |
| // Give subclasses access to what otherwise would be wasted padding. |
| // (19 + 4 + 2 + 2 + 2 + 3) == 32. |
| unsigned SubClassData : GlobalValueSubClassDataBits; |
| |
| void destroyConstantImpl(); |
| Value *handleOperandChangeImpl(Value *From, Value *To); |
| |
| /// Returns true if the definition of this global may be replaced by a |
| /// differently optimized variant of the same source level function at link |
| /// time. |
| bool mayBeDerefined() const { |
| switch (getLinkage()) { |
| case WeakODRLinkage: |
| case LinkOnceODRLinkage: |
| case AvailableExternallyLinkage: |
| return true; |
| |
| case WeakAnyLinkage: |
| case LinkOnceAnyLinkage: |
| case CommonLinkage: |
| case ExternalWeakLinkage: |
| case ExternalLinkage: |
| case AppendingLinkage: |
| case InternalLinkage: |
| case PrivateLinkage: |
| return isInterposable(); |
| } |
| |
| llvm_unreachable("Fully covered switch above!"); |
| } |
| |
| protected: |
| /// \brief The intrinsic ID for this subclass (which must be a Function). |
| /// |
| /// This member is defined by this class, but not used for anything. |
| /// Subclasses can use it to store their intrinsic ID, if they have one. |
| /// |
| /// This is stored here to save space in Function on 64-bit hosts. |
| Intrinsic::ID IntID; |
| |
| unsigned getGlobalValueSubClassData() const { |
| return SubClassData; |
| } |
| void setGlobalValueSubClassData(unsigned V) { |
| assert(V < (1 << GlobalValueSubClassDataBits) && "It will not fit"); |
| SubClassData = V; |
| } |
| |
| Module *Parent; // The containing module. |
| |
| // Used by SymbolTableListTraits. |
| void setParent(Module *parent) { |
| Parent = parent; |
| } |
| |
| public: |
| enum ThreadLocalMode { |
| NotThreadLocal = 0, |
| GeneralDynamicTLSModel, |
| LocalDynamicTLSModel, |
| InitialExecTLSModel, |
| LocalExecTLSModel |
| }; |
| |
| GlobalValue(const GlobalValue &) = delete; |
| |
| ~GlobalValue() override { |
| removeDeadConstantUsers(); // remove any dead constants using this. |
| } |
| |
| unsigned getAlignment() const; |
| |
| enum class UnnamedAddr { |
| None, |
| Local, |
| Global, |
| }; |
| |
| bool hasGlobalUnnamedAddr() const { |
| return getUnnamedAddr() == UnnamedAddr::Global; |
| } |
| |
| /// Returns true if this value's address is not significant in this module. |
| /// This attribute is intended to be used only by the code generator and LTO |
| /// to allow the linker to decide whether the global needs to be in the symbol |
| /// table. It should probably not be used in optimizations, as the value may |
| /// have uses outside the module; use hasGlobalUnnamedAddr() instead. |
| bool hasAtLeastLocalUnnamedAddr() const { |
| return getUnnamedAddr() != UnnamedAddr::None; |
| } |
| |
| UnnamedAddr getUnnamedAddr() const { |
| return UnnamedAddr(UnnamedAddrVal); |
| } |
| void setUnnamedAddr(UnnamedAddr Val) { UnnamedAddrVal = unsigned(Val); } |
| |
| static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) { |
| if (A == UnnamedAddr::None || B == UnnamedAddr::None) |
| return UnnamedAddr::None; |
| if (A == UnnamedAddr::Local || B == UnnamedAddr::Local) |
| return UnnamedAddr::Local; |
| return UnnamedAddr::Global; |
| } |
| |
| bool hasComdat() const { return getComdat() != nullptr; } |
| Comdat *getComdat(); |
| const Comdat *getComdat() const { |
| return const_cast<GlobalValue *>(this)->getComdat(); |
| } |
| |
| VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); } |
| bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; } |
| bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; } |
| bool hasProtectedVisibility() const { |
| return Visibility == ProtectedVisibility; |
| } |
| void setVisibility(VisibilityTypes V) { |
| assert((!hasLocalLinkage() || V == DefaultVisibility) && |
| "local linkage requires default visibility"); |
| Visibility = V; |
| } |
| |
| /// If the value is "Thread Local", its value isn't shared by the threads. |
| bool isThreadLocal() const { return getThreadLocalMode() != NotThreadLocal; } |
| void setThreadLocal(bool Val) { |
| setThreadLocalMode(Val ? GeneralDynamicTLSModel : NotThreadLocal); |
| } |
| void setThreadLocalMode(ThreadLocalMode Val) { |
| assert(Val == NotThreadLocal || getValueID() != Value::FunctionVal); |
| ThreadLocal = Val; |
| } |
| ThreadLocalMode getThreadLocalMode() const { |
| return static_cast<ThreadLocalMode>(ThreadLocal); |
| } |
| |
| DLLStorageClassTypes getDLLStorageClass() const { |
| return DLLStorageClassTypes(DllStorageClass); |
| } |
| bool hasDLLImportStorageClass() const { |
| return DllStorageClass == DLLImportStorageClass; |
| } |
| bool hasDLLExportStorageClass() const { |
| return DllStorageClass == DLLExportStorageClass; |
| } |
| void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; } |
| |
| bool hasSection() const { return !getSection().empty(); } |
| StringRef getSection() const; |
| |
| /// Global values are always pointers. |
| PointerType *getType() const { return cast<PointerType>(User::getType()); } |
| |
| Type *getValueType() const { return ValueType; } |
| |
| static LinkageTypes getLinkOnceLinkage(bool ODR) { |
| return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; |
| } |
| static LinkageTypes getWeakLinkage(bool ODR) { |
| return ODR ? WeakODRLinkage : WeakAnyLinkage; |
| } |
| |
| static bool isExternalLinkage(LinkageTypes Linkage) { |
| return Linkage == ExternalLinkage; |
| } |
| static bool isAvailableExternallyLinkage(LinkageTypes Linkage) { |
| return Linkage == AvailableExternallyLinkage; |
| } |
| static bool isLinkOnceODRLinkage(LinkageTypes Linkage) { |
| return Linkage == LinkOnceODRLinkage; |
| } |
| static bool isLinkOnceLinkage(LinkageTypes Linkage) { |
| return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage; |
| } |
| static bool isWeakAnyLinkage(LinkageTypes Linkage) { |
| return Linkage == WeakAnyLinkage; |
| } |
| static bool isWeakODRLinkage(LinkageTypes Linkage) { |
| return Linkage == WeakODRLinkage; |
| } |
| static bool isWeakLinkage(LinkageTypes Linkage) { |
| return isWeakAnyLinkage(Linkage) || isWeakODRLinkage(Linkage); |
| } |
| static bool isAppendingLinkage(LinkageTypes Linkage) { |
| return Linkage == AppendingLinkage; |
| } |
| static bool isInternalLinkage(LinkageTypes Linkage) { |
| return Linkage == InternalLinkage; |
| } |
| static bool isPrivateLinkage(LinkageTypes Linkage) { |
| return Linkage == PrivateLinkage; |
| } |
| static bool isLocalLinkage(LinkageTypes Linkage) { |
| return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage); |
| } |
| static bool isExternalWeakLinkage(LinkageTypes Linkage) { |
| return Linkage == ExternalWeakLinkage; |
| } |
| static bool isCommonLinkage(LinkageTypes Linkage) { |
| return Linkage == CommonLinkage; |
| } |
| static bool isValidDeclarationLinkage(LinkageTypes Linkage) { |
| return isExternalWeakLinkage(Linkage) || isExternalLinkage(Linkage); |
| } |
| |
| /// Whether the definition of this global may be replaced by something |
| /// non-equivalent at link time. For example, if a function has weak linkage |
| /// then the code defining it may be replaced by different code. |
| static bool isInterposableLinkage(LinkageTypes Linkage) { |
| switch (Linkage) { |
| case WeakAnyLinkage: |
| case LinkOnceAnyLinkage: |
| case CommonLinkage: |
| case ExternalWeakLinkage: |
| return true; |
| |
| case AvailableExternallyLinkage: |
| case LinkOnceODRLinkage: |
| case WeakODRLinkage: |
| // The above three cannot be overridden but can be de-refined. |
| |
| case ExternalLinkage: |
| case AppendingLinkage: |
| case InternalLinkage: |
| case PrivateLinkage: |
| return false; |
| } |
| llvm_unreachable("Fully covered switch above!"); |
| } |
| |
| /// Whether the definition of this global may be discarded if it is not used |
| /// in its compilation unit. |
| static bool isDiscardableIfUnused(LinkageTypes Linkage) { |
| return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage) || |
| isAvailableExternallyLinkage(Linkage); |
| } |
| |
| /// Whether the definition of this global may be replaced at link time. NB: |
| /// Using this method outside of the code generators is almost always a |
| /// mistake: when working at the IR level use isInterposable instead as it |
| /// knows about ODR semantics. |
| static bool isWeakForLinker(LinkageTypes Linkage) { |
| return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage || |
| Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage || |
| Linkage == CommonLinkage || Linkage == ExternalWeakLinkage; |
| } |
| |
| /// Return true if the currently visible definition of this global (if any) is |
| /// exactly the definition we will see at runtime. |
| /// |
| /// Non-exact linkage types inhibits most non-inlining IPO, since a |
| /// differently optimized variant of the same function can have different |
| /// observable or undefined behavior than in the variant currently visible. |
| /// For instance, we could have started with |
| /// |
| /// void foo(int *v) { |
| /// int t = 5 / v[0]; |
| /// (void) t; |
| /// } |
| /// |
| /// and "refined" it to |
| /// |
| /// void foo(int *v) { } |
| /// |
| /// However, we cannot infer readnone for `foo`, since that would justify |
| /// DSE'ing a store to `v[0]` across a call to `foo`, which can cause |
| /// undefined behavior if the linker replaces the actual call destination with |
| /// the unoptimized `foo`. |
| /// |
| /// Inlining is okay across non-exact linkage types as long as they're not |
| /// interposable (see \c isInterposable), since in such cases the currently |
| /// visible variant is *a* correct implementation of the original source |
| /// function; it just isn't the *only* correct implementation. |
| bool isDefinitionExact() const { |
| return !mayBeDerefined(); |
| } |
| |
| /// Return true if this global has an exact defintion. |
| bool hasExactDefinition() const { |
| // While this computes exactly the same thing as |
| // isStrongDefinitionForLinker, the intended uses are different. This |
| // function is intended to help decide if specific inter-procedural |
| // transforms are correct, while isStrongDefinitionForLinker's intended use |
| // is in low level code generation. |
| return !isDeclaration() && isDefinitionExact(); |
| } |
| |
| /// Return true if this global's definition can be substituted with an |
| /// *arbitrary* definition at link time. We cannot do any IPO or inlinining |
| /// across interposable call edges, since the callee can be replaced with |
| /// something arbitrary at link time. |
| bool isInterposable() const { return isInterposableLinkage(getLinkage()); } |
| |
| bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); } |
| bool hasAvailableExternallyLinkage() const { |
| return isAvailableExternallyLinkage(getLinkage()); |
| } |
| bool hasLinkOnceLinkage() const { return isLinkOnceLinkage(getLinkage()); } |
| bool hasLinkOnceODRLinkage() const { |
| return isLinkOnceODRLinkage(getLinkage()); |
| } |
| bool hasWeakLinkage() const { return isWeakLinkage(getLinkage()); } |
| bool hasWeakAnyLinkage() const { return isWeakAnyLinkage(getLinkage()); } |
| bool hasWeakODRLinkage() const { return isWeakODRLinkage(getLinkage()); } |
| bool hasAppendingLinkage() const { return isAppendingLinkage(getLinkage()); } |
| bool hasInternalLinkage() const { return isInternalLinkage(getLinkage()); } |
| bool hasPrivateLinkage() const { return isPrivateLinkage(getLinkage()); } |
| bool hasLocalLinkage() const { return isLocalLinkage(getLinkage()); } |
| bool hasExternalWeakLinkage() const { |
| return isExternalWeakLinkage(getLinkage()); |
| } |
| bool hasCommonLinkage() const { return isCommonLinkage(getLinkage()); } |
| bool hasValidDeclarationLinkage() const { |
| return isValidDeclarationLinkage(getLinkage()); |
| } |
| |
| void setLinkage(LinkageTypes LT) { |
| if (isLocalLinkage(LT)) |
| Visibility = DefaultVisibility; |
| Linkage = LT; |
| } |
| LinkageTypes getLinkage() const { return LinkageTypes(Linkage); } |
| |
| bool isDiscardableIfUnused() const { |
| return isDiscardableIfUnused(getLinkage()); |
| } |
| |
| bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); } |
| |
| /// Copy all additional attributes (those not needed to create a GlobalValue) |
| /// from the GlobalValue Src to this one. |
| virtual void copyAttributesFrom(const GlobalValue *Src); |
| |
| /// If special LLVM prefix that is used to inform the asm printer to not emit |
| /// usual symbol prefix before the symbol name is used then return linkage |
| /// name after skipping this special LLVM prefix. |
| static StringRef getRealLinkageName(StringRef Name) { |
| if (!Name.empty() && Name[0] == '\1') |
| return Name.substr(1); |
| return Name; |
| } |
| |
| /// Return the modified name for a global value suitable to be |
| /// used as the key for a global lookup (e.g. profile or ThinLTO). |
| /// The value's original name is \c Name and has linkage of type |
| /// \c Linkage. The value is defined in module \c FileName. |
| static std::string getGlobalIdentifier(StringRef Name, |
| GlobalValue::LinkageTypes Linkage, |
| StringRef FileName); |
| |
| /// Return the modified name for this global value suitable to be |
| /// used as the key for a global lookup (e.g. profile or ThinLTO). |
| std::string getGlobalIdentifier() const; |
| |
| /// Declare a type to represent a global unique identifier for a global value. |
| /// This is a 64 bits hash that is used by PGO and ThinLTO to have a compact |
| /// unique way to identify a symbol. |
| using GUID = uint64_t; |
| |
| /// Return a 64-bit global unique ID constructed from global value name |
| /// (i.e. returned by getGlobalIdentifier()). |
| static GUID getGUID(StringRef GlobalName) { return MD5Hash(GlobalName); } |
| |
| /// Return a 64-bit global unique ID constructed from global value name |
| /// (i.e. returned by getGlobalIdentifier()). |
| GUID getGUID() const { return getGUID(getGlobalIdentifier()); } |
| |
| /// @name Materialization |
| /// Materialization is used to construct functions only as they're needed. |
| /// This |
| /// is useful to reduce memory usage in LLVM or parsing work done by the |
| /// BitcodeReader to load the Module. |
| /// @{ |
| |
| /// If this function's Module is being lazily streamed in functions from disk |
| /// or some other source, this method can be used to check to see if the |
| /// function has been read in yet or not. |
| bool isMaterializable() const; |
| |
| /// Make sure this GlobalValue is fully read. |
| Error materialize(); |
| |
| /// @} |
| |
| /// Return true if the primary definition of this global value is outside of |
| /// the current translation unit. |
| bool isDeclaration() const; |
| |
| bool isDeclarationForLinker() const { |
| if (hasAvailableExternallyLinkage()) |
| return true; |
| |
| return isDeclaration(); |
| } |
| |
| /// Returns true if this global's definition will be the one chosen by the |
| /// linker. |
| /// |
| /// NB! Ideally this should not be used at the IR level at all. If you're |
| /// interested in optimization constraints implied by the linker's ability to |
| /// choose an implementation, prefer using \c hasExactDefinition. |
| bool isStrongDefinitionForLinker() const { |
| return !(isDeclarationForLinker() || isWeakForLinker()); |
| } |
| |
| // Returns true if the alignment of the value can be unilaterally |
| // increased. |
| bool canIncreaseAlignment() const; |
| |
| const GlobalObject *getBaseObject() const { |
| return const_cast<GlobalValue *>(this)->getBaseObject(); |
| } |
| GlobalObject *getBaseObject(); |
| |
| /// Returns whether this is a reference to an absolute symbol. |
| bool isAbsoluteSymbolRef() const; |
| |
| /// If this is an absolute symbol reference, returns the range of the symbol, |
| /// otherwise returns None. |
| Optional<ConstantRange> getAbsoluteSymbolRange() const; |
| |
| /// This method unlinks 'this' from the containing module, but does not delete |
| /// it. |
| virtual void removeFromParent() = 0; |
| |
| /// This method unlinks 'this' from the containing module and deletes it. |
| virtual void eraseFromParent() = 0; |
| |
| /// Get the module that this global value is contained inside of... |
| Module *getParent() { return Parent; } |
| const Module *getParent() const { return Parent; } |
| |
| // Methods for support type inquiry through isa, cast, and dyn_cast: |
| static bool classof(const Value *V) { |
| return V->getValueID() == Value::FunctionVal || |
| V->getValueID() == Value::GlobalVariableVal || |
| V->getValueID() == Value::GlobalAliasVal || |
| V->getValueID() == Value::GlobalIFuncVal; |
| } |
| }; |
| |
| } // end namespace llvm |
| |
| #endif // LLVM_IR_GLOBALVALUE_H |