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