Chromium Code Reviews| 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 |