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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/IceInst.def ('k') | src/IceOperand.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the Operand class and its target-independent
11 // subclasses. The main classes are Variable, which represents an
12 // LLVM variable that is either register- or stack-allocated, and the
13 // Constant hierarchy, which represents integer, floating-point,
14 // and/or symbolic constants.
15 //
16 //===----------------------------------------------------------------------===//
17
18 #ifndef SUBZERO_SRC_ICEOPERAND_H
19 #define SUBZERO_SRC_ICEOPERAND_H
20
21 #include "IceDefs.h"
22 #include "IceTypes.h"
23
24 namespace Ice {
25
26 class Operand {
27 public:
28 enum OperandKind {
29 kConst_Base,
30 kConstInteger,
31 kConstFloat,
32 kConstDouble,
33 kConstRelocatable,
34 kConst_Num,
35 kVariable,
36 // Target-specific operand classes use kTarget as the starting
37 // point for their Kind enum space.
38 kTarget
39 };
40 OperandKind getKind() const { return Kind; }
41 Type getType() const { return Ty; }
42
43 // Every Operand keeps an array of the Variables referenced in
44 // the operand. This is so that the liveness operations can get
45 // quick access to the variables of interest, without having to dig
46 // so far into the operand.
47 SizeT getNumVars() const { return NumVars; }
48 Variable *getVar(SizeT I) const {
49 assert(I < getNumVars());
50 return Vars[I];
51 }
52 virtual void dump(const Cfg *Func) const = 0;
53
54 // Query whether this object was allocated in isolation, or added to
55 // some higher-level pool. This determines whether a containing
56 // object's destructor should delete this object. Generally,
57 // constants are pooled globally, variables are pooled per-CFG, and
58 // target-specific operands are not pooled.
59 virtual bool isPooled() const { return false; }
60
61 virtual ~Operand() {}
62
63 protected:
64 Operand(OperandKind Kind, Type Ty)
65 : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {}
66
67 const Type Ty;
68 const OperandKind Kind;
69 // Vars and NumVars are initialized by the derived class.
70 SizeT NumVars;
71 Variable **Vars;
72
73 private:
74 Operand(const Operand &) LLVM_DELETED_FUNCTION;
75 Operand &operator=(const Operand &) LLVM_DELETED_FUNCTION;
76 };
77
78 // Constant is the abstract base class for constants. All
79 // constants are allocated from a global arena and are pooled.
80 class Constant : public Operand {
81 public:
82 virtual void dump(const Cfg *Func) const = 0;
83
84 static bool classof(const Operand *Operand) {
85 OperandKind Kind = Operand->getKind();
86 return Kind >= kConst_Base && Kind <= kConst_Num;
87 }
88
89 protected:
90 Constant(OperandKind Kind, Type Ty) : Operand(Kind, Ty) {
91 Vars = NULL;
92 NumVars = 0;
93 }
94 virtual ~Constant() {}
95
96 private:
97 Constant(const Constant &) LLVM_DELETED_FUNCTION;
98 Constant &operator=(const Constant &) LLVM_DELETED_FUNCTION;
99 };
100
101 // ConstantPrimitive<> wraps a primitive type.
102 template <typename T, Operand::OperandKind K>
103 class ConstantPrimitive : public Constant {
104 public:
105 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, T Value) {
106 return new (Ctx->allocate<ConstantPrimitive>())
107 ConstantPrimitive(Ty, Value);
108 }
109 T getValue() const { return Value; }
110 virtual void dump(const Cfg *Func) const {
111 Ostream &Str = Func->getContext()->getStrDump();
112 Str << getValue();
113 }
114
115 static bool classof(const Operand *Operand) {
116 return Operand->getKind() == K;
117 }
118
119 private:
120 ConstantPrimitive(Type Ty, T Value) : Constant(K, Ty), Value(Value) {}
121 ConstantPrimitive(const ConstantPrimitive &) LLVM_DELETED_FUNCTION;
122 ConstantPrimitive &operator=(const ConstantPrimitive &) LLVM_DELETED_FUNCTION;
123 virtual ~ConstantPrimitive() {}
124 const T Value;
125 };
126
127 typedef ConstantPrimitive<uint64_t, Operand::kConstInteger> ConstantInteger;
128 typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat;
129 typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble;
130
131 // RelocatableTuple bundles the parameters that are used to
132 // construct an ConstantRelocatable. It is done this way so that
133 // ConstantRelocatable can fit into the global constant pool
134 // template mechanism.
135 class RelocatableTuple {
136 RelocatableTuple &operator=(const RelocatableTuple &) LLVM_DELETED_FUNCTION;
137
138 public:
139 RelocatableTuple(const int64_t Offset, const IceString &Name,
140 bool SuppressMangling)
141 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {}
142 RelocatableTuple(const RelocatableTuple &Other)
143 : Offset(Other.Offset), Name(Other.Name),
144 SuppressMangling(Other.SuppressMangling) {}
145
146 const int64_t Offset;
147 const IceString Name;
148 bool SuppressMangling;
149 };
150
151 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B);
152
153 // ConstantRelocatable represents a symbolic constant combined with
154 // a fixed offset.
155 class ConstantRelocatable : public Constant {
156 public:
157 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty,
158 const RelocatableTuple &Tuple) {
159 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable(
160 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling);
161 }
162 int64_t getOffset() const { return Offset; }
163 IceString getName() const { return Name; }
164 void setSuppressMangling(bool Value) { SuppressMangling = Value; }
165 bool getSuppressMangling() const { return SuppressMangling; }
166 virtual void dump(const Cfg *Func) const;
167
168 static bool classof(const Operand *Operand) {
169 OperandKind Kind = Operand->getKind();
170 return Kind == kConstRelocatable;
171 }
172
173 private:
174 ConstantRelocatable(Type Ty, int64_t Offset, const IceString &Name,
175 bool SuppressMangling)
176 : Constant(kConstRelocatable, Ty), Offset(Offset), Name(Name),
177 SuppressMangling(SuppressMangling) {}
178 ConstantRelocatable(const ConstantRelocatable &) LLVM_DELETED_FUNCTION;
179 ConstantRelocatable &
180 operator=(const ConstantRelocatable &) LLVM_DELETED_FUNCTION;
181 virtual ~ConstantRelocatable() {}
182 const int64_t Offset; // fixed offset to add
183 const IceString Name; // optional for debug/dump
184 bool SuppressMangling;
185 };
186
187 // Variable represents an operand that is register-allocated or
188 // stack-allocated. If it is register-allocated, it will ultimately
189 // have a non-negative RegNum field.
190 class Variable : public Operand {
191 public:
192 static Variable *create(Cfg *Func, Type Ty, const CfgNode *Node, SizeT Index,
193 const IceString &Name) {
194 return new (Func->allocate<Variable>()) Variable(Ty, Node, Index, Name);
195 }
196
197 SizeT getIndex() const { return Number; }
198 IceString getName() const;
199
200 Inst *getDefinition() const { return DefInst; }
201 void setDefinition(Inst *Inst, const CfgNode *Node);
202 void replaceDefinition(Inst *Inst, const CfgNode *Node);
203
204 const CfgNode *getLocalUseNode() const { return DefNode; }
205 bool isMultiblockLife() const { return (DefNode == NULL); }
206 void setUse(const Inst *Inst, const CfgNode *Node);
207
208 bool getIsArg() const { return IsArgument; }
209 void setIsArg(Cfg *Func);
210
211 virtual void dump(const Cfg *Func) const;
212
213 static bool classof(const Operand *Operand) {
214 return Operand->getKind() == kVariable;
215 }
216
217 private:
218 Variable(Type Ty, const CfgNode *Node, SizeT Index, const IceString &Name)
219 : Operand(kVariable, Ty), Number(Index), Name(Name), DefInst(NULL),
220 DefNode(Node), IsArgument(false) {
221 Vars = VarsReal;
222 Vars[0] = this;
223 NumVars = 1;
224 }
225 Variable(const Variable &) LLVM_DELETED_FUNCTION;
226 Variable &operator=(const Variable &) LLVM_DELETED_FUNCTION;
227 virtual ~Variable() {}
228 // Number is unique across all variables, and is used as a
229 // (bit)vector index for liveness analysis.
230 const SizeT Number;
231 // Name is optional.
232 const IceString Name;
233 // DefInst is the instruction that produces this variable as its
234 // dest.
235 Inst *DefInst;
236 // DefNode is the node where this variable was produced, and is
237 // reset to NULL if it is used outside that node. This is used for
238 // detecting isMultiblockLife(). TODO: Collapse this to a single
239 // bit and use a separate pass to calculate the values across the
240 // Cfg. This saves space in the Variable, and removes the fragility
241 // of incrementally computing and maintaining the information.
242 const CfgNode *DefNode;
243 bool IsArgument;
244 // VarsReal (and Operand::Vars) are set up such that Vars[0] ==
245 // this.
246 Variable *VarsReal[1];
247 };
248
249 } // end of namespace Ice
250
251 #endif // SUBZERO_SRC_ICEOPERAND_H
OLDNEW
« 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