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