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