Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(622)

Side by Side Diff: src/IceGlobalInits.h

Issue 641193002: Introduce the notion of function addresses in Subzero. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues from Jan. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
OLDNEW
« src/IceGlobalContext.cpp ('K') | « src/IceGlobalContext.cpp ('k') | src/IceGlobalInits.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698