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

Unified Diff: src/IceOperand.h

Issue 205613002: Initial skeleton of Subzero. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Use non-anonymous structs so that array_lengthof works Created 6 years, 8 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
« no previous file with comments | « src/IceInst.def ('k') | src/IceOperand.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceOperand.h
diff --git a/src/IceOperand.h b/src/IceOperand.h
new file mode 100644
index 0000000000000000000000000000000000000000..fcad7b9f83d8606d29bebae511c8072d34068755
--- /dev/null
+++ b/src/IceOperand.h
@@ -0,0 +1,251 @@
+//===- subzero/src/IceOperand.h - High-level operands -----------*- 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 Operand class and its target-independent
+// subclasses. The main classes are Variable, which represents an
+// LLVM variable that is either register- or stack-allocated, and the
+// Constant hierarchy, which represents integer, floating-point,
+// and/or symbolic constants.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUBZERO_SRC_ICEOPERAND_H
+#define SUBZERO_SRC_ICEOPERAND_H
+
+#include "IceDefs.h"
+#include "IceTypes.h"
+
+namespace Ice {
+
+class Operand {
+public:
+ enum OperandKind {
+ kConst_Base,
+ kConstInteger,
+ kConstFloat,
+ kConstDouble,
+ kConstRelocatable,
+ kConst_Num,
+ kVariable,
+ // Target-specific operand classes use kTarget as the starting
+ // point for their Kind enum space.
+ kTarget
+ };
+ OperandKind getKind() const { return Kind; }
+ Type getType() const { return Ty; }
+
+ // Every Operand keeps an array of the Variables referenced in
+ // the operand. This is so that the liveness operations can get
+ // quick access to the variables of interest, without having to dig
+ // so far into the operand.
+ SizeT getNumVars() const { return NumVars; }
+ Variable *getVar(SizeT I) const {
+ assert(I < getNumVars());
+ return Vars[I];
+ }
+ virtual void dump(const Cfg *Func) const = 0;
+
+ // Query whether this object was allocated in isolation, or added to
+ // some higher-level pool. This determines whether a containing
+ // object's destructor should delete this object. Generally,
+ // constants are pooled globally, variables are pooled per-CFG, and
+ // target-specific operands are not pooled.
+ virtual bool isPooled() const { return false; }
+
+ virtual ~Operand() {}
+
+protected:
+ Operand(OperandKind Kind, Type Ty)
+ : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {}
+
+ const Type Ty;
+ const OperandKind Kind;
+ // Vars and NumVars are initialized by the derived class.
+ SizeT NumVars;
+ Variable **Vars;
+
+private:
+ Operand(const Operand &) LLVM_DELETED_FUNCTION;
+ Operand &operator=(const Operand &) LLVM_DELETED_FUNCTION;
+};
+
+// Constant is the abstract base class for constants. All
+// constants are allocated from a global arena and are pooled.
+class Constant : public Operand {
+public:
+ virtual void dump(const Cfg *Func) const = 0;
+
+ static bool classof(const Operand *Operand) {
+ OperandKind Kind = Operand->getKind();
+ return Kind >= kConst_Base && Kind <= kConst_Num;
+ }
+
+protected:
+ Constant(OperandKind Kind, Type Ty) : Operand(Kind, Ty) {
+ Vars = NULL;
+ NumVars = 0;
+ }
+ virtual ~Constant() {}
+
+private:
+ Constant(const Constant &) LLVM_DELETED_FUNCTION;
+ Constant &operator=(const Constant &) LLVM_DELETED_FUNCTION;
+};
+
+// ConstantPrimitive<> wraps a primitive type.
+template <typename T, Operand::OperandKind K>
+class ConstantPrimitive : public Constant {
+public:
+ static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, T Value) {
+ return new (Ctx->allocate<ConstantPrimitive>())
+ ConstantPrimitive(Ty, Value);
+ }
+ T getValue() const { return Value; }
+ virtual void dump(const Cfg *Func) const {
+ Ostream &Str = Func->getContext()->getStrDump();
+ Str << getValue();
+ }
+
+ static bool classof(const Operand *Operand) {
+ return Operand->getKind() == K;
+ }
+
+private:
+ ConstantPrimitive(Type Ty, T Value) : Constant(K, Ty), Value(Value) {}
+ ConstantPrimitive(const ConstantPrimitive &) LLVM_DELETED_FUNCTION;
+ ConstantPrimitive &operator=(const ConstantPrimitive &) LLVM_DELETED_FUNCTION;
+ virtual ~ConstantPrimitive() {}
+ const T Value;
+};
+
+typedef ConstantPrimitive<uint64_t, Operand::kConstInteger> ConstantInteger;
+typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat;
+typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble;
+
+// RelocatableTuple bundles the parameters that are used to
+// construct an ConstantRelocatable. It is done this way so that
+// ConstantRelocatable can fit into the global constant pool
+// template mechanism.
+class RelocatableTuple {
+ RelocatableTuple &operator=(const RelocatableTuple &) LLVM_DELETED_FUNCTION;
+
+public:
+ RelocatableTuple(const int64_t Offset, const IceString &Name,
+ bool SuppressMangling)
+ : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {}
+ RelocatableTuple(const RelocatableTuple &Other)
+ : Offset(Other.Offset), Name(Other.Name),
+ SuppressMangling(Other.SuppressMangling) {}
+
+ const int64_t Offset;
+ const IceString Name;
+ bool SuppressMangling;
+};
+
+bool operator<(const RelocatableTuple &A, const RelocatableTuple &B);
+
+// ConstantRelocatable represents a symbolic constant combined with
+// a fixed offset.
+class ConstantRelocatable : public Constant {
+public:
+ static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty,
+ const RelocatableTuple &Tuple) {
+ return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable(
+ Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling);
+ }
+ int64_t getOffset() const { return Offset; }
+ IceString getName() const { return Name; }
+ void setSuppressMangling(bool Value) { SuppressMangling = Value; }
+ bool getSuppressMangling() const { return SuppressMangling; }
+ virtual void dump(const Cfg *Func) const;
+
+ static bool classof(const Operand *Operand) {
+ OperandKind Kind = Operand->getKind();
+ return Kind == kConstRelocatable;
+ }
+
+private:
+ ConstantRelocatable(Type Ty, int64_t Offset, const IceString &Name,
+ bool SuppressMangling)
+ : Constant(kConstRelocatable, Ty), Offset(Offset), Name(Name),
+ SuppressMangling(SuppressMangling) {}
+ ConstantRelocatable(const ConstantRelocatable &) LLVM_DELETED_FUNCTION;
+ ConstantRelocatable &
+ operator=(const ConstantRelocatable &) LLVM_DELETED_FUNCTION;
+ virtual ~ConstantRelocatable() {}
+ const int64_t Offset; // fixed offset to add
+ const IceString Name; // optional for debug/dump
+ bool SuppressMangling;
+};
+
+// Variable represents an operand that is register-allocated or
+// stack-allocated. If it is register-allocated, it will ultimately
+// have a non-negative RegNum field.
+class Variable : public Operand {
+public:
+ static Variable *create(Cfg *Func, Type Ty, const CfgNode *Node, SizeT Index,
+ const IceString &Name) {
+ return new (Func->allocate<Variable>()) Variable(Ty, Node, Index, Name);
+ }
+
+ SizeT getIndex() const { return Number; }
+ IceString getName() const;
+
+ Inst *getDefinition() const { return DefInst; }
+ void setDefinition(Inst *Inst, const CfgNode *Node);
+ void replaceDefinition(Inst *Inst, const CfgNode *Node);
+
+ const CfgNode *getLocalUseNode() const { return DefNode; }
+ bool isMultiblockLife() const { return (DefNode == NULL); }
+ void setUse(const Inst *Inst, const CfgNode *Node);
+
+ bool getIsArg() const { return IsArgument; }
+ void setIsArg(Cfg *Func);
+
+ virtual void dump(const Cfg *Func) const;
+
+ static bool classof(const Operand *Operand) {
+ return Operand->getKind() == kVariable;
+ }
+
+private:
+ Variable(Type Ty, const CfgNode *Node, SizeT Index, const IceString &Name)
+ : Operand(kVariable, Ty), Number(Index), Name(Name), DefInst(NULL),
+ DefNode(Node), IsArgument(false) {
+ Vars = VarsReal;
+ Vars[0] = this;
+ NumVars = 1;
+ }
+ Variable(const Variable &) LLVM_DELETED_FUNCTION;
+ Variable &operator=(const Variable &) LLVM_DELETED_FUNCTION;
+ virtual ~Variable() {}
+ // Number is unique across all variables, and is used as a
+ // (bit)vector index for liveness analysis.
+ const SizeT Number;
+ // Name is optional.
+ const IceString Name;
+ // DefInst is the instruction that produces this variable as its
+ // dest.
+ Inst *DefInst;
+ // DefNode is the node where this variable was produced, and is
+ // reset to NULL if it is used outside that node. This is used for
+ // detecting isMultiblockLife(). TODO: Collapse this to a single
+ // bit and use a separate pass to calculate the values across the
+ // Cfg. This saves space in the Variable, and removes the fragility
+ // of incrementally computing and maintaining the information.
+ const CfgNode *DefNode;
+ bool IsArgument;
+ // VarsReal (and Operand::Vars) are set up such that Vars[0] ==
+ // this.
+ Variable *VarsReal[1];
+};
+
+} // end of namespace Ice
+
+#endif // SUBZERO_SRC_ICEOPERAND_H
« no previous file with comments | « src/IceInst.def ('k') | src/IceOperand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698