OLD | NEW |
---|---|
1 //===- subzero/src/IceGlobalInits.h - Global initializers -------*- C++ -*-===// | 1 //===- subzero/src/IceGlobalInits.h - Global initializers -------*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file declares the representation of global addresses and | 10 // This file declares the representation of global addresses and |
11 // initializers in Subzero. Global initializers are represented as a | 11 // initializers in Subzero. Global initializers are represented as a |
12 // sequence of simple initializers. | 12 // sequence of simple initializers. |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #ifndef SUBZERO_SRC_ICEGLOBALINITS_H | 16 #ifndef SUBZERO_SRC_ICEGLOBALINITS_H |
17 #define SUBZERO_SRC_ICEGLOBALINITS_H | 17 #define SUBZERO_SRC_ICEGLOBALINITS_H |
18 | 18 |
19 #include "IceDefs.h" | 19 #include "IceDefs.h" |
20 #include "IceTypes.h" | |
21 | |
22 #include "llvm/IR/CallingConv.h" | |
23 #include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes | |
20 | 24 |
21 namespace llvm { | 25 namespace llvm { |
22 // TODO(kschimpf): Remove this dependency on LLVM IR. | 26 // TODO(kschimpf): Remove this dependency on LLVM IR. |
23 class Value; | 27 class Value; |
24 } | 28 } |
25 | 29 |
26 namespace Ice { | 30 namespace Ice { |
27 | 31 |
28 /// Models a global address, and its initializers. | 32 /// Base class for global and function addresses. |
29 class GlobalAddress { | 33 class GlobalAddress { |
30 GlobalAddress(const GlobalAddress &) = delete; | 34 GlobalAddress(const GlobalAddress &) = delete; |
31 GlobalAddress &operator=(const GlobalAddress &) = delete; | 35 GlobalAddress &operator=(const GlobalAddress &) = delete; |
32 | 36 |
33 public: | 37 public: |
38 /// Discriminator for LLVM-style RTTI. | |
39 enum GlobalAddressKind { FunctionKind, GlobalVariableKind }; | |
40 GlobalAddressKind getKind() const { return Kind; } | |
41 const IceString &getName() const { return Name; } | |
42 void setName(const IceString &NewName) { Name = NewName; } | |
43 bool hasName() const { return !Name.empty(); } | |
44 IceString mangleName(GlobalContext *Ctx) const; | |
45 | |
46 virtual ~GlobalAddress() {} | |
47 | |
48 /// Returns true if address is external. | |
49 virtual bool getIsExternal() const = 0; | |
50 | |
51 /// Returns true if initialized (or defined if function). | |
52 virtual bool hasInitializer() const = 0; | |
53 | |
54 /// Prints out type of the global address. | |
55 virtual void dumpType(Ostream &Stream) const = 0; | |
56 | |
57 /// Prints out the declaration of the global address. | |
58 virtual void dump(Ostream &Stream) const = 0; | |
59 | |
60 protected: | |
61 GlobalAddress(GlobalAddressKind Kind) : Kind(Kind) {} | |
62 | |
63 const GlobalAddressKind Kind; | |
64 // The name for the global address. | |
65 IceString Name; | |
66 }; | |
67 | |
68 // Models a function address. Also defines the type signature of the function, | |
69 // it's calling conventions, and its linkage. | |
Jim Stichnoth
2014/10/10 13:15:00
its
Karl
2014/10/10 20:17:30
Done.
| |
70 class Function : public GlobalAddress { | |
Jim Stichnoth
2014/10/10 13:15:00
Could we use a different name than "Function" for
Karl
2014/10/10 20:17:30
Changing as follows:
GlobalAddress -> GlobalDecla
| |
71 Function(const Function &) = delete; | |
72 Function &operator=(const Function &) = delete; | |
73 friend class GlobalContext; | |
74 | |
75 public: | |
76 static Function *create(GlobalContext *Ctx, const FuncSigType &Signature, | |
77 llvm::CallingConv::ID CallingConv, | |
78 llvm::GlobalValue::LinkageTypes Linkage, | |
79 bool IsProto); | |
80 ~Function() final {} | |
81 const FuncSigType &getSignature() const { return Signature; } | |
82 llvm::CallingConv::ID getCallingConv() const { return CallingConv; } | |
83 llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; } | |
84 // isProto implies that there isn't a (local) definition for the function. | |
85 bool isProto() const { return IsProto; } | |
86 static bool classof(const GlobalAddress *Addr) { | |
87 return Addr->getKind() == FunctionKind; | |
88 } | |
89 void dumpType(Ostream &Stream) const final; | |
90 void dump(Ostream &Stream) const final; | |
91 bool getIsExternal() const final { | |
92 return Linkage == llvm::GlobalValue::ExternalLinkage; | |
93 } | |
94 bool hasInitializer() const final { return !IsProto; } | |
95 | |
96 private: | |
97 const Ice::FuncSigType Signature; | |
98 llvm::CallingConv::ID CallingConv; | |
99 llvm::GlobalValue::LinkageTypes Linkage; | |
100 bool IsProto; | |
101 | |
102 Function(const FuncSigType &Signature, llvm::CallingConv::ID CallingConv, | |
103 llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) | |
104 : GlobalAddress(FunctionKind), Signature(Signature), | |
105 CallingConv(CallingConv), Linkage(Linkage), IsProto(IsProto) {} | |
106 }; | |
107 | |
108 /// Models a global address, and its initializers. | |
jvoung (off chromium)
2014/10/10 01:47:28
nit: How about "global variable address" otherwise
Karl
2014/10/10 20:17:30
See renaming above.
| |
109 class GlobalVariable : public GlobalAddress { | |
110 GlobalVariable(const GlobalVariable &) = delete; | |
111 GlobalVariable &operator=(const GlobalVariable &) = delete; | |
112 friend class GlobalContext; | |
113 // TODO(kschimpf) Factor out allocation of initializers into global context, | |
114 // so that memory allocation/collection can be optimized. | |
115 public: | |
34 /// Base class for a global variable initializer. | 116 /// Base class for a global variable initializer. |
35 class Initializer { | 117 class Initializer { |
36 Initializer(const Initializer &) = delete; | 118 Initializer(const Initializer &) = delete; |
37 Initializer &operator=(const Initializer &) = delete; | 119 Initializer &operator=(const Initializer &) = delete; |
38 | 120 |
39 public: | 121 public: |
40 /// Discriminator for LLVM-style RTTI. | 122 /// Discriminator for LLVM-style RTTI. |
41 enum InitializerKind { | 123 enum InitializerKind { |
42 DataInitializerKind, | 124 DataInitializerKind, |
43 ZeroInitializerKind, | 125 ZeroInitializerKind, |
(...skipping 30 matching lines...) Expand all Loading... | |
74 ++i; | 156 ++i; |
75 } | 157 } |
76 } | 158 } |
77 DataInitializer(const char *Str, size_t StrLen) | 159 DataInitializer(const char *Str, size_t StrLen) |
78 : Initializer(DataInitializerKind), Contents(StrLen) { | 160 : Initializer(DataInitializerKind), Contents(StrLen) { |
79 for (size_t i = 0; i < StrLen; ++i) | 161 for (size_t i = 0; i < StrLen; ++i) |
80 Contents[i] = static_cast<uint8_t>(Str[i]); | 162 Contents[i] = static_cast<uint8_t>(Str[i]); |
81 } | 163 } |
82 ~DataInitializer() override {} | 164 ~DataInitializer() override {} |
83 const DataVecType &getContents() const { return Contents; } | 165 const DataVecType &getContents() const { return Contents; } |
84 SizeT getNumBytes() const override { return Contents.size(); } | 166 SizeT getNumBytes() const final { return Contents.size(); } |
85 void dump(Ostream &Stream) const override; | 167 void dump(Ostream &Stream) const final; |
86 static bool classof(const Initializer *D) { | 168 static bool classof(const Initializer *D) { |
87 return D->getKind() == DataInitializerKind; | 169 return D->getKind() == DataInitializerKind; |
88 } | 170 } |
89 | 171 |
90 private: | 172 private: |
91 // The byte contents of the data initializer. | 173 // The byte contents of the data initializer. |
92 DataVecType Contents; | 174 DataVecType Contents; |
93 }; | 175 }; |
94 | 176 |
95 /// Defines a sequence of bytes initialized to zero. | 177 /// Defines a sequence of bytes initialized to zero. |
96 class ZeroInitializer : public Initializer { | 178 class ZeroInitializer : public Initializer { |
97 ZeroInitializer(const ZeroInitializer &) = delete; | 179 ZeroInitializer(const ZeroInitializer &) = delete; |
98 ZeroInitializer &operator=(const ZeroInitializer &) = delete; | 180 ZeroInitializer &operator=(const ZeroInitializer &) = delete; |
99 | 181 |
100 public: | 182 public: |
101 explicit ZeroInitializer(SizeT Size) | 183 explicit ZeroInitializer(SizeT Size) |
102 : Initializer(ZeroInitializerKind), Size(Size) {} | 184 : Initializer(ZeroInitializerKind), Size(Size) {} |
103 ~ZeroInitializer() override {} | 185 ~ZeroInitializer() override {} |
104 SizeT getNumBytes() const override { return Size; } | 186 SizeT getNumBytes() const final { return Size; } |
105 void dump(Ostream &Stream) const override; | 187 void dump(Ostream &Stream) const final; |
106 static bool classof(const Initializer *Z) { | 188 static bool classof(const Initializer *Z) { |
107 return Z->getKind() == ZeroInitializerKind; | 189 return Z->getKind() == ZeroInitializerKind; |
108 } | 190 } |
109 | 191 |
110 private: | 192 private: |
111 // The number of bytes to be zero initialized. | 193 // The number of bytes to be zero initialized. |
112 SizeT Size; | 194 SizeT Size; |
113 }; | 195 }; |
114 | 196 |
115 /// Defines the kind of relocation addresses allowed. | |
116 enum RelocationKind { FunctionRelocation, GlobalAddressRelocation }; | |
117 | |
118 /// Defines a relocation address (i.e. reference to a function | |
119 /// or global variable address). | |
120 class RelocationAddress { | |
121 RelocationAddress &operator=(const RelocationAddress &) = delete; | |
122 | |
123 public: | |
124 explicit RelocationAddress(const RelocationAddress &Addr) | |
125 : Kind(Addr.Kind) { | |
126 switch (Kind) { | |
127 case FunctionRelocation: | |
128 Address.Function = Addr.Address.Function; | |
129 break; | |
130 case GlobalAddressRelocation: | |
131 Address.GlobalAddr = Addr.Address.GlobalAddr; | |
132 } | |
133 } | |
134 explicit RelocationAddress(llvm::Value *Function) | |
135 : Kind(FunctionRelocation) { | |
136 Address.Function = Function; | |
137 } | |
138 explicit RelocationAddress(GlobalAddress *GlobalAddr) | |
139 : Kind(GlobalAddressRelocation) { | |
140 Address.GlobalAddr = GlobalAddr; | |
141 } | |
142 RelocationKind getKind() const { return Kind; } | |
143 llvm::Value *getFunction() const { | |
144 assert(Kind == FunctionRelocation); | |
145 return Address.Function; | |
146 } | |
147 GlobalAddress *getGlobalAddr() const { | |
148 assert(Kind == GlobalAddressRelocation); | |
149 return Address.GlobalAddr; | |
150 } | |
151 private: | |
152 const RelocationKind Kind; | |
153 union { | |
154 // TODO(kschimpf) Integrate Functions into ICE model. | |
155 llvm::Value *Function; | |
156 GlobalAddress *GlobalAddr; | |
157 } Address; | |
158 }; | |
159 | |
160 // Relocation address offsets must be 32 bit values. | 197 // Relocation address offsets must be 32 bit values. |
161 typedef int32_t RelocOffsetType; | 198 typedef int32_t RelocOffsetType; |
162 static const SizeT RelocAddrSize = 4; | 199 static const SizeT RelocAddrSize = 4; |
163 | 200 |
164 /// Defines the relocation value of another address. | 201 /// Defines the relocation value of another address. |
165 class RelocInitializer : public Initializer { | 202 class RelocInitializer : public Initializer { |
166 RelocInitializer(const RelocInitializer &) = delete; | 203 RelocInitializer(const RelocInitializer &) = delete; |
167 RelocInitializer &operator=(const RelocInitializer &) = delete; | 204 RelocInitializer &operator=(const RelocInitializer &) = delete; |
168 | 205 |
169 public: | 206 public: |
170 RelocInitializer(const RelocationAddress &Address, RelocOffsetType Offset) | 207 RelocInitializer(const GlobalAddress *Address, RelocOffsetType Offset) |
171 : Initializer(RelocInitializerKind), Address(Address), Offset(Offset) {} | 208 : Initializer(RelocInitializerKind), Address(Address), Offset(Offset) {} |
172 ~RelocInitializer() override {} | 209 ~RelocInitializer() override {} |
173 RelocOffsetType getOffset() const { return Offset; } | 210 RelocOffsetType getOffset() const { return Offset; } |
174 IceString getName() const; | 211 const GlobalAddress *getAddress() const { return Address; } |
175 SizeT getNumBytes() const override { return RelocAddrSize; } | 212 SizeT getNumBytes() const final { return RelocAddrSize; } |
176 void dump(Ostream &Stream) const override; | 213 void dump(Ostream &Stream) const final; |
177 virtual void dumpType(Ostream &Stream) const; | 214 void dumpType(Ostream &Stream) const final; |
178 static bool classof(const Initializer *R) { | 215 static bool classof(const Initializer *R) { |
179 return R->getKind() == RelocInitializerKind; | 216 return R->getKind() == RelocInitializerKind; |
180 } | 217 } |
181 | 218 |
182 private: | 219 private: |
183 // The global address used in the relocation. | 220 // The global address used in the relocation. |
184 const RelocationAddress Address; | 221 const GlobalAddress *Address; |
185 // The offset to add to the relocation. | 222 // The offset to add to the relocation. |
186 const RelocOffsetType Offset; | 223 const RelocOffsetType Offset; |
187 }; | 224 }; |
188 | 225 |
189 /// Models the list of initializers. | 226 /// Models the list of initializers. |
190 typedef std::vector<Initializer *> InitializerListType; | 227 typedef std::vector<Initializer *> InitializerListType; |
191 | 228 |
192 GlobalAddress() : Alignment(0), IsConstant(false), IsInternal(true) {} | 229 static GlobalVariable *create(GlobalContext *Ctx); |
193 ~GlobalAddress(); | 230 ~GlobalVariable() final; |
194 | 231 |
195 const InitializerListType &getInitializers() const { return Initializers; } | 232 const InitializerListType &getInitializers() const { return Initializers; } |
196 bool hasName() const { return !Name.empty(); } | |
197 const IceString &getName() const { return Name; } | |
198 void setName(const IceString &NewName) { Name = NewName; } | |
199 bool getIsConstant() const { return IsConstant; } | 233 bool getIsConstant() const { return IsConstant; } |
200 void setIsConstant(bool NewValue) { IsConstant = NewValue; } | 234 void setIsConstant(bool NewValue) { IsConstant = NewValue; } |
201 uint32_t getAlignment() const { return Alignment; } | 235 uint32_t getAlignment() const { return Alignment; } |
202 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } | 236 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } |
203 bool getIsInternal() const { return IsInternal; } | 237 bool getIsInternal() const { return IsInternal; } |
204 void setIsInternal(bool NewValue) { IsInternal = NewValue; } | 238 void setIsInternal(bool NewValue) { IsInternal = NewValue; } |
239 bool getIsExternal() const final { return !getIsInternal(); } | |
240 bool hasInitializer() const final { | |
241 return !(Initializers.size() == 1 && | |
242 llvm::isa<ZeroInitializer>(Initializers[0])); | |
243 } | |
205 | 244 |
206 /// Returns the number of bytes for the initializer of the global | 245 /// Returns the number of bytes for the initializer of the global |
207 /// address. | 246 /// address. |
208 SizeT getNumBytes() const { | 247 SizeT getNumBytes() const { |
209 SizeT Count = 0; | 248 SizeT Count = 0; |
210 for (Initializer *Init : Initializers) { | 249 for (Initializer *Init : Initializers) { |
211 Count += Init->getNumBytes(); | 250 Count += Init->getNumBytes(); |
212 } | 251 } |
213 return Count; | 252 return Count; |
214 } | 253 } |
215 | 254 |
216 /// Adds Initializer to the list of initializers. Takes ownership of | 255 /// Adds Initializer to the list of initializers. Takes ownership of |
217 /// the initializer. | 256 /// the initializer. |
218 void addInitializer(Initializer *Initializer) { | 257 void addInitializer(Initializer *Initializer) { |
219 Initializers.push_back(Initializer); | 258 Initializers.push_back(Initializer); |
220 } | 259 } |
221 | 260 |
222 /// Prints out type for initializer associated with the global address | 261 /// Prints out type for initializer associated with the global address |
223 /// to Stream. | 262 /// to Stream. |
224 void dumpType(Ostream &Stream) const; | 263 void dumpType(Ostream &Stream) const final; |
225 | 264 |
226 /// Prints out the definition of the global address (including | 265 /// Prints out the definition of the global address (including |
227 /// initialization). | 266 /// initialization). |
228 void dump(Ostream &Stream) const; | 267 void dump(Ostream &Stream) const final; |
268 | |
269 static bool classof(const GlobalAddress *Addr) { | |
270 return Addr->getKind() == GlobalVariableKind; | |
271 } | |
229 | 272 |
230 private: | 273 private: |
231 // list of initializers associated with the global address. | 274 // list of initializers associated with the global address. |
232 InitializerListType Initializers; | 275 InitializerListType Initializers; |
233 // The name for the global. | |
234 IceString Name; | |
235 // The alignment of the initializer. | 276 // The alignment of the initializer. |
236 uint32_t Alignment; | 277 uint32_t Alignment; |
237 // True if a constant initializer. | 278 // True if a constant initializer. |
238 bool IsConstant; | 279 bool IsConstant; |
239 // True if the address is internal. | 280 // True if the address is internal. |
240 bool IsInternal; | 281 bool IsInternal; |
282 | |
283 GlobalVariable() | |
284 : GlobalAddress(GlobalVariableKind), Alignment(0), IsConstant(false), | |
285 IsInternal(true) {} | |
241 }; | 286 }; |
242 | 287 |
243 template <class StreamType> | 288 template <class StreamType> |
244 inline StreamType &operator<<(StreamType &Stream, | 289 inline StreamType &operator<<(StreamType &Stream, |
245 const GlobalAddress::Initializer &Init) { | 290 const GlobalVariable::Initializer &Init) { |
246 Init.dump(Stream); | 291 Init.dump(Stream); |
247 return Stream; | 292 return Stream; |
248 } | 293 } |
249 | 294 |
250 template <class StreamType> | 295 template <class StreamType> |
251 inline StreamType &operator<<(StreamType &Stream, const GlobalAddress &Addr) { | 296 inline StreamType &operator<<(StreamType &Stream, const GlobalVariable &Addr) { |
252 Addr.dump(Stream); | 297 Addr.dump(Stream); |
253 return Stream; | 298 return Stream; |
254 } | 299 } |
255 | 300 |
256 } // end of namespace Ice | 301 } // end of namespace Ice |
257 | 302 |
258 #endif // SUBZERO_SRC_ICEGLOBALINITS_H | 303 #endif // SUBZERO_SRC_ICEGLOBALINITS_H |
OLD | NEW |