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 |