OLD | NEW |
1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// | 1 //===- subzero/src/IceOperand.h - High-level operands -----------*- C++ -*-===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file declares the Operand class and its target-independent | 10 // This file declares the Operand class and its target-independent |
11 // subclasses. The main classes are Variable, which represents an | 11 // subclasses. The main classes are Variable, which represents an |
12 // LLVM variable that is either register- or stack-allocated, and the | 12 // LLVM variable that is either register- or stack-allocated, and the |
13 // Constant hierarchy, which represents integer, floating-point, | 13 // Constant hierarchy, which represents integer, floating-point, |
14 // and/or symbolic constants. | 14 // and/or symbolic constants. |
15 // | 15 // |
16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
17 | 17 |
18 #ifndef SUBZERO_SRC_ICEOPERAND_H | 18 #ifndef SUBZERO_SRC_ICEOPERAND_H |
19 #define SUBZERO_SRC_ICEOPERAND_H | 19 #define SUBZERO_SRC_ICEOPERAND_H |
20 | 20 |
21 #include "IceCfg.h" | 21 #include "IceCfg.h" |
22 #include "IceDefs.h" | 22 #include "IceDefs.h" |
23 #include "IceGlobalContext.h" | 23 #include "IceGlobalContext.h" |
24 #include "IceTypes.h" | 24 #include "IceTypes.h" |
25 | 25 |
26 namespace Ice { | 26 namespace Ice { |
27 | 27 |
28 class Operand { | 28 class Operand { |
| 29 Operand(const Operand &) = delete; |
| 30 Operand &operator=(const Operand &) = delete; |
| 31 |
29 public: | 32 public: |
30 static const size_t MaxTargetKinds = 10; | 33 static const size_t MaxTargetKinds = 10; |
31 enum OperandKind { | 34 enum OperandKind { |
32 kConst_Base, | 35 kConst_Base, |
33 kConstInteger32, | 36 kConstInteger32, |
34 kConstInteger64, | 37 kConstInteger64, |
35 kConstFloat, | 38 kConstFloat, |
36 kConstDouble, | 39 kConstDouble, |
37 kConstRelocatable, | 40 kConstRelocatable, |
38 kConstUndef, | 41 kConstUndef, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 protected: | 82 protected: |
80 Operand(OperandKind Kind, Type Ty) | 83 Operand(OperandKind Kind, Type Ty) |
81 : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {} | 84 : Ty(Ty), Kind(Kind), NumVars(0), Vars(NULL) {} |
82 Operand(Operand &&O) = default; | 85 Operand(Operand &&O) = default; |
83 | 86 |
84 const Type Ty; | 87 const Type Ty; |
85 const OperandKind Kind; | 88 const OperandKind Kind; |
86 // Vars and NumVars are initialized by the derived class. | 89 // Vars and NumVars are initialized by the derived class. |
87 SizeT NumVars; | 90 SizeT NumVars; |
88 Variable **Vars; | 91 Variable **Vars; |
89 | |
90 private: | |
91 Operand(const Operand &) = delete; | |
92 Operand &operator=(const Operand &) = delete; | |
93 }; | 92 }; |
94 | 93 |
95 template<class StreamType> | 94 template<class StreamType> |
96 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { | 95 inline StreamType &operator<<(StreamType &Str, const Operand &Op) { |
97 Op.dump(Str); | 96 Op.dump(Str); |
98 return Str; | 97 return Str; |
99 } | 98 } |
100 | 99 |
101 // Constant is the abstract base class for constants. All | 100 // Constant is the abstract base class for constants. All |
102 // constants are allocated from a global arena and are pooled. | 101 // constants are allocated from a global arena and are pooled. |
103 class Constant : public Operand { | 102 class Constant : public Operand { |
| 103 Constant(const Constant &) = delete; |
| 104 Constant &operator=(const Constant &) = delete; |
| 105 |
104 public: | 106 public: |
105 uint32_t getPoolEntryID() const { return PoolEntryID; } | 107 uint32_t getPoolEntryID() const { return PoolEntryID; } |
106 using Operand::dump; | 108 using Operand::dump; |
107 void emit(const Cfg *Func) const override { emit(Func->getContext()); } | 109 void emit(const Cfg *Func) const override { emit(Func->getContext()); } |
108 virtual void emit(GlobalContext *Ctx) const = 0; | 110 virtual void emit(GlobalContext *Ctx) const = 0; |
109 void dump(const Cfg *Func, Ostream &Str) const = 0; | 111 void dump(const Cfg *Func, Ostream &Str) const = 0; |
110 | 112 |
111 static bool classof(const Operand *Operand) { | 113 static bool classof(const Operand *Operand) { |
112 OperandKind Kind = Operand->getKind(); | 114 OperandKind Kind = Operand->getKind(); |
113 return Kind >= kConst_Base && Kind <= kConst_Num; | 115 return Kind >= kConst_Base && Kind <= kConst_Num; |
114 } | 116 } |
115 | 117 |
116 protected: | 118 protected: |
117 Constant(OperandKind Kind, Type Ty, uint32_t PoolEntryID) | 119 Constant(OperandKind Kind, Type Ty, uint32_t PoolEntryID) |
118 : Operand(Kind, Ty), PoolEntryID(PoolEntryID) { | 120 : Operand(Kind, Ty), PoolEntryID(PoolEntryID) { |
119 Vars = NULL; | 121 Vars = NULL; |
120 NumVars = 0; | 122 NumVars = 0; |
121 } | 123 } |
122 ~Constant() override {} | 124 ~Constant() override {} |
123 // PoolEntryID is an integer that uniquely identifies the constant | 125 // PoolEntryID is an integer that uniquely identifies the constant |
124 // within its constant pool. It is used for building the constant | 126 // within its constant pool. It is used for building the constant |
125 // pool in the object code and for referencing its entries. | 127 // pool in the object code and for referencing its entries. |
126 const uint32_t PoolEntryID; | 128 const uint32_t PoolEntryID; |
127 | |
128 private: | |
129 Constant(const Constant &) = delete; | |
130 Constant &operator=(const Constant &) = delete; | |
131 }; | 129 }; |
132 | 130 |
133 // ConstantPrimitive<> wraps a primitive type. | 131 // ConstantPrimitive<> wraps a primitive type. |
134 template <typename T, Operand::OperandKind K> | 132 template <typename T, Operand::OperandKind K> |
135 class ConstantPrimitive : public Constant { | 133 class ConstantPrimitive : public Constant { |
| 134 ConstantPrimitive(const ConstantPrimitive &) = delete; |
| 135 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; |
| 136 |
136 public: | 137 public: |
137 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, T Value, | 138 static ConstantPrimitive *create(GlobalContext *Ctx, Type Ty, T Value, |
138 uint32_t PoolEntryID) { | 139 uint32_t PoolEntryID) { |
139 return new (Ctx->allocate<ConstantPrimitive>()) | 140 return new (Ctx->allocate<ConstantPrimitive>()) |
140 ConstantPrimitive(Ty, Value, PoolEntryID); | 141 ConstantPrimitive(Ty, Value, PoolEntryID); |
141 } | 142 } |
142 T getValue() const { return Value; } | 143 T getValue() const { return Value; } |
143 using Constant::emit; | 144 using Constant::emit; |
144 // The target needs to implement this for each ConstantPrimitive | 145 // The target needs to implement this for each ConstantPrimitive |
145 // specialization. | 146 // specialization. |
146 void emit(GlobalContext *Ctx) const override; | 147 void emit(GlobalContext *Ctx) const override; |
147 using Constant::dump; | 148 using Constant::dump; |
148 void dump(const Cfg *, Ostream &Str) const override { Str << getValue(); } | 149 void dump(const Cfg *, Ostream &Str) const override { Str << getValue(); } |
149 | 150 |
150 static bool classof(const Operand *Operand) { | 151 static bool classof(const Operand *Operand) { |
151 return Operand->getKind() == K; | 152 return Operand->getKind() == K; |
152 } | 153 } |
153 | 154 |
154 private: | 155 private: |
155 ConstantPrimitive(Type Ty, T Value, uint32_t PoolEntryID) | 156 ConstantPrimitive(Type Ty, T Value, uint32_t PoolEntryID) |
156 : Constant(K, Ty, PoolEntryID), Value(Value) {} | 157 : Constant(K, Ty, PoolEntryID), Value(Value) {} |
157 ConstantPrimitive(const ConstantPrimitive &) = delete; | |
158 ConstantPrimitive &operator=(const ConstantPrimitive &) = delete; | |
159 ~ConstantPrimitive() override {} | 158 ~ConstantPrimitive() override {} |
160 const T Value; | 159 const T Value; |
161 }; | 160 }; |
162 | 161 |
163 typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32; | 162 typedef ConstantPrimitive<uint32_t, Operand::kConstInteger32> ConstantInteger32; |
164 typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64; | 163 typedef ConstantPrimitive<uint64_t, Operand::kConstInteger64> ConstantInteger64; |
165 typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat; | 164 typedef ConstantPrimitive<float, Operand::kConstFloat> ConstantFloat; |
166 typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble; | 165 typedef ConstantPrimitive<double, Operand::kConstDouble> ConstantDouble; |
167 | 166 |
168 template <> inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const
{ | 167 template <> inline void ConstantInteger32::dump(const Cfg *, Ostream &Str) const
{ |
169 if (getType() == IceType_i1) | 168 if (getType() == IceType_i1) |
170 Str << (getValue() ? "true" : "false"); | 169 Str << (getValue() ? "true" : "false"); |
171 else | 170 else |
172 Str << static_cast<int32_t>(getValue()); | 171 Str << static_cast<int32_t>(getValue()); |
173 } | 172 } |
174 | 173 |
175 template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const
{ | 174 template <> inline void ConstantInteger64::dump(const Cfg *, Ostream &Str) const
{ |
176 assert(getType() == IceType_i64); | 175 assert(getType() == IceType_i64); |
177 Str << static_cast<int64_t>(getValue()); | 176 Str << static_cast<int64_t>(getValue()); |
178 } | 177 } |
179 | 178 |
180 // RelocatableTuple bundles the parameters that are used to | 179 // RelocatableTuple bundles the parameters that are used to |
181 // construct an ConstantRelocatable. It is done this way so that | 180 // construct an ConstantRelocatable. It is done this way so that |
182 // ConstantRelocatable can fit into the global constant pool | 181 // ConstantRelocatable can fit into the global constant pool |
183 // template mechanism. | 182 // template mechanism. |
184 class RelocatableTuple { | 183 class RelocatableTuple { |
| 184 // RelocatableTuple(const RelocatableTuple &) = delete; |
185 RelocatableTuple &operator=(const RelocatableTuple &) = delete; | 185 RelocatableTuple &operator=(const RelocatableTuple &) = delete; |
186 | 186 |
187 public: | 187 public: |
188 RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, | 188 RelocatableTuple(const RelocOffsetT Offset, const IceString &Name, |
189 bool SuppressMangling) | 189 bool SuppressMangling) |
190 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} | 190 : Offset(Offset), Name(Name), SuppressMangling(SuppressMangling) {} |
191 RelocatableTuple(const RelocatableTuple &Other) | |
192 : Offset(Other.Offset), Name(Other.Name), | |
193 SuppressMangling(Other.SuppressMangling) {} | |
194 | 191 |
195 const RelocOffsetT Offset; | 192 const RelocOffsetT Offset; |
196 const IceString Name; | 193 const IceString Name; |
197 bool SuppressMangling; | 194 bool SuppressMangling; |
198 }; | 195 }; |
199 | 196 |
200 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B); | 197 bool operator<(const RelocatableTuple &A, const RelocatableTuple &B); |
201 | 198 |
202 // ConstantRelocatable represents a symbolic constant combined with | 199 // ConstantRelocatable represents a symbolic constant combined with |
203 // a fixed offset. | 200 // a fixed offset. |
204 class ConstantRelocatable : public Constant { | 201 class ConstantRelocatable : public Constant { |
| 202 ConstantRelocatable(const ConstantRelocatable &) = delete; |
| 203 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; |
| 204 |
205 public: | 205 public: |
206 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, | 206 static ConstantRelocatable *create(GlobalContext *Ctx, Type Ty, |
207 const RelocatableTuple &Tuple, | 207 const RelocatableTuple &Tuple, |
208 uint32_t PoolEntryID) { | 208 uint32_t PoolEntryID) { |
209 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( | 209 return new (Ctx->allocate<ConstantRelocatable>()) ConstantRelocatable( |
210 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling, PoolEntryID); | 210 Ty, Tuple.Offset, Tuple.Name, Tuple.SuppressMangling, PoolEntryID); |
211 } | 211 } |
212 | 212 |
213 RelocOffsetT getOffset() const { return Offset; } | 213 RelocOffsetT getOffset() const { return Offset; } |
214 IceString getName() const { return Name; } | 214 IceString getName() const { return Name; } |
215 void setSuppressMangling(bool Value) { SuppressMangling = Value; } | 215 void setSuppressMangling(bool Value) { SuppressMangling = Value; } |
216 bool getSuppressMangling() const { return SuppressMangling; } | 216 bool getSuppressMangling() const { return SuppressMangling; } |
217 using Constant::emit; | 217 using Constant::emit; |
218 using Constant::dump; | 218 using Constant::dump; |
219 void emit(GlobalContext *Ctx) const override; | 219 void emit(GlobalContext *Ctx) const override; |
220 void dump(const Cfg *Func, Ostream &Str) const override; | 220 void dump(const Cfg *Func, Ostream &Str) const override; |
221 | 221 |
222 static bool classof(const Operand *Operand) { | 222 static bool classof(const Operand *Operand) { |
223 OperandKind Kind = Operand->getKind(); | 223 OperandKind Kind = Operand->getKind(); |
224 return Kind == kConstRelocatable; | 224 return Kind == kConstRelocatable; |
225 } | 225 } |
226 | 226 |
227 private: | 227 private: |
228 ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, | 228 ConstantRelocatable(Type Ty, RelocOffsetT Offset, const IceString &Name, |
229 bool SuppressMangling, uint32_t PoolEntryID) | 229 bool SuppressMangling, uint32_t PoolEntryID) |
230 : Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset), | 230 : Constant(kConstRelocatable, Ty, PoolEntryID), Offset(Offset), |
231 Name(Name), SuppressMangling(SuppressMangling) {} | 231 Name(Name), SuppressMangling(SuppressMangling) {} |
232 ConstantRelocatable(const ConstantRelocatable &) = delete; | |
233 ConstantRelocatable &operator=(const ConstantRelocatable &) = delete; | |
234 ~ConstantRelocatable() override {} | 232 ~ConstantRelocatable() override {} |
235 const RelocOffsetT Offset; // fixed offset to add | 233 const RelocOffsetT Offset; // fixed offset to add |
236 const IceString Name; // optional for debug/dump | 234 const IceString Name; // optional for debug/dump |
237 bool SuppressMangling; | 235 bool SuppressMangling; |
238 }; | 236 }; |
239 | 237 |
240 // ConstantUndef represents an unspecified bit pattern. Although it is | 238 // ConstantUndef represents an unspecified bit pattern. Although it is |
241 // legal to lower ConstantUndef to any value, backends should try to | 239 // legal to lower ConstantUndef to any value, backends should try to |
242 // make code generation deterministic by lowering ConstantUndefs to 0. | 240 // make code generation deterministic by lowering ConstantUndefs to 0. |
243 class ConstantUndef : public Constant { | 241 class ConstantUndef : public Constant { |
| 242 ConstantUndef(const ConstantUndef &) = delete; |
| 243 ConstantUndef &operator=(const ConstantUndef &) = delete; |
| 244 |
244 public: | 245 public: |
245 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, | 246 static ConstantUndef *create(GlobalContext *Ctx, Type Ty, |
246 uint32_t PoolEntryID) { | 247 uint32_t PoolEntryID) { |
247 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); | 248 return new (Ctx->allocate<ConstantUndef>()) ConstantUndef(Ty, PoolEntryID); |
248 } | 249 } |
249 | 250 |
250 using Constant::emit; | 251 using Constant::emit; |
251 using Constant::dump; | 252 using Constant::dump; |
252 // The target needs to implement this. | 253 // The target needs to implement this. |
253 void emit(GlobalContext *Ctx) const override; | 254 void emit(GlobalContext *Ctx) const override; |
254 void dump(const Cfg *, Ostream &Str) const override { Str << "undef"; } | 255 void dump(const Cfg *, Ostream &Str) const override { Str << "undef"; } |
255 | 256 |
256 static bool classof(const Operand *Operand) { | 257 static bool classof(const Operand *Operand) { |
257 return Operand->getKind() == kConstUndef; | 258 return Operand->getKind() == kConstUndef; |
258 } | 259 } |
259 | 260 |
260 private: | 261 private: |
261 ConstantUndef(Type Ty, uint32_t PoolEntryID) | 262 ConstantUndef(Type Ty, uint32_t PoolEntryID) |
262 : Constant(kConstUndef, Ty, PoolEntryID) {} | 263 : Constant(kConstUndef, Ty, PoolEntryID) {} |
263 ConstantUndef(const ConstantUndef &) = delete; | |
264 ConstantUndef &operator=(const ConstantUndef &) = delete; | |
265 ~ConstantUndef() override {} | 264 ~ConstantUndef() override {} |
266 }; | 265 }; |
267 | 266 |
268 // RegWeight is a wrapper for a uint32_t weight value, with a | 267 // RegWeight is a wrapper for a uint32_t weight value, with a |
269 // special value that represents infinite weight, and an addWeight() | 268 // special value that represents infinite weight, and an addWeight() |
270 // method that ensures that W+infinity=infinity. | 269 // method that ensures that W+infinity=infinity. |
271 class RegWeight { | 270 class RegWeight { |
| 271 // RegWeight(const RegWeight &) = delete; |
| 272 // RegWeight &operator=(const RegWeight &) = delete; |
| 273 |
272 public: | 274 public: |
273 RegWeight() : Weight(0) {} | 275 RegWeight() : Weight(0) {} |
274 RegWeight(uint32_t Weight) : Weight(Weight) {} | 276 RegWeight(uint32_t Weight) : Weight(Weight) {} |
275 const static uint32_t Inf = ~0; // Force regalloc to give a register | 277 const static uint32_t Inf = ~0; // Force regalloc to give a register |
276 const static uint32_t Zero = 0; // Force regalloc NOT to give a register | 278 const static uint32_t Zero = 0; // Force regalloc NOT to give a register |
277 void addWeight(uint32_t Delta) { | 279 void addWeight(uint32_t Delta) { |
278 if (Delta == Inf) | 280 if (Delta == Inf) |
279 Weight = Inf; | 281 Weight = Inf; |
280 else if (Weight != Inf) | 282 else if (Weight != Inf) |
281 Weight += Delta; | 283 Weight += Delta; |
(...skipping 11 matching lines...) Expand all Loading... |
293 bool operator<=(const RegWeight &A, const RegWeight &B); | 295 bool operator<=(const RegWeight &A, const RegWeight &B); |
294 bool operator==(const RegWeight &A, const RegWeight &B); | 296 bool operator==(const RegWeight &A, const RegWeight &B); |
295 | 297 |
296 // LiveRange is a set of instruction number intervals representing | 298 // LiveRange is a set of instruction number intervals representing |
297 // a variable's live range. Generally there is one interval per basic | 299 // a variable's live range. Generally there is one interval per basic |
298 // block where the variable is live, but adjacent intervals get | 300 // block where the variable is live, but adjacent intervals get |
299 // coalesced into a single interval. LiveRange also includes a | 301 // coalesced into a single interval. LiveRange also includes a |
300 // weight, in case e.g. we want a live range to have higher weight | 302 // weight, in case e.g. we want a live range to have higher weight |
301 // inside a loop. | 303 // inside a loop. |
302 class LiveRange { | 304 class LiveRange { |
| 305 // LiveRange(const LiveRange &) = delete; |
| 306 // LiveRange &operator=(const LiveRange &) = delete; |
| 307 |
303 public: | 308 public: |
304 LiveRange() : Weight(0), IsNonpoints(false) {} | 309 LiveRange() : Weight(0), IsNonpoints(false) {} |
305 | 310 |
306 void reset() { | 311 void reset() { |
307 Range.clear(); | 312 Range.clear(); |
308 Weight.setWeight(0); | 313 Weight.setWeight(0); |
309 untrim(); | 314 untrim(); |
310 IsNonpoints = false; | 315 IsNonpoints = false; |
311 } | 316 } |
312 void addSegment(InstNumberT Start, InstNumberT End); | 317 void addSegment(InstNumberT Start, InstNumberT End); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
509 // VarsReal (and Operand::Vars) are set up such that Vars[0] == | 514 // VarsReal (and Operand::Vars) are set up such that Vars[0] == |
510 // this. | 515 // this. |
511 Variable *VarsReal[1]; | 516 Variable *VarsReal[1]; |
512 }; | 517 }; |
513 | 518 |
514 typedef std::vector<const Inst *> InstDefList; | 519 typedef std::vector<const Inst *> InstDefList; |
515 | 520 |
516 // VariableTracking tracks the metadata for a single variable. It is | 521 // VariableTracking tracks the metadata for a single variable. It is |
517 // only meant to be used internally by VariablesMetadata. | 522 // only meant to be used internally by VariablesMetadata. |
518 class VariableTracking { | 523 class VariableTracking { |
| 524 // VariableTracking(const VariableTracking &) = delete; |
| 525 VariableTracking &operator=(const VariableTracking &) = delete; |
| 526 |
519 public: | 527 public: |
520 enum MultiDefState { | 528 enum MultiDefState { |
521 // TODO(stichnot): Consider using just a simple counter. | 529 // TODO(stichnot): Consider using just a simple counter. |
522 MDS_Unknown, | 530 MDS_Unknown, |
523 MDS_SingleDef, | 531 MDS_SingleDef, |
524 MDS_MultiDefSingleBlock, | 532 MDS_MultiDefSingleBlock, |
525 MDS_MultiDefMultiBlock | 533 MDS_MultiDefMultiBlock |
526 }; | 534 }; |
527 enum MultiBlockState { | 535 enum MultiBlockState { |
528 MBS_Unknown, | 536 MBS_Unknown, |
529 MBS_SingleBlock, | 537 MBS_SingleBlock, |
530 MBS_MultiBlock | 538 MBS_MultiBlock |
531 }; | 539 }; |
532 VariableTracking() | 540 VariableTracking() |
533 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL), | 541 : MultiDef(MDS_Unknown), MultiBlock(MBS_Unknown), SingleUseNode(NULL), |
534 SingleDefNode(NULL) {} | 542 SingleDefNode(NULL) {} |
535 MultiDefState getMultiDef() const { return MultiDef; } | 543 MultiDefState getMultiDef() const { return MultiDef; } |
536 MultiBlockState getMultiBlock() const { return MultiBlock; } | 544 MultiBlockState getMultiBlock() const { return MultiBlock; } |
537 const Inst *getFirstDefinition() const; | 545 const Inst *getFirstDefinition() const; |
538 const Inst *getSingleDefinition() const; | 546 const Inst *getSingleDefinition() const; |
539 const InstDefList &getDefinitions() const { return Definitions; } | 547 const InstDefList &getDefinitions() const { return Definitions; } |
540 const CfgNode *getNode() const { return SingleUseNode; } | 548 const CfgNode *getNode() const { return SingleUseNode; } |
541 void markUse(const Inst *Instr, const CfgNode *Node, bool IsFromDef, | 549 void markUse(const Inst *Instr, const CfgNode *Node, bool IsFromDef, |
542 bool IsImplicit); | 550 bool IsImplicit); |
543 void markDef(const Inst *Instr, const CfgNode *Node); | 551 void markDef(const Inst *Instr, const CfgNode *Node); |
544 | 552 |
545 private: | 553 private: |
546 VariableTracking &operator=(const VariableTracking &) = delete; | |
547 MultiDefState MultiDef; | 554 MultiDefState MultiDef; |
548 MultiBlockState MultiBlock; | 555 MultiBlockState MultiBlock; |
549 const CfgNode *SingleUseNode; | 556 const CfgNode *SingleUseNode; |
550 const CfgNode *SingleDefNode; | 557 const CfgNode *SingleDefNode; |
551 // All definitions of the variable are collected here, in increasing | 558 // All definitions of the variable are collected here, in increasing |
552 // order of instruction number. | 559 // order of instruction number. |
553 InstDefList Definitions; | 560 InstDefList Definitions; |
554 }; | 561 }; |
555 | 562 |
556 // VariablesMetadata analyzes and summarizes the metadata for the | 563 // VariablesMetadata analyzes and summarizes the metadata for the |
557 // complete set of Variables. | 564 // complete set of Variables. |
558 class VariablesMetadata { | 565 class VariablesMetadata { |
| 566 VariablesMetadata(const VariablesMetadata &) = delete; |
| 567 VariablesMetadata &operator=(const VariablesMetadata &) = delete; |
| 568 |
559 public: | 569 public: |
560 VariablesMetadata(const Cfg *Func) : Func(Func) {} | 570 VariablesMetadata(const Cfg *Func) : Func(Func) {} |
561 // Initialize the state by traversing all instructions/variables in | 571 // Initialize the state by traversing all instructions/variables in |
562 // the CFG. | 572 // the CFG. |
563 void init(); | 573 void init(); |
564 // Returns whether the given Variable is tracked in this object. It | 574 // Returns whether the given Variable is tracked in this object. It |
565 // should only return false if changes were made to the CFG after | 575 // should only return false if changes were made to the CFG after |
566 // running init(), in which case the state is stale and the results | 576 // running init(), in which case the state is stale and the results |
567 // shouldn't be trusted (but it may be OK e.g. for dumping). | 577 // shouldn't be trusted (but it may be OK e.g. for dumping). |
568 bool isTracked(const Variable *Var) const { | 578 bool isTracked(const Variable *Var) const { |
(...skipping 26 matching lines...) Expand all Loading... |
595 // entry block. | 605 // entry block. |
596 bool isMultiBlock(const Variable *Var) const; | 606 bool isMultiBlock(const Variable *Var) const; |
597 // Returns the node that the given Variable is used in, assuming | 607 // Returns the node that the given Variable is used in, assuming |
598 // isMultiBlock() returns false. Otherwise, NULL is returned. | 608 // isMultiBlock() returns false. Otherwise, NULL is returned. |
599 const CfgNode *getLocalUseNode(const Variable *Var) const; | 609 const CfgNode *getLocalUseNode(const Variable *Var) const; |
600 | 610 |
601 private: | 611 private: |
602 const Cfg *Func; | 612 const Cfg *Func; |
603 std::vector<VariableTracking> Metadata; | 613 std::vector<VariableTracking> Metadata; |
604 const static InstDefList NoDefinitions; | 614 const static InstDefList NoDefinitions; |
605 VariablesMetadata(const VariablesMetadata &) = delete; | |
606 VariablesMetadata &operator=(const VariablesMetadata &) = delete; | |
607 }; | 615 }; |
608 | 616 |
609 } // end of namespace Ice | 617 } // end of namespace Ice |
610 | 618 |
611 #endif // SUBZERO_SRC_ICEOPERAND_H | 619 #endif // SUBZERO_SRC_ICEOPERAND_H |
OLD | NEW |