1 //===-- llvm/GlobalObject.h - Class to represent global objects -*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This represents an independent object. That is, a function or a global 10 // variable, but not an alias. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_IR_GLOBALOBJECT_H 15 #define LLVM_IR_GLOBALOBJECT_H 16 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/IR/GlobalValue.h" 19 #include "llvm/IR/Value.h" 20 #include "llvm/Support/Alignment.h" 21 #include <string> 22 #include <utility> 23 24 namespace llvm { 25 26 class Comdat; 27 class MDNode; 28 class Metadata; 29 30 class GlobalObject : public GlobalValue { 31 public: 32 // VCallVisibility - values for visibility metadata attached to vtables. This 33 // describes the scope in which a virtual call could end up being dispatched 34 // through this vtable. 35 enum VCallVisibility { 36 // Type is potentially visible to external code. 37 VCallVisibilityPublic = 0, 38 // Type is only visible to code which will be in the current Module after 39 // LTO internalization. 40 VCallVisibilityLinkageUnit = 1, 41 // Type is only visible to code in the current Module. 42 VCallVisibilityTranslationUnit = 2, 43 }; 44 45 protected: 46 GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, 47 LinkageTypes Linkage, const Twine &Name, 48 unsigned AddressSpace = 0) 49 : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace), 50 ObjComdat(nullptr) { 51 setGlobalValueSubClassData(0); 52 } 53 54 Comdat *ObjComdat; 55 enum { 56 LastAlignmentBit = 4, 57 HasMetadataHashEntryBit, 58 HasSectionHashEntryBit, 59 60 GlobalObjectBits, 61 }; 62 static const unsigned GlobalObjectSubClassDataBits = 63 GlobalValueSubClassDataBits - GlobalObjectBits; 64 65 private: 66 static const unsigned AlignmentBits = LastAlignmentBit + 1; 67 static const unsigned AlignmentMask = (1 << AlignmentBits) - 1; 68 static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1; 69 70 public: 71 GlobalObject(const GlobalObject &) = delete; 72 73 /// FIXME: Remove this function once transition to Align is over. 74 unsigned getAlignment() const { 75 MaybeAlign Align = getAlign(); 76 return Align ? Align->value() : 0; 77 } 78 79 /// Returns the alignment of the given variable or function. 80 /// 81 /// Note that for functions this is the alignment of the code, not the 82 /// alignment of a function pointer. 83 MaybeAlign getAlign() const { 84 unsigned Data = getGlobalValueSubClassData(); 85 unsigned AlignmentData = Data & AlignmentMask; 86 return decodeMaybeAlign(AlignmentData); 87 } 88 89 void setAlignment(MaybeAlign Align); 90 91 unsigned getGlobalObjectSubClassData() const { 92 unsigned ValueData = getGlobalValueSubClassData(); 93 return ValueData >> GlobalObjectBits; 94 } 95 96 void setGlobalObjectSubClassData(unsigned Val) { 97 unsigned OldData = getGlobalValueSubClassData(); 98 setGlobalValueSubClassData((OldData & GlobalObjectMask) | 99 (Val << GlobalObjectBits)); 100 assert(getGlobalObjectSubClassData() == Val && "representation error"); 101 } 102 103 /// Check if this global has a custom object file section. 104 /// 105 /// This is more efficient than calling getSection() and checking for an empty 106 /// string. 107 bool hasSection() const { 108 return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit); 109 } 110 111 /// Get the custom section of this global if it has one. 112 /// 113 /// If this global does not have a custom section, this will be empty and the 114 /// default object file section (.text, .data, etc) will be used. 115 StringRef getSection() const { 116 return hasSection() ? getSectionImpl() : StringRef(); 117 } 118 119 /// Change the section for this global. 120 /// 121 /// Setting the section to the empty string tells LLVM to choose an 122 /// appropriate default object file section. 123 void setSection(StringRef S); 124 125 bool hasComdat() const { return getComdat() != nullptr; } 126 const Comdat *getComdat() const { return ObjComdat; } 127 Comdat *getComdat() { return ObjComdat; } 128 void setComdat(Comdat *C) { ObjComdat = C; } 129 130 /// Check if this has any metadata. 131 bool hasMetadata() const { return hasMetadataHashEntry(); } 132 133 /// Check if this has any metadata of the given kind. 134 bool hasMetadata(unsigned KindID) const { 135 return getMetadata(KindID) != nullptr; 136 } 137 bool hasMetadata(StringRef Kind) const { 138 return getMetadata(Kind) != nullptr; 139 } 140 141 /// Get the current metadata attachments for the given kind, if any. 142 /// 143 /// These functions require that the function have at most a single attachment 144 /// of the given kind, and return \c nullptr if such an attachment is missing. 145 /// @{ 146 MDNode *getMetadata(unsigned KindID) const; 147 MDNode *getMetadata(StringRef Kind) const; 148 /// @} 149 150 /// Appends all attachments with the given ID to \c MDs in insertion order. 151 /// If the global has no attachments with the given ID, or if ID is invalid, 152 /// leaves MDs unchanged. 153 /// @{ 154 void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const; 155 void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const; 156 /// @} 157 158 /// Set a particular kind of metadata attachment. 159 /// 160 /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or 161 /// replacing it if it already exists. 162 /// @{ 163 void setMetadata(unsigned KindID, MDNode *MD); 164 void setMetadata(StringRef Kind, MDNode *MD); 165 /// @} 166 167 /// Add a metadata attachment. 168 /// @{ 169 void addMetadata(unsigned KindID, MDNode &MD); 170 void addMetadata(StringRef Kind, MDNode &MD); 171 /// @} 172 173 /// Appends all attachments for the global to \c MDs, sorting by attachment 174 /// ID. Attachments with the same ID appear in insertion order. 175 void 176 getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const; 177 178 /// Erase all metadata attachments with the given kind. 179 /// 180 /// \returns true if any metadata was removed. 181 bool eraseMetadata(unsigned KindID); 182 183 /// Copy metadata from Src, adjusting offsets by Offset. 184 void copyMetadata(const GlobalObject *Src, unsigned Offset); 185 186 void addTypeMetadata(unsigned Offset, Metadata *TypeID); 187 void setVCallVisibilityMetadata(VCallVisibility Visibility); 188 VCallVisibility getVCallVisibility() const; 189 190 /// Returns true if the alignment of the value can be unilaterally 191 /// increased. 192 /// 193 /// Note that for functions this is the alignment of the code, not the 194 /// alignment of a function pointer. 195 bool canIncreaseAlignment() const; 196 197 protected: 198 void copyAttributesFrom(const GlobalObject *Src); 199 200 public: 201 // Methods for support type inquiry through isa, cast, and dyn_cast: 202 static bool classof(const Value *V) { 203 return V->getValueID() == Value::FunctionVal || 204 V->getValueID() == Value::GlobalVariableVal; 205 } 206 207 void clearMetadata(); 208 209 private: 210 void setGlobalObjectFlag(unsigned Bit, bool Val) { 211 unsigned Mask = 1 << Bit; 212 setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | 213 (Val ? Mask : 0u)); 214 } 215 216 bool hasMetadataHashEntry() const { 217 return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit); 218 } 219 void setHasMetadataHashEntry(bool HasEntry) { 220 setGlobalObjectFlag(HasMetadataHashEntryBit, HasEntry); 221 } 222 223 StringRef getSectionImpl() const; 224 }; 225 226 } // end namespace llvm 227 228 #endif // LLVM_IR_GLOBALOBJECT_H 229