OLD | NEW |
---|---|
(Empty) | |
1 //===- subzero/src/IceGlobalInits.h - Global initializers -------*- C++ -*-===// | |
2 // | |
3 // The Subzero Code Generator | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 // | |
10 // This file declares the representation of global addresses and | |
11 // initializers in Subzero. Global initializers are represented as a | |
12 // sequence of simple initializers. | |
13 // | |
14 //===----------------------------------------------------------------------===// | |
15 | |
16 #ifndef SUBZERO_SRC_ICEGLOBALINITS_H | |
17 #define SUBZERO_SRC_ICEGLOBALINITS_H | |
18 | |
19 #include "IceDefs.h" | |
20 | |
21 namespace llvm { | |
22 // TODO(kschimpf): Remove this dependency on LLVM IR. | |
23 class Value; | |
24 } | |
25 | |
26 namespace Ice { | |
27 | |
28 /// Models a global address, and its initializers. | |
29 class GlobalAddress { | |
30 GlobalAddress(const GlobalAddress &) = delete; | |
31 GlobalAddress &operator=(const GlobalAddress &) = delete; | |
32 | |
33 public: | |
34 /// Base class for a global variable initializer. | |
35 class Initializer { | |
36 Initializer(const Initializer &) = delete; | |
37 Initializer &operator=(const Initializer &) = delete; | |
38 | |
39 public: | |
40 /// Discriminator for LLVM-style RTTI. | |
41 enum InitializerKind { | |
42 DataInitializerKind, | |
43 ZeroInitializerKind, | |
44 RelocInitializerKind | |
45 }; | |
46 InitializerKind getKind() const { return Kind; } | |
47 virtual ~Initializer() {} | |
48 virtual SizeT getNumBytes() const = 0; | |
49 virtual void dump(Ostream &Stream) const = 0; | |
50 virtual void dumpType(Ostream &Stream) const; | |
51 | |
52 protected: | |
53 explicit Initializer(InitializerKind Kind) : Kind(Kind) {} | |
54 | |
55 private: | |
56 const InitializerKind Kind; | |
57 }; | |
58 | |
59 // Models the data in a data initializer. | |
60 typedef std::vector<uint8_t> DataVecType; | |
61 | |
62 /// Defines a sequence of byte values as a data initializer. | |
63 class DataInitializer : public Initializer { | |
64 DataInitializer(const DataInitializer &) = delete; | |
65 DataInitializer &operator=(const DataInitializer &) = delete; | |
66 | |
67 public: | |
68 template <class Data> | |
Jim Stichnoth
2014/10/06 18:16:38
I didn't see any uses of this templatized construc
Karl
2014/10/06 22:44:04
I should be more clear. This constructor gets cont
| |
69 DataInitializer(const Data &Values) | |
70 : Initializer(DataInitializerKind), Contents(Values.size()) { | |
71 size_t i = 0; | |
72 for (auto &V : Values) { | |
73 Contents[i] = static_cast<uint8_t>(V); | |
74 ++i; | |
75 } | |
76 } | |
77 DataInitializer(const char *Str, size_t StrLen) | |
78 : Initializer(DataInitializerKind), Contents(StrLen) { | |
79 for (size_t i = 0; i < StrLen; ++i) | |
80 Contents[i] = static_cast<uint8_t>(Str[i]); | |
81 } | |
82 ~DataInitializer() override {} | |
83 const DataVecType &getContents() const { return Contents; } | |
84 SizeT getNumBytes() const override { return Contents.size(); } | |
85 void dump(Ostream &Stream) const override; | |
86 static bool classof(const Initializer *D) { | |
87 return D->getKind() == DataInitializerKind; | |
88 } | |
89 | |
90 private: | |
91 // The byte contents of the data initializer. | |
92 DataVecType Contents; | |
93 }; | |
94 | |
95 /// Defines a sequence of bytes initialized to zero. | |
96 class ZeroInitializer : public Initializer { | |
97 ZeroInitializer(const ZeroInitializer &) = delete; | |
98 ZeroInitializer &operator=(const ZeroInitializer &) = delete; | |
99 | |
100 public: | |
101 explicit ZeroInitializer(SizeT Size) | |
102 : Initializer(ZeroInitializerKind), Size(Size) {} | |
103 ~ZeroInitializer() override {} | |
104 SizeT getNumBytes() const override { return Size; } | |
105 void dump(Ostream &Stream) const override; | |
106 static bool classof(const Initializer *Z) { | |
107 return Z->getKind() == ZeroInitializerKind; | |
108 } | |
109 | |
110 private: | |
111 // The number of bytes to be zero initialized. | |
112 SizeT Size; | |
113 }; | |
114 | |
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 Kind; | |
Jim Stichnoth
2014/10/06 18:16:38
const?
Karl
2014/10/06 22:44:04
Converted to only allow const accessors.
| |
143 union { | |
144 // TODO(kschimpf) Integrate Functions into ICE model. | |
145 llvm::Value *Function; | |
146 GlobalAddress *GlobalAddr; | |
147 } Address; | |
148 }; | |
149 | |
150 // Relocation address offsets must be 32 bit values. | |
151 typedef int32_t RelocOffsetType; | |
152 static const SizeT RelocAddrSize = 4; | |
153 | |
154 /// Defines the relocation value of another address. | |
155 class RelocInitializer : public Initializer { | |
156 RelocInitializer(const RelocInitializer &) = delete; | |
157 RelocInitializer &operator=(const RelocInitializer &) = delete; | |
158 | |
159 public: | |
160 RelocInitializer(const RelocationAddress &Address, RelocOffsetType Offset) | |
161 : Initializer(RelocInitializerKind), Address(Address), Offset(Offset) {} | |
162 ~RelocInitializer() override {} | |
163 RelocOffsetType getOffset() const { return Offset; } | |
164 IceString getName() const; | |
165 SizeT getNumBytes() const override { return RelocAddrSize; } | |
166 void dump(Ostream &Stream) const override; | |
167 virtual void dumpType(Ostream &Stream) const; | |
168 static bool classof(const Initializer *R) { | |
169 return R->getKind() == RelocInitializerKind; | |
170 } | |
171 | |
172 private: | |
173 // The global address used in the relocation. | |
174 RelocationAddress Address; | |
Jim Stichnoth
2014/10/06 18:16:38
Can these be const?
Karl
2014/10/06 22:44:04
Done.
| |
175 // The offset to add to the relocation. | |
176 RelocOffsetType Offset; | |
177 }; | |
178 | |
179 /// Models the list of initializers. | |
180 typedef std::vector<Initializer *> InitializerListType; | |
181 | |
182 GlobalAddress() : Alignment(0), IsConstant(false), IsInternal(true) {} | |
183 ~GlobalAddress(); | |
184 | |
185 const InitializerListType &getInitializers() const { return Initializers; } | |
186 bool hasName() const { return !Name.empty(); } | |
187 const IceString &getName() const { return Name; } | |
188 void setName(const IceString &NewName) { Name = NewName; } | |
189 bool getIsConstant() const { return IsConstant; } | |
190 void setIsConstant(bool NewValue) { IsConstant = NewValue; } | |
191 uint32_t getAlignment() const { return Alignment; } | |
192 void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } | |
193 bool getIsInternal() const { return IsInternal; } | |
194 void setIsInternal(bool NewValue) { IsInternal = NewValue; } | |
195 | |
196 /// Returns the number of bytes for the initializer of the global | |
197 /// address. | |
198 SizeT getNumBytes() const { | |
199 SizeT Count = 0; | |
200 for (Initializer *Init : Initializers) { | |
201 Count += Init->getNumBytes(); | |
202 } | |
203 return Count; | |
204 } | |
205 | |
206 /// Adds Initializer to the list of initializers. Takes ownership of | |
207 /// the initializer. | |
208 void addInitializer(Initializer *Initializer) { | |
209 Initializers.push_back(Initializer); | |
210 } | |
211 | |
212 /// Prints out type for initializer associated with the global address | |
213 /// to Stream. | |
214 void dumpType(Ostream &Stream) const; | |
215 | |
216 /// Prints out the definition of the global address (including | |
217 /// initialization). | |
218 void dump(Ostream &Stream) const; | |
219 | |
220 private: | |
221 // list of initializers associated with the global address. | |
222 InitializerListType Initializers; | |
223 // The name for the global. | |
224 IceString Name; | |
225 // The alignment of the initializer. | |
226 uint32_t Alignment; | |
227 // True if a constant initializer. | |
228 bool IsConstant; | |
229 // True if the address is internal. | |
230 bool IsInternal; | |
231 }; | |
232 | |
233 template <class StreamType> | |
234 inline StreamType &operator<<(StreamType &Stream, | |
235 const GlobalAddress::Initializer &Init) { | |
236 Init.dump(Stream); | |
237 return Stream; | |
238 } | |
239 | |
240 template <class StreamType> | |
241 inline StreamType &operator<<(StreamType &Stream, const GlobalAddress &Addr) { | |
242 Addr.dump(Stream); | |
243 return Stream; | |
244 } | |
245 | |
246 } // end of namespace Ice | |
247 | |
248 #endif // SUBZERO_SRC_ICEGLOBALINITS_H | |
OLD | NEW |