Index: src/IceGlobalInits.h |
diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..09e5574a0b01139f94f2f4cda63aadda10612c86 |
--- /dev/null |
+++ b/src/IceGlobalInits.h |
@@ -0,0 +1,258 @@ |
+//===- subzero/src/IceGlobalInits.h - Global initializers -------*- C++ -*-===// |
+// |
+// The Subzero Code Generator |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+// |
+// This file declares the representation of global addresses and |
+// initializers in Subzero. Global initializers are represented as a |
+// sequence of simple initializers. |
+// |
+//===----------------------------------------------------------------------===// |
+ |
+#ifndef SUBZERO_SRC_ICEGLOBALINITS_H |
+#define SUBZERO_SRC_ICEGLOBALINITS_H |
+ |
+#include "IceDefs.h" |
+ |
+namespace llvm { |
+// TODO(kschimpf): Remove this dependency on LLVM IR. |
+class Value; |
+} |
+ |
+namespace Ice { |
+ |
+/// Models a global address, and its initializers. |
+class GlobalAddress { |
+ GlobalAddress(const GlobalAddress &) = delete; |
+ GlobalAddress &operator=(const GlobalAddress &) = delete; |
+ |
+public: |
+ /// Base class for a global variable initializer. |
+ class Initializer { |
+ Initializer(const Initializer &) = delete; |
+ Initializer &operator=(const Initializer &) = delete; |
+ |
+ public: |
+ /// Discriminator for LLVM-style RTTI. |
+ enum InitializerKind { |
+ DataInitializerKind, |
+ ZeroInitializerKind, |
+ RelocInitializerKind |
+ }; |
+ InitializerKind getKind() const { return Kind; } |
+ virtual ~Initializer() {} |
+ virtual SizeT getNumBytes() const = 0; |
+ virtual void dump(Ostream &Stream) const = 0; |
+ virtual void dumpType(Ostream &Stream) const; |
+ |
+ protected: |
+ explicit Initializer(InitializerKind Kind) : Kind(Kind) {} |
+ |
+ private: |
+ const InitializerKind Kind; |
+ }; |
+ |
+ // Models the data in a data initializer. |
+ typedef std::vector<uint8_t> DataVecType; |
+ |
+ /// Defines a sequence of byte values as a data initializer. |
+ class DataInitializer : public Initializer { |
+ DataInitializer(const DataInitializer &) = delete; |
+ DataInitializer &operator=(const DataInitializer &) = delete; |
+ |
+ public: |
+ template <class IntContainer> |
+ DataInitializer(const IntContainer &Values) |
+ : Initializer(DataInitializerKind), Contents(Values.size()) { |
+ size_t i = 0; |
+ for (auto &V : Values) { |
+ Contents[i] = static_cast<uint8_t>(V); |
+ ++i; |
+ } |
+ } |
+ DataInitializer(const char *Str, size_t StrLen) |
+ : Initializer(DataInitializerKind), Contents(StrLen) { |
+ for (size_t i = 0; i < StrLen; ++i) |
+ Contents[i] = static_cast<uint8_t>(Str[i]); |
+ } |
+ ~DataInitializer() override {} |
+ const DataVecType &getContents() const { return Contents; } |
+ SizeT getNumBytes() const override { return Contents.size(); } |
+ void dump(Ostream &Stream) const override; |
+ static bool classof(const Initializer *D) { |
+ return D->getKind() == DataInitializerKind; |
+ } |
+ |
+ private: |
+ // The byte contents of the data initializer. |
+ DataVecType Contents; |
+ }; |
+ |
+ /// Defines a sequence of bytes initialized to zero. |
+ class ZeroInitializer : public Initializer { |
+ ZeroInitializer(const ZeroInitializer &) = delete; |
+ ZeroInitializer &operator=(const ZeroInitializer &) = delete; |
+ |
+ public: |
+ explicit ZeroInitializer(SizeT Size) |
+ : Initializer(ZeroInitializerKind), Size(Size) {} |
+ ~ZeroInitializer() override {} |
+ SizeT getNumBytes() const override { return Size; } |
+ void dump(Ostream &Stream) const override; |
+ static bool classof(const Initializer *Z) { |
+ return Z->getKind() == ZeroInitializerKind; |
+ } |
+ |
+ private: |
+ // The number of bytes to be zero initialized. |
+ SizeT Size; |
+ }; |
+ |
+ /// Defines the kind of relocation addresses allowed. |
+ enum RelocationKind { FunctionRelocation, GlobalAddressRelocation }; |
+ |
+ /// Defines a relocation address (i.e. reference to a function |
+ /// or global variable address). |
+ class RelocationAddress { |
+ RelocationAddress &operator=(const RelocationAddress &) = delete; |
+ |
+ public: |
+ explicit RelocationAddress(const RelocationAddress &Addr) |
+ : Kind(Addr.Kind) { |
+ switch (Kind) { |
+ case FunctionRelocation: |
+ Address.Function = Addr.Address.Function; |
+ break; |
+ case GlobalAddressRelocation: |
+ Address.GlobalAddr = Addr.Address.GlobalAddr; |
+ } |
+ } |
+ explicit RelocationAddress(llvm::Value *Function) |
+ : Kind(FunctionRelocation) { |
+ Address.Function = Function; |
+ } |
+ explicit RelocationAddress(GlobalAddress *GlobalAddr) |
+ : Kind(GlobalAddressRelocation) { |
+ Address.GlobalAddr = GlobalAddr; |
+ } |
+ RelocationKind getKind() const { return Kind; } |
+ llvm::Value *getFunction() const { |
+ assert(Kind == FunctionRelocation); |
+ return Address.Function; |
+ } |
+ GlobalAddress *getGlobalAddr() const { |
+ assert(Kind == GlobalAddressRelocation); |
+ return Address.GlobalAddr; |
+ } |
+ private: |
+ const RelocationKind Kind; |
+ union { |
+ // TODO(kschimpf) Integrate Functions into ICE model. |
+ llvm::Value *Function; |
+ GlobalAddress *GlobalAddr; |
+ } Address; |
+ }; |
+ |
+ // Relocation address offsets must be 32 bit values. |
+ typedef int32_t RelocOffsetType; |
+ static const SizeT RelocAddrSize = 4; |
+ |
+ /// Defines the relocation value of another address. |
+ class RelocInitializer : public Initializer { |
+ RelocInitializer(const RelocInitializer &) = delete; |
+ RelocInitializer &operator=(const RelocInitializer &) = delete; |
+ |
+ public: |
+ RelocInitializer(const RelocationAddress &Address, RelocOffsetType Offset) |
+ : Initializer(RelocInitializerKind), Address(Address), Offset(Offset) {} |
+ ~RelocInitializer() override {} |
+ RelocOffsetType getOffset() const { return Offset; } |
+ IceString getName() const; |
+ SizeT getNumBytes() const override { return RelocAddrSize; } |
+ void dump(Ostream &Stream) const override; |
+ virtual void dumpType(Ostream &Stream) const; |
+ static bool classof(const Initializer *R) { |
+ return R->getKind() == RelocInitializerKind; |
+ } |
+ |
+ private: |
+ // The global address used in the relocation. |
+ const RelocationAddress Address; |
+ // The offset to add to the relocation. |
+ const RelocOffsetType Offset; |
+ }; |
+ |
+ /// Models the list of initializers. |
+ typedef std::vector<Initializer *> InitializerListType; |
+ |
+ GlobalAddress() : Alignment(0), IsConstant(false), IsInternal(true) {} |
+ ~GlobalAddress(); |
+ |
+ const InitializerListType &getInitializers() const { return Initializers; } |
+ bool hasName() const { return !Name.empty(); } |
+ const IceString &getName() const { return Name; } |
+ void setName(const IceString &NewName) { Name = NewName; } |
+ bool getIsConstant() const { return IsConstant; } |
+ void setIsConstant(bool NewValue) { IsConstant = NewValue; } |
+ uint32_t getAlignment() const { return Alignment; } |
+ void setAlignment(uint32_t NewAlignment) { Alignment = NewAlignment; } |
+ bool getIsInternal() const { return IsInternal; } |
+ void setIsInternal(bool NewValue) { IsInternal = NewValue; } |
+ |
+ /// Returns the number of bytes for the initializer of the global |
+ /// address. |
+ SizeT getNumBytes() const { |
+ SizeT Count = 0; |
+ for (Initializer *Init : Initializers) { |
+ Count += Init->getNumBytes(); |
+ } |
+ return Count; |
+ } |
+ |
+ /// Adds Initializer to the list of initializers. Takes ownership of |
+ /// the initializer. |
+ void addInitializer(Initializer *Initializer) { |
+ Initializers.push_back(Initializer); |
+ } |
+ |
+ /// Prints out type for initializer associated with the global address |
+ /// to Stream. |
+ void dumpType(Ostream &Stream) const; |
+ |
+ /// Prints out the definition of the global address (including |
+ /// initialization). |
+ void dump(Ostream &Stream) const; |
+ |
+private: |
+ // list of initializers associated with the global address. |
+ InitializerListType Initializers; |
+ // The name for the global. |
+ IceString Name; |
+ // The alignment of the initializer. |
+ uint32_t Alignment; |
+ // True if a constant initializer. |
+ bool IsConstant; |
+ // True if the address is internal. |
+ bool IsInternal; |
+}; |
+ |
+template <class StreamType> |
+inline StreamType &operator<<(StreamType &Stream, |
+ const GlobalAddress::Initializer &Init) { |
+ Init.dump(Stream); |
+ return Stream; |
+} |
+ |
+template <class StreamType> |
+inline StreamType &operator<<(StreamType &Stream, const GlobalAddress &Addr) { |
+ Addr.dump(Stream); |
+ return Stream; |
+} |
+ |
+} // end of namespace Ice |
+ |
+#endif // SUBZERO_SRC_ICEGLOBALINITS_H |