/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/IR/GlobalObject.h
Line | Count | Source (jump to first uncovered line) |
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) |
34 | | : GlobalValue(Ty, VTy, Ops, NumOps, Linkage, Name, AddressSpace), |
35 | 2.79M | ObjComdat(nullptr) { |
36 | 2.79M | setGlobalValueSubClassData(0); |
37 | 2.79M | } |
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 | | |
58 | 13.9M | unsigned getAlignment() const { |
59 | 13.9M | unsigned Data = getGlobalValueSubClassData(); |
60 | 13.9M | unsigned AlignmentData = Data & AlignmentMask; |
61 | 13.9M | return (1u << AlignmentData) >> 1; |
62 | 13.9M | } |
63 | | void setAlignment(unsigned Align); |
64 | | |
65 | 33.5M | unsigned getGlobalObjectSubClassData() const { |
66 | 33.5M | unsigned ValueData = getGlobalValueSubClassData(); |
67 | 33.5M | return ValueData >> GlobalObjectBits; |
68 | 33.5M | } |
69 | | |
70 | 5.20M | void setGlobalObjectSubClassData(unsigned Val) { |
71 | 5.20M | unsigned OldData = getGlobalValueSubClassData(); |
72 | 5.20M | setGlobalValueSubClassData((OldData & GlobalObjectMask) | |
73 | 5.20M | (Val << GlobalObjectBits)); |
74 | 5.20M | assert(getGlobalObjectSubClassData() == Val && "representation error"); |
75 | 5.20M | } |
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. |
81 | 5.67M | bool hasSection() const { |
82 | 5.67M | return getGlobalValueSubClassData() & (1 << HasSectionHashEntryBit); |
83 | 5.67M | } |
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. |
89 | 1.38M | StringRef getSection() const { |
90 | 1.38M | return hasSection() ? getSectionImpl()61.0k : StringRef()1.32M ; |
91 | 1.38M | } |
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 | | |
99 | 425k | bool hasComdat() const { return getComdat() != nullptr; } |
100 | 12.1M | const Comdat *getComdat() const { return ObjComdat; } |
101 | 6.15M | Comdat *getComdat() { return ObjComdat; } |
102 | 420k | void setComdat(Comdat *C) { ObjComdat = C; } |
103 | | |
104 | | /// Check if this has any metadata. |
105 | 19.5M | bool hasMetadata() const { return hasMetadataHashEntry(); } |
106 | | |
107 | | /// Check if this has any metadata of the given kind. |
108 | 1.51M | bool hasMetadata(unsigned KindID) const { |
109 | 1.51M | return getMetadata(KindID) != nullptr; |
110 | 1.51M | } |
111 | 0 | bool hasMetadata(StringRef Kind) const { |
112 | 0 | return getMetadata(Kind) != nullptr; |
113 | 0 | } |
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: |
167 | 577k | static bool classof(const Value *V) { |
168 | 577k | return V->getValueID() == Value::FunctionVal || |
169 | 577k | V->getValueID() == Value::GlobalVariableVal538k ; |
170 | 577k | } |
171 | | |
172 | | void clearMetadata(); |
173 | | |
174 | | private: |
175 | 261k | void setGlobalObjectFlag(unsigned Bit, bool Val) { |
176 | 261k | unsigned Mask = 1 << Bit; |
177 | 261k | setGlobalValueSubClassData((~Mask & getGlobalValueSubClassData()) | |
178 | 261k | (Val ? Mask166k : 0u95.0k )); |
179 | 261k | } |
180 | | |
181 | 19.5M | bool hasMetadataHashEntry() const { |
182 | 19.5M | return getGlobalValueSubClassData() & (1 << HasMetadataHashEntryBit); |
183 | 19.5M | } |
184 | 224k | void setHasMetadataHashEntry(bool HasEntry) { |
185 | 224k | setGlobalObjectFlag(HasMetadataHashEntryBit, HasEntry); |
186 | 224k | } |
187 | | |
188 | | StringRef getSectionImpl() const; |
189 | | }; |
190 | | |
191 | | } // end namespace llvm |
192 | | |
193 | | #endif // LLVM_IR_GLOBALOBJECT_H |