OLD | NEW |
---|---|
1 //===- subzero/src/IceGlobalInits.h - Global initializers -------*- C++ -*-===// | 1 //===- subzero/src/IceGlobalInits.h - Global declarations -------*- 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 function declarations, |
11 // initializers in Subzero. Global initializers are represented as a | 11 // global variable declarations, and the corresponding variable |
12 // sequence of simple initializers. | 12 // initializers in Subzero. Global variable initializers are |
13 // represented as a sequence of simple initializers. | |
13 // | 14 // |
14 //===----------------------------------------------------------------------===// | 15 //===----------------------------------------------------------------------===// |
15 | 16 |
16 #ifndef SUBZERO_SRC_ICEGLOBALINITS_H | 17 #ifndef SUBZERO_SRC_ICEGLOBALINITS_H |
17 #define SUBZERO_SRC_ICEGLOBALINITS_H | 18 #define SUBZERO_SRC_ICEGLOBALINITS_H |
18 | 19 |
19 #include "IceDefs.h" | 20 #include "IceDefs.h" |
21 #include "IceTypes.h" | |
20 | 22 |
21 namespace llvm { | 23 #include "llvm/IR/CallingConv.h" |
Jim Stichnoth
2014/10/13 19:14:22
put these includes first
Karl
2014/10/13 20:48:03
Done.
| |
22 // TODO(kschimpf): Remove this dependency on LLVM IR. | 24 #include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes |
23 class Value; | 25 |
24 } | 26 // TODO(kschimpf): Remove ourselves from using LLVM representation for calling |
27 // conventions and linkage types. | |
25 | 28 |
26 namespace Ice { | 29 namespace Ice { |
27 | 30 |
28 /// Models a global address, and its initializers. | 31 /// Base class for global variable and function declarations. |
29 class GlobalAddress { | 32 class GlobalDeclaration { |
30 GlobalAddress(const GlobalAddress &) = delete; | 33 GlobalDeclaration(const GlobalDeclaration &) = delete; |
31 GlobalAddress &operator=(const GlobalAddress &) = delete; | 34 GlobalDeclaration &operator=(const GlobalDeclaration &) = delete; |
32 | 35 |
33 public: | 36 public: |
37 /// Discriminator for LLVM-style RTTI. | |
38 enum GlobalDeclarationKind { | |
39 FunctionDeclarationKind, | |
40 VariableDeclarationKind | |
41 }; | |
42 GlobalDeclarationKind getKind() const { return Kind; } | |
43 const IceString &getName() const { return Name; } | |
44 void setName(const IceString &NewName) { Name = NewName; } | |
45 bool hasName() const { return !Name.empty(); } | |
46 virtual ~GlobalDeclaration() {} | |
47 | |
48 /// Returns true if the declaration is external. | |
49 virtual bool getIsExternal() const = 0; | |
50 | |
51 /// Returns true if initialized (or defined if function declaration). | |
52 // virtual bool hasInitializer() const = 0; | |
Jim Stichnoth
2014/10/13 19:14:22
Not sure why this method is commented out here and
Karl
2014/10/13 20:48:03
Initialization (as pointed out by Jan) is a Variab
| |
53 | |
54 /// Prints out type of the global declaration. | |
55 virtual void dumpType(Ostream &Stream) const = 0; | |
56 | |
57 /// Prints out the global declaration. | |
58 virtual void dump(Ostream &Stream) const = 0; | |
59 | |
60 // Mangles name for cross tests, unless external and not defined locally | |
61 // (so that relocations accross llvm2ice and pnacl-llc will work). | |
62 virtual IceString mangleName(GlobalContext *Ctx) const = 0; | |
63 | |
64 protected: | |
65 GlobalDeclaration(GlobalDeclarationKind Kind) : Kind(Kind) {} | |
66 | |
67 const GlobalDeclarationKind Kind; | |
68 IceString Name; | |
69 }; | |
70 | |
71 // Models a function declaration. This includes the type signature of | |
72 // the function, its calling conventions, and its linkage. | |
73 class FunctionDeclaration : public GlobalDeclaration { | |
74 FunctionDeclaration(const FunctionDeclaration &) = delete; | |
75 FunctionDeclaration &operator=(const FunctionDeclaration &) = delete; | |
76 friend class GlobalContext; | |
77 | |
78 public: | |
79 static FunctionDeclaration *create(GlobalContext *Ctx, | |
80 const FuncSigType &Signature, | |
81 llvm::CallingConv::ID CallingConv, | |
82 llvm::GlobalValue::LinkageTypes Linkage, | |
83 bool IsProto); | |
84 ~FunctionDeclaration() final {} | |
85 const FuncSigType &getSignature() const { return Signature; } | |
86 llvm::CallingConv::ID getCallingConv() const { return CallingConv; } | |
87 llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; } | |
88 // isProto implies that there isn't a (local) definition for the function. | |
89 bool isProto() const { return IsProto; } | |
90 static bool classof(const GlobalDeclaration *Addr) { | |
91 return Addr->getKind() == FunctionDeclarationKind; | |
92 } | |
93 void dumpType(Ostream &Stream) const final; | |
94 void dump(Ostream &Stream) const final; | |
95 bool getIsExternal() const final { | |
96 return Linkage == llvm::GlobalValue::ExternalLinkage; | |
97 } | |
98 // bool hasInitializer() const final { return !IsProto; } | |
99 | |
100 virtual IceString mangleName(GlobalContext *Ctx) const final { | |
101 return (getIsExternal() && IsProto) ? Name : Ctx->mangleName(Name); | |
102 } | |
103 | |
104 private: | |
105 const Ice::FuncSigType Signature; | |
106 llvm::CallingConv::ID CallingConv; | |
107 llvm::GlobalValue::LinkageTypes Linkage; | |
108 bool IsProto; | |
109 | |
110 FunctionDeclaration(const FuncSigType &Signature, | |
111 llvm::CallingConv::ID CallingConv, | |
112 llvm::GlobalValue::LinkageTypes Linkage, bool IsProto) | |
113 : GlobalDeclaration(FunctionDeclarationKind), Signature(Signature), | |
114 CallingConv(CallingConv), Linkage(Linkage), IsProto(IsProto) {} | |
115 }; | |
116 | |
117 /// Models a global variable declaration, and its initializers. | |
118 class VariableDeclaration : public GlobalDeclaration { | |
119 VariableDeclaration(const VariableDeclaration &) = delete; | |
120 VariableDeclaration &operator=(const VariableDeclaration &) = delete; | |
121 friend class GlobalContext; | |
122 // TODO(kschimpf) Factor out allocation of initializers into the | |
123 // global context, so that memory allocation/collection can be | |
124 // optimized. | |
125 public: | |
34 /// Base class for a global variable initializer. | 126 /// Base class for a global variable initializer. |
35 class Initializer { | 127 class Initializer { |
36 Initializer(const Initializer &) = delete; | 128 Initializer(const Initializer &) = delete; |
37 Initializer &operator=(const Initializer &) = delete; | 129 Initializer &operator=(const Initializer &) = delete; |
38 | 130 |
39 public: | 131 public: |
40 /// Discriminator for LLVM-style RTTI. | 132 /// Discriminator for LLVM-style RTTI. |
41 enum InitializerKind { | 133 enum InitializerKind { |
42 DataInitializerKind, | 134 DataInitializerKind, |
43 ZeroInitializerKind, | 135 ZeroInitializerKind, |
(...skipping 30 matching lines...) Expand all Loading... | |
74 ++i; | 166 ++i; |
75 } | 167 } |
76 } | 168 } |
77 DataInitializer(const char *Str, size_t StrLen) | 169 DataInitializer(const char *Str, size_t StrLen) |
78 : Initializer(DataInitializerKind), Contents(StrLen) { | 170 : Initializer(DataInitializerKind), Contents(StrLen) { |
79 for (size_t i = 0; i < StrLen; ++i) | 171 for (size_t i = 0; i < StrLen; ++i) |
80 Contents[i] = static_cast<uint8_t>(Str[i]); | 172 Contents[i] = static_cast<uint8_t>(Str[i]); |
81 } | 173 } |
82 ~DataInitializer() override {} | 174 ~DataInitializer() override {} |
83 const DataVecType &getContents() const { return Contents; } | 175 const DataVecType &getContents() const { return Contents; } |
84 SizeT getNumBytes() const override { return Contents.size(); } | 176 SizeT getNumBytes() const final { return Contents.size(); } |
85 void dump(Ostream &Stream) const override; | 177 void dump(Ostream &Stream) const final; |
86 static bool classof(const Initializer *D) { | 178 static bool classof(const Initializer *D) { |
87 return D->getKind() == DataInitializerKind; | 179 return D->getKind() == DataInitializerKind; |
88 } | 180 } |
89 | 181 |
90 private: | 182 private: |
91 // The byte contents of the data initializer. | 183 // The byte contents of the data initializer. |
92 DataVecType Contents; | 184 DataVecType Contents; |
93 }; | 185 }; |
94 | 186 |
95 /// Defines a sequence of bytes initialized to zero. | 187 /// Defines a sequence of bytes initialized to zero. |
96 class ZeroInitializer : public Initializer { | 188 class ZeroInitializer : public Initializer { |
97 ZeroInitializer(const ZeroInitializer &) = delete; | 189 ZeroInitializer(const ZeroInitializer &) = delete; |
98 ZeroInitializer &operator=(const ZeroInitializer &) = delete; | 190 ZeroInitializer &operator=(const ZeroInitializer &) = delete; |
99 | 191 |
100 public: | 192 public: |
101 explicit ZeroInitializer(SizeT Size) | 193 explicit ZeroInitializer(SizeT Size) |
102 : Initializer(ZeroInitializerKind), Size(Size) {} | 194 : Initializer(ZeroInitializerKind), Size(Size) {} |
103 ~ZeroInitializer() override {} | 195 ~ZeroInitializer() override {} |
104 SizeT getNumBytes() const override { return Size; } | 196 SizeT getNumBytes() const final { return Size; } |
105 void dump(Ostream &Stream) const override; | 197 void dump(Ostream &Stream) const final; |
106 static bool classof(const Initializer *Z) { | 198 static bool classof(const Initializer *Z) { |
107 return Z->getKind() == ZeroInitializerKind; | 199 return Z->getKind() == ZeroInitializerKind; |
108 } | 200 } |
109 | 201 |
110 private: | 202 private: |
111 // The number of bytes to be zero initialized. | 203 // The number of bytes to be zero initialized. |
112 SizeT Size; | 204 SizeT Size; |
113 }; | 205 }; |
114 | 206 |
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. | 207 // Relocation address offsets must be 32 bit values. |
161 typedef int32_t RelocOffsetType; | 208 typedef int32_t RelocOffsetType; |
162 static const SizeT RelocAddrSize = 4; | 209 static const SizeT RelocAddrSize = 4; |
163 | 210 |
164 /// Defines the relocation value of another address. | 211 /// Defines the relocation value of another global declaration. |
165 class RelocInitializer : public Initializer { | 212 class RelocInitializer : public Initializer { |
166 RelocInitializer(const RelocInitializer &) = delete; | 213 RelocInitializer(const RelocInitializer &) = delete; |
167 RelocInitializer &operator=(const RelocInitializer &) = delete; | 214 RelocInitializer &operator=(const RelocInitializer &) = delete; |
168 | 215 |
169 public: | 216 public: |
170 RelocInitializer(const RelocationAddress &Address, RelocOffsetType Offset) | 217 RelocInitializer(const GlobalDeclaration *Declaration, |
171 : Initializer(RelocInitializerKind), Address(Address), Offset(Offset) {} | 218 RelocOffsetType Offset) |
219 : Initializer(RelocInitializerKind), Declaration(Declaration), | |
220 Offset(Offset) {} | |
172 ~RelocInitializer() override {} | 221 ~RelocInitializer() override {} |
173 RelocOffsetType getOffset() const { return Offset; } | 222 RelocOffsetType getOffset() const { return Offset; } |
174 IceString getName() const; | 223 const GlobalDeclaration *getDeclaration() const { return Declaration; } |
175 SizeT getNumBytes() const override { return RelocAddrSize; } | 224 SizeT getNumBytes() const final { return RelocAddrSize; } |
176 void dump(Ostream &Stream) const override; | 225 void dump(Ostream &Stream) const final; |
177 virtual void dumpType(Ostream &Stream) const; | 226 void dumpType(Ostream &Stream) const final; |
178 static bool classof(const Initializer *R) { | 227 static bool classof(const Initializer *R) { |
179 return R->getKind() == RelocInitializerKind; | 228 return R->getKind() == RelocInitializerKind; |
180 } | 229 } |
181 | 230 |
182 private: | 231 private: |
183 // The global address used in the relocation. | 232 // The global declaration used in the relocation. |
184 const RelocationAddress Address; | 233 const GlobalDeclaration *Declaration; |
185 // The offset to add to the relocation. | 234 // The offset to add to the relocation. |
186 const RelocOffsetType Offset; | 235 const RelocOffsetType Offset; |
187 }; | 236 }; |
188 | 237 |
189 /// Models the list of initializers. | 238 /// Models the list of initializers. |
190 typedef std::vector<Initializer *> InitializerListType; | 239 typedef std::vector<Initializer *> InitializerListType; |
191 | 240 |
192 GlobalAddress() : Alignment(0), IsConstant(false), IsInternal(true) {} | 241 static VariableDeclaration *create(GlobalContext *Ctx); |
193 ~GlobalAddress(); | 242 ~VariableDeclaration() final; |
194 | 243 |
195 const InitializerListType &getInitializers() const { return Initializers; } | 244 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; } | 245 bool getIsConstant() const { return IsConstant; } |
200 void setIsConstant(bool NewValue) { IsConstant = NewValue; } | 246 void setIsConstant(bool NewValue) { IsConstant = NewValue; } |
201 uint32_t getAlignment() const { return Alignment; } | 247 uint32_t getAlignment() const { return Alignment; } |
202 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } | 248 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } |
203 bool getIsInternal() const { return IsInternal; } | 249 bool getIsInternal() const { return IsInternal; } |
204 void setIsInternal(bool NewValue) { IsInternal = NewValue; } | 250 void setIsInternal(bool NewValue) { IsInternal = NewValue; } |
251 bool getIsExternal() const final { return !getIsInternal(); } | |
252 bool hasInitializer() const { | |
253 return !(Initializers.size() == 1 && | |
254 llvm::isa<ZeroInitializer>(Initializers[0])); | |
255 } | |
205 | 256 |
206 /// Returns the number of bytes for the initializer of the global | 257 /// Returns the number of bytes for the initializer of the global |
207 /// address. | 258 /// address. |
208 SizeT getNumBytes() const { | 259 SizeT getNumBytes() const { |
209 SizeT Count = 0; | 260 SizeT Count = 0; |
210 for (Initializer *Init : Initializers) { | 261 for (Initializer *Init : Initializers) { |
211 Count += Init->getNumBytes(); | 262 Count += Init->getNumBytes(); |
212 } | 263 } |
213 return Count; | 264 return Count; |
214 } | 265 } |
215 | 266 |
216 /// Adds Initializer to the list of initializers. Takes ownership of | 267 /// Adds Initializer to the list of initializers. Takes ownership of |
217 /// the initializer. | 268 /// the initializer. |
218 void addInitializer(Initializer *Initializer) { | 269 void addInitializer(Initializer *Initializer) { |
219 Initializers.push_back(Initializer); | 270 Initializers.push_back(Initializer); |
220 } | 271 } |
221 | 272 |
222 /// Prints out type for initializer associated with the global address | 273 /// Prints out type for initializer associated with the declaration |
223 /// to Stream. | 274 /// to Stream. |
224 void dumpType(Ostream &Stream) const; | 275 void dumpType(Ostream &Stream) const final; |
225 | 276 |
226 /// Prints out the definition of the global address (including | 277 /// Prints out the definition of the global variable declaration |
227 /// initialization). | 278 /// (including initialization). |
228 void dump(Ostream &Stream) const; | 279 void dump(Ostream &Stream) const final; |
280 | |
281 static bool classof(const GlobalDeclaration *Addr) { | |
282 return Addr->getKind() == VariableDeclarationKind; | |
283 } | |
284 | |
285 IceString mangleName(GlobalContext *Ctx) const final { | |
286 return (getIsExternal() && !hasInitializer()) | |
287 ? Name : Ctx->mangleName(Name); | |
288 } | |
289 | |
229 | 290 |
230 private: | 291 private: |
231 // list of initializers associated with the global address. | 292 // list of initializers for the declared variable. |
232 InitializerListType Initializers; | 293 InitializerListType Initializers; |
233 // The name for the global. | 294 // The alignment of the declared variable. |
234 IceString Name; | |
235 // The alignment of the initializer. | |
236 uint32_t Alignment; | 295 uint32_t Alignment; |
237 // True if a constant initializer. | 296 // True if a declared (global) constant. |
238 bool IsConstant; | 297 bool IsConstant; |
239 // True if the address is internal. | 298 // True if the declaration is internal. |
240 bool IsInternal; | 299 bool IsInternal; |
300 | |
301 VariableDeclaration() | |
302 : GlobalDeclaration(VariableDeclarationKind), Alignment(0), | |
303 IsConstant(false), IsInternal(true) {} | |
241 }; | 304 }; |
242 | 305 |
243 template <class StreamType> | 306 template <class StreamType> |
244 inline StreamType &operator<<(StreamType &Stream, | 307 inline StreamType &operator<<(StreamType &Stream, |
245 const GlobalAddress::Initializer &Init) { | 308 const VariableDeclaration::Initializer &Init) { |
246 Init.dump(Stream); | 309 Init.dump(Stream); |
247 return Stream; | 310 return Stream; |
248 } | 311 } |
249 | 312 |
250 template <class StreamType> | 313 template <class StreamType> |
251 inline StreamType &operator<<(StreamType &Stream, const GlobalAddress &Addr) { | 314 inline StreamType &operator<<(StreamType &Stream, |
315 const GlobalDeclaration &Addr) { | |
252 Addr.dump(Stream); | 316 Addr.dump(Stream); |
253 return Stream; | 317 return Stream; |
254 } | 318 } |
255 | 319 |
256 } // end of namespace Ice | 320 } // end of namespace Ice |
257 | 321 |
258 #endif // SUBZERO_SRC_ICEGLOBALINITS_H | 322 #endif // SUBZERO_SRC_ICEGLOBALINITS_H |
OLD | NEW |