Chromium Code Reviews| Index: src/IceGlobalInits.h |
| diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2f068f613fa6541836d63337c6f368f82fb0c104 |
| --- /dev/null |
| +++ b/src/IceGlobalInits.h |
| @@ -0,0 +1,218 @@ |
| +//===- 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 |
|
Jim Stichnoth
2014/10/03 01:28:08
Reformat? e.g. "and" ought to fit on this line.
Karl
2014/10/04 16:28:34
Done.
|
| +// 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 { |
| +public: |
| + /// Base class for a global variable initializer. |
| + class Initializer { |
| + 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: |
| + 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 { |
| + public: |
| + template <class Data> |
| + DataInitializer(const Data &Values) |
| + : Initializer(DataInitializerKind), Contents(Values.size()) { |
| + size_t i = 0; |
| + for (auto &V : Values) { |
| + Contents[i] = static_cast<uint8_t>(V); |
|
jvoung (off chromium)
2014/10/03 16:15:29
Would it be cleaner to just:
Contents.push_back(..
Karl
2014/10/04 16:28:34
The reason I factored it this way was to optimize
|
| + ++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; |
|
jvoung (off chromium)
2014/10/03 16:15:30
Disallow copy/assign for these initializer types?
Karl
2014/10/04 16:28:34
Done.
|
| + }; |
| + |
| + /// Defines a sequence of bytes initialized to zero. |
| + class ZeroInitializer : public Initializer { |
| + public: |
| + ZeroInitializer(SizeT Size) |
|
jvoung (off chromium)
2014/10/03 16:15:29
explicit
Karl
2014/10/04 16:28:34
Done.
|
| + : 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). |
| + struct RelocationAddress { |
| + RelocationAddress(llvm::Value *Function) : Kind(FunctionRelocation) { |
| + Address.Function = Function; |
| + } |
| + RelocationAddress(GlobalAddress *GlobalAddr) |
| + : Kind(GlobalAddressRelocation) { |
| + Address.GlobalAddr = GlobalAddr; |
| + } |
| + 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 { |
| + 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. |
| + RelocationAddress Address; |
| + // The offset to add to the relocation. |
| + 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; } |
| + |
| + /// 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; |
| + } |
| + |
| + /// Addes Initializer to the list of initializers. Takes ownership of |
|
jvoung (off chromium)
2014/10/03 16:15:30
Adds
Karl
2014/10/04 16:28:34
Done.
|
| + /// the initializer. |
| + void AddInitializer(Initializer *Initializer) { |
|
jvoung (off chromium)
2014/10/03 16:15:30
naming style: addInitializer(...) ?
Karl
2014/10/04 16:28:34
Done.
|
| + 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 |