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 <string> 21 #include <utility> 22 23 namespace llvm { 24 25 class Comdat; 26 class MDNode; 27 class Metadata; 28 29 class GlobalObject : public GlobalValue { 30 protected: 31 GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, 32 LinkageTypes Linkage, const Twine &Name, 33 unsigned AddressSpace = 0) GlobalValue(Ty,VTy,Ops,NumOps,Linkage,Name,AddressSpace)34 : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace), 35 ObjComdat(nullptr) { 36 setGlobalValueSubClassData(0); 37 } 38 39 Comdat *ObjComdat; 40 enum { 41 LastAlignmentBit = 4, 42 HasMetadataHashEntryBit, 43 HasSectionHashEntryBit, 44 45 GlobalObjectBits, 46 }; 47 static const unsigned GlobalObjectSubClassDataBits = 48 GlobalValueSubClassDataBits - GlobalObjectBits; 49 50 private: 51 static const unsigned AlignmentBits = LastAlignmentBit + 1; 52 static const unsigned AlignmentMask = (1 << AlignmentBits) - 1; 53 static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1; 54 55 public: 56 GlobalObject(const GlobalObject &) = delete; 57 getAlignment()58 unsigned getAlignment() const { 59 unsigned Data = getGlobalValueSubClassData(); 60 unsigned AlignmentData = Data & AlignmentMask; 61 return (1u << AlignmentData) >> 1; 62 } 63 void setAlignment(unsigned Align); 64 getGlobalObjectSubClassData()65 unsigned getGlobalObjectSubClassData() const { 66 unsigned ValueData = getGlobalValueSubClassData(); 67 return ValueData >> GlobalObjectBits; 68 } 69 setGlobalObjectSubClassData(unsigned Val)70 void setGlobalObjectSubClassData(unsigned Val) { 71 unsigned OldData = getGlobalValueSubClassData(); 72 setGlobalValueSubClassData((OldData & GlobalObjectMask) | 73 (Val << GlobalObjectBits)); 74 assert(getGlobalObjectSubClassData() == Val && "representation error"); 75 } 76 77 /// Check if this global has a custom object file section. 78 /// 79 /// This is more efficient than calling getSection() and checking for an empty 80 /// string. hasSection()81 bool hasSection() const { 82 return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit); 83 } 84 85 /// Get the custom section of this global if it has one. 86 /// 87 /// If this global does not have a custom section, this will be empty and the 88 /// default object file section (.text, .data, etc) will be used. getSection()89 StringRef getSection() const { 90 return hasSection() ? getSectionImpl() : StringRef(); 91 } 92 93 /// Change the section for this global. 94 /// 95 /// Setting the section to the empty string tells LLVM to choose an 96 /// appropriate default object file section. 97 void setSection(StringRef S); 98 hasComdat()99 bool hasComdat() const { return getComdat() != nullptr; } getComdat()100 const Comdat *getComdat() const { return ObjComdat; } getComdat()101 Comdat *getComdat() { return ObjComdat; } setComdat(Comdat * C)102 void setComdat(Comdat *C) { ObjComdat = C; } 103 104 /// Check if this has any metadata. hasMetadata()105 bool hasMetadata() const { return hasMetadataHashEntry(); } 106 107 /// Check if this has any metadata of the given kind. hasMetadata(unsigned KindID)108 bool hasMetadata(unsigned KindID) const { 109 return getMetadata(KindID) != nullptr; 110 } hasMetadata(StringRef Kind)111 bool hasMetadata(StringRef Kind) const { 112 return getMetadata(Kind) != nullptr; 113 } 114 115 /// Get the current metadata attachments for the given kind, if any. 116 /// 117 /// These functions require that the function have at most a single attachment 118 /// of the given kind, and return \c nullptr if such an attachment is missing. 119 /// @{ 120 MDNode *getMetadata(unsigned KindID) const; 121 MDNode *getMetadata(StringRef Kind) const; 122 /// @} 123 124 /// Appends all attachments with the given ID to \c MDs in insertion order. 125 /// If the global has no attachments with the given ID, or if ID is invalid, 126 /// leaves MDs unchanged. 127 /// @{ 128 void getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const; 129 void getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const; 130 /// @} 131 132 /// Set a particular kind of metadata attachment. 133 /// 134 /// Sets the given attachment to \c MD, erasing it if \c MD is \c nullptr or 135 /// replacing it if it already exists. 136 /// @{ 137 void setMetadata(unsigned KindID, MDNode *MD); 138 void setMetadata(StringRef Kind, MDNode *MD); 139 /// @} 140 141 /// Add a metadata attachment. 142 /// @{ 143 void addMetadata(unsigned KindID, MDNode &MD); 144 void addMetadata(StringRef Kind, MDNode &MD); 145 /// @} 146 147 /// Appends all attachments for the global to \c MDs, sorting by attachment 148 /// ID. Attachments with the same ID appear in insertion order. 149 void 150 getAllMetadata(SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs) const; 151 152 /// Erase all metadata attachments with the given kind. 153 /// 154 /// \returns true if any metadata was removed. 155 bool eraseMetadata(unsigned KindID); 156 157 /// Copy metadata from Src, adjusting offsets by Offset. 158 void copyMetadata(const GlobalObject *Src, unsigned Offset); 159 160 void addTypeMetadata(unsigned Offset, Metadata *TypeID); 161 162 protected: 163 void copyAttributesFrom(const GlobalObject *Src); 164 165 public: 166 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const Value * V)167 static bool classof(const Value *V) { 168 return V->getValueID() == Value::FunctionVal || 169 V->getValueID() == Value::GlobalVariableVal; 170 } 171 172 void clearMetadata(); 173 174 private: setGlobalObjectFlag(unsigned Bit,bool Val)175 void setGlobalObjectFlag(unsigned Bit, bool Val) { 176 unsigned Mask = 1 << Bit; 177 setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | 178 (Val ? Mask : 0u)); 179 } 180 hasMetadataHashEntry()181 bool hasMetadataHashEntry() const { 182 return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit); 183 } setHasMetadataHashEntry(bool HasEntry)184 void setHasMetadataHashEntry(bool HasEntry) { 185 setGlobalObjectFlag(HasMetadataHashEntryBit, HasEntry); 186 } 187 188 StringRef getSectionImpl() const; 189 }; 190 191 } // end namespace llvm 192 193 #endif // LLVM_IR_GLOBALOBJECT_H 194