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

Unified 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: Clean up code and fix nits. 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 side-by-side diff with in-line comments
Download patch
Index: src/IceGlobalInits.h
diff --git a/src/IceGlobalInits.h b/src/IceGlobalInits.h
index 09e5574a0b01139f94f2f4cda63aadda10612c86..939b4b60eaaf572b9b115ce0c5833e7d8977d437 100644
--- a/src/IceGlobalInits.h
+++ b/src/IceGlobalInits.h
@@ -17,6 +17,10 @@
#define SUBZERO_SRC_ICEGLOBALINITS_H
#include "IceDefs.h"
+#include "IceTypes.h"
+
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/GlobalValue.h" // for GlobalValue::LinkageTypes
namespace llvm {
// TODO(kschimpf): Remove this dependency on LLVM IR.
@@ -25,12 +29,90 @@ class Value;
namespace Ice {
-/// Models a global address, and its initializers.
+/// Base class for global and function addresses.
class GlobalAddress {
GlobalAddress(const GlobalAddress &) = delete;
GlobalAddress &operator=(const GlobalAddress &) = delete;
public:
+ /// Discriminator for LLVM-style RTTI.
+ enum GlobalAddressKind { FunctionKind, GlobalVariableKind };
+ GlobalAddressKind getKind() const { return Kind; }
+ const IceString &getName() const { return Name; }
+ void setName(const IceString &NewName) { Name = NewName; }
+ bool hasName() const { return !Name.empty(); }
+ IceString mangleName(GlobalContext *Ctx) const;
+
+ virtual ~GlobalAddress() {}
+
+ /// Returns true if address is external.
+ virtual bool getIsExternal() const = 0;
+
+ /// Returns true if initialized (or defined if function).
+ virtual bool hasInitializer() const = 0;
+
+ /// Prints out type of the global address.
+ virtual void dumpType(Ostream &Stream) const = 0;
+
+ /// Prints out the declaration of the global address.
+ virtual void dump(Ostream &Stream) const = 0;
+
+protected:
+ GlobalAddress(GlobalAddressKind Kind) : Kind(Kind) {}
+
+ const GlobalAddressKind Kind;
+ // The name for the global address.
+ IceString Name;
+};
+
+// Models a function address. Also defines the type signature of the function,
+// it's calling conventions, and its linkage.
Jim Stichnoth 2014/10/10 13:15:00 its
Karl 2014/10/10 20:17:30 Done.
+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
+ Function(const Function &) = delete;
+ Function &operator=(const Function &) = delete;
+ friend class GlobalContext;
+
+public:
+ static Function *create(GlobalContext *Ctx, const FuncSigType &Signature,
+ llvm::CallingConv::ID CallingConv,
+ llvm::GlobalValue::LinkageTypes Linkage,
+ bool IsProto);
+ ~Function() final {}
+ const FuncSigType &getSignature() const { return Signature; }
+ llvm::CallingConv::ID getCallingConv() const { return CallingConv; }
+ llvm::GlobalValue::LinkageTypes getLinkage() const { return Linkage; }
+ // isProto implies that there isn't a (local) definition for the function.
+ bool isProto() const { return IsProto; }
+ static bool classof(const GlobalAddress *Addr) {
+ return Addr->getKind() == FunctionKind;
+ }
+ void dumpType(Ostream &Stream) const final;
+ void dump(Ostream &Stream) const final;
+ bool getIsExternal() const final {
+ return Linkage == llvm::GlobalValue::ExternalLinkage;
+ }
+ bool hasInitializer() const final { return !IsProto; }
+
+private:
+ const Ice::FuncSigType Signature;
+ llvm::CallingConv::ID CallingConv;
+ llvm::GlobalValue::LinkageTypes Linkage;
+ bool IsProto;
+
+ Function(const FuncSigType &Signature, llvm::CallingConv::ID CallingConv,
+ llvm::GlobalValue::LinkageTypes Linkage, bool IsProto)
+ : GlobalAddress(FunctionKind), Signature(Signature),
+ CallingConv(CallingConv), Linkage(Linkage), IsProto(IsProto) {}
+};
+
+/// 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.
+class GlobalVariable : public GlobalAddress {
+ GlobalVariable(const GlobalVariable &) = delete;
+ GlobalVariable &operator=(const GlobalVariable &) = delete;
+ friend class GlobalContext;
+ // TODO(kschimpf) Factor out allocation of initializers into global context,
+ // so that memory allocation/collection can be optimized.
+public:
/// Base class for a global variable initializer.
class Initializer {
Initializer(const Initializer &) = delete;
@@ -81,8 +163,8 @@ public:
}
~DataInitializer() override {}
const DataVecType &getContents() const { return Contents; }
- SizeT getNumBytes() const override { return Contents.size(); }
- void dump(Ostream &Stream) const override;
+ SizeT getNumBytes() const final { return Contents.size(); }
+ void dump(Ostream &Stream) const final;
static bool classof(const Initializer *D) {
return D->getKind() == DataInitializerKind;
}
@@ -101,8 +183,8 @@ public:
explicit ZeroInitializer(SizeT Size)
: Initializer(ZeroInitializerKind), Size(Size) {}
~ZeroInitializer() override {}
- SizeT getNumBytes() const override { return Size; }
- void dump(Ostream &Stream) const override;
+ SizeT getNumBytes() const final { return Size; }
+ void dump(Ostream &Stream) const final;
static bool classof(const Initializer *Z) {
return Z->getKind() == ZeroInitializerKind;
}
@@ -112,51 +194,6 @@ public:
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;
@@ -167,21 +204,21 @@ public:
RelocInitializer &operator=(const RelocInitializer &) = delete;
public:
- RelocInitializer(const RelocationAddress &Address, RelocOffsetType Offset)
+ RelocInitializer(const GlobalAddress *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;
+ const GlobalAddress *getAddress() const { return Address; }
+ SizeT getNumBytes() const final { return RelocAddrSize; }
+ void dump(Ostream &Stream) const final;
+ void dumpType(Ostream &Stream) const final;
static bool classof(const Initializer *R) {
return R->getKind() == RelocInitializerKind;
}
private:
// The global address used in the relocation.
- const RelocationAddress Address;
+ const GlobalAddress *Address;
// The offset to add to the relocation.
const RelocOffsetType Offset;
};
@@ -189,19 +226,21 @@ public:
/// Models the list of initializers.
typedef std::vector<Initializer *> InitializerListType;
- GlobalAddress() : Alignment(0), IsConstant(false), IsInternal(true) {}
- ~GlobalAddress();
+ static GlobalVariable *create(GlobalContext *Ctx);
+ ~GlobalVariable() final;
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; }
+ bool getIsExternal() const final { return !getIsInternal(); }
+ bool hasInitializer() const final {
+ return !(Initializers.size() == 1 &&
+ llvm::isa<ZeroInitializer>(Initializers[0]));
+ }
/// Returns the number of bytes for the initializer of the global
/// address.
@@ -221,34 +260,40 @@ public:
/// Prints out type for initializer associated with the global address
/// to Stream.
- void dumpType(Ostream &Stream) const;
+ void dumpType(Ostream &Stream) const final;
/// Prints out the definition of the global address (including
/// initialization).
- void dump(Ostream &Stream) const;
+ void dump(Ostream &Stream) const final;
+
+ static bool classof(const GlobalAddress *Addr) {
+ return Addr->getKind() == GlobalVariableKind;
+ }
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;
+
+ GlobalVariable()
+ : GlobalAddress(GlobalVariableKind), Alignment(0), IsConstant(false),
+ IsInternal(true) {}
};
template <class StreamType>
inline StreamType &operator<<(StreamType &Stream,
- const GlobalAddress::Initializer &Init) {
+ const GlobalVariable::Initializer &Init) {
Init.dump(Stream);
return Stream;
}
template <class StreamType>
-inline StreamType &operator<<(StreamType &Stream, const GlobalAddress &Addr) {
+inline StreamType &operator<<(StreamType &Stream, const GlobalVariable &Addr) {
Addr.dump(Stream);
return Stream;
}

Powered by Google App Engine
This is Rietveld 408576698