Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 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 | |||
| 22 | namespace llvm { | ||
| 23 | |||
| 24 | class Comdat; | ||
| 25 | class Metadata; | ||
| 26 | |||
| 27 | class GlobalObject : public GlobalValue { | ||
| 28 | public: | ||
| 29 |   // VCallVisibility - values for visibility metadata attached to vtables. This | ||
| 30 |   // describes the scope in which a virtual call could end up being dispatched | ||
| 31 |   // through this vtable. | ||
| 32 | enum VCallVisibility { | ||
| 33 |     // Type is potentially visible to external code. | ||
| 34 | VCallVisibilityPublic = 0, | ||
| 35 |     // Type is only visible to code which will be in the current Module after | ||
| 36 |     // LTO internalization. | ||
| 37 | VCallVisibilityLinkageUnit = 1, | ||
| 38 |     // Type is only visible to code in the current Module. | ||
| 39 | VCallVisibilityTranslationUnit = 2, | ||
| 40 | }; | ||
| 41 | |||
| 42 | protected: | ||
| 43 | GlobalObject(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps, | ||
| 44 | LinkageTypes Linkage, const Twine &Name, | ||
| 45 | unsigned AddressSpace = 0) | ||
| 46 | : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace) { | ||
| 47 | setGlobalValueSubClassData(0); | ||
| 48 |   } | ||
| 49 | ~GlobalObject(); | ||
| 50 | |||
| 51 | Comdat *ObjComdat = nullptr; | ||
| 52 | enum { | ||
| 53 | LastAlignmentBit = 5, | ||
| 54 | HasSectionHashEntryBit, | ||
| 55 | |||
| 56 | GlobalObjectBits, | ||
| 57 | }; | ||
| 58 | static const unsigned GlobalObjectSubClassDataBits = | ||
| 59 | GlobalValueSubClassDataBits - GlobalObjectBits; | ||
| 60 | |||
| 61 | private: | ||
| 62 | static const unsigned AlignmentBits = LastAlignmentBit + 1; | ||
| 63 | static const unsigned AlignmentMask = (1 << AlignmentBits) - 1; | ||
| 64 | static const unsigned GlobalObjectMask = (1 << GlobalObjectBits) - 1; | ||
| 65 | |||
| 66 | public: | ||
| 67 | GlobalObject(const GlobalObject &) = delete; | ||
| 68 | |||
| 69 |   /// FIXME: Remove this function once transition to Align is over. | ||
| 70 | uint64_t getAlignment() const { | ||
| 71 | MaybeAlign Align = getAlign(); | ||
| 72 | return Align ? Align->value() : 0; | ||
| 73 |   } | ||
| 74 | |||
| 75 |   /// Returns the alignment of the given variable or function. | ||
| 76 |   /// | ||
| 77 |   /// Note that for functions this is the alignment of the code, not the | ||
| 78 |   /// alignment of a function pointer. | ||
| 79 | MaybeAlign getAlign() const { | ||
| 80 | unsigned Data = getGlobalValueSubClassData(); | ||
| 81 | unsigned AlignmentData = Data & AlignmentMask; | ||
| 82 | return decodeMaybeAlign(AlignmentData); | ||
| 83 |   } | ||
| 84 | |||
| 85 | void setAlignment(MaybeAlign Align); | ||
| 86 | |||
| 87 | unsigned getGlobalObjectSubClassData() const { | ||
| 88 | unsigned ValueData = getGlobalValueSubClassData(); | ||
| 89 | return ValueData >> GlobalObjectBits; | ||
| 90 |   } | ||
| 91 | |||
| 92 | void setGlobalObjectSubClassData(unsigned Val) { | ||
| 93 | unsigned OldData = getGlobalValueSubClassData(); | ||
| 94 | setGlobalValueSubClassData((OldData & GlobalObjectMask) | | ||
| 95 | (Val << GlobalObjectBits)); | ||
| 96 | assert(getGlobalObjectSubClassData() == Val && "representation error"); | ||
| 97 |   } | ||
| 98 | |||
| 99 |   /// Check if this global has a custom object file section. | ||
| 100 |   /// | ||
| 101 |   /// This is more efficient than calling getSection() and checking for an empty | ||
| 102 |   /// string. | ||
| 103 | bool hasSection() const { | ||
| 104 | return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit); | ||
| 105 |   } | ||
| 106 | |||
| 107 |   /// Get the custom section of this global if it has one. | ||
| 108 |   /// | ||
| 109 |   /// If this global does not have a custom section, this will be empty and the | ||
| 110 |   /// default object file section (.text, .data, etc) will be used. | ||
| 111 | StringRef getSection() const { | ||
| 112 | return hasSection() ? getSectionImpl() : StringRef(); | ||
| 113 |   } | ||
| 114 | |||
| 115 |   /// Change the section for this global. | ||
| 116 |   /// | ||
| 117 |   /// Setting the section to the empty string tells LLVM to choose an | ||
| 118 |   /// appropriate default object file section. | ||
| 119 | void setSection(StringRef S); | ||
| 120 | |||
| 121 | bool hasComdat() const { return getComdat() != nullptr; } | ||
| 122 | const Comdat *getComdat() const { return ObjComdat; } | ||
| 123 | Comdat *getComdat() { return ObjComdat; } | ||
| 124 | void setComdat(Comdat *C); | ||
| 125 | |||
| 126 | using Value::addMetadata; | ||
| 127 | using Value::clearMetadata; | ||
| 128 | using Value::eraseMetadata; | ||
| 129 | using Value::getAllMetadata; | ||
| 130 | using Value::getMetadata; | ||
| 131 | using Value::hasMetadata; | ||
| 132 | using Value::setMetadata; | ||
| 133 | |||
| 134 |   /// Copy metadata from Src, adjusting offsets by Offset. | ||
| 135 | void copyMetadata(const GlobalObject *Src, unsigned Offset); | ||
| 136 | |||
| 137 | void addTypeMetadata(unsigned Offset, Metadata *TypeID); | ||
| 138 | void setVCallVisibilityMetadata(VCallVisibility Visibility); | ||
| 139 | VCallVisibility getVCallVisibility() const; | ||
| 140 | |||
| 141 |   /// Returns true if the alignment of the value can be unilaterally | ||
| 142 |   /// increased. | ||
| 143 |   /// | ||
| 144 |   /// Note that for functions this is the alignment of the code, not the | ||
| 145 |   /// alignment of a function pointer. | ||
| 146 | bool canIncreaseAlignment() const; | ||
| 147 | |||
| 148 | protected: | ||
| 149 | void copyAttributesFrom(const GlobalObject *Src); | ||
| 150 | |||
| 151 | public: | ||
| 152 |   // Methods for support type inquiry through isa, cast, and dyn_cast: | ||
| 153 | static bool classof(const Value *V) { | ||
| 154 | return V->getValueID() == Value::FunctionVal || | ||
| 155 | V->getValueID() == Value::GlobalVariableVal || | ||
| 156 | V->getValueID() == Value::GlobalIFuncVal; | ||
| 157 |   } | ||
| 158 | |||
| 159 | private: | ||
| 160 | void setGlobalObjectFlag(unsigned Bit, bool Val) { | ||
| 161 | unsigned Mask = 1 << Bit; | ||
| 162 | setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | | ||
| 163 | (Val ? Mask : 0u)); | ||
| 164 |   } | ||
| 165 | |||
| 166 | StringRef getSectionImpl() const; | ||
| 167 | }; | ||
| 168 | |||
| 169 | } // end namespace llvm | ||
| 170 | |||
| 171 | #endif // LLVM_IR_GLOBALOBJECT_H |