/src/hermes/external/llvh/include/llvh/IR/GlobalObject.h
Line | Count | Source |
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 "llvh/ADT/StringRef.h" |
19 | | #include "llvh/IR/GlobalValue.h" |
20 | | #include "llvh/IR/Value.h" |
21 | | #include <string> |
22 | | #include <utility> |
23 | | |
24 | | namespace llvh { |
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) |
35 | | : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace), |
36 | 0 | ObjComdat(nullptr) { |
37 | 0 | setGlobalValueSubClassData(0); |
38 | 0 | } |
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 | | |
59 | 0 | unsigned getAlignment() const { |
60 | 0 | unsigned Data = getGlobalValueSubClassData(); |
61 | 0 | unsigned AlignmentData = Data & AlignmentMask; |
62 | 0 | return (1u << AlignmentData) >> 1; |
63 | 0 | } |
64 | | void setAlignment(unsigned Align); |
65 | | |
66 | 0 | unsigned getGlobalObjectSubClassData() const { |
67 | 0 | unsigned ValueData = getGlobalValueSubClassData(); |
68 | 0 | return ValueData >> GlobalObjectBits; |
69 | 0 | } |
70 | | |
71 | 0 | void setGlobalObjectSubClassData(unsigned Val) { |
72 | 0 | unsigned OldData = getGlobalValueSubClassData(); |
73 | 0 | setGlobalValueSubClassData((OldData & GlobalObjectMask) | |
74 | 0 | (Val << GlobalObjectBits)); |
75 | 0 | assert(getGlobalObjectSubClassData() == Val && "representation error"); |
76 | 0 | } |
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. |
82 | 0 | bool hasSection() const { |
83 | 0 | return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit); |
84 | 0 | } |
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. |
90 | 0 | StringRef getSection() const { |
91 | 0 | return hasSection() ? getSectionImpl() : StringRef(); |
92 | 0 | } |
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 | | |
100 | 0 | bool hasComdat() const { return getComdat() != nullptr; } |
101 | 0 | const Comdat *getComdat() const { return ObjComdat; } |
102 | 0 | Comdat *getComdat() { return ObjComdat; } |
103 | 0 | void setComdat(Comdat *C) { ObjComdat = C; } |
104 | | |
105 | | /// Check if this has any metadata. |
106 | 0 | bool hasMetadata() const { return hasMetadataHashEntry(); } |
107 | | |
108 | | /// Check if this has any metadata of the given kind. |
109 | 0 | bool hasMetadata(unsigned KindID) const { |
110 | 0 | return getMetadata(KindID) != nullptr; |
111 | 0 | } |
112 | 0 | bool hasMetadata(StringRef Kind) const { |
113 | 0 | return getMetadata(Kind) != nullptr; |
114 | 0 | } |
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: |
168 | 0 | static bool classof(const Value *V) { |
169 | 0 | return V->getValueID() == Value::FunctionVal || |
170 | 0 | V->getValueID() == Value::GlobalVariableVal; |
171 | 0 | } |
172 | | |
173 | | void clearMetadata(); |
174 | | |
175 | | private: |
176 | 0 | void setGlobalObjectFlag(unsigned Bit, bool Val) { |
177 | 0 | unsigned Mask = 1 << Bit; |
178 | 0 | setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | |
179 | 0 | (Val ? Mask : 0u)); |
180 | 0 | } |
181 | | |
182 | 0 | bool hasMetadataHashEntry() const { |
183 | 0 | return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit); |
184 | 0 | } |
185 | 0 | void setHasMetadataHashEntry(bool HasEntry) { |
186 | 0 | setGlobalObjectFlag(HasMetadataHashEntryBit, HasEntry); |
187 | 0 | } |
188 | | |
189 | | StringRef getSectionImpl() const; |
190 | | }; |
191 | | |
192 | | } // end namespace llvh |
193 | | |
194 | | #endif // LLVM_IR_GLOBALOBJECT_H |