OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 // | 46 // |
47 // Values of CompileType form a lattice with a None type as a bottom and a | 47 // Values of CompileType form a lattice with a None type as a bottom and a |
48 // nullable Dynamic type as a top element. Method Union provides a join | 48 // nullable Dynamic type as a top element. Method Union provides a join |
49 // operation for the lattice. | 49 // operation for the lattice. |
50 class CompileType : public ValueObject { | 50 class CompileType : public ValueObject { |
51 public: | 51 public: |
52 static const bool kNullable = true; | 52 static const bool kNullable = true; |
53 static const bool kNonNullable = false; | 53 static const bool kNonNullable = false; |
54 | 54 |
55 CompileType(bool is_nullable, intptr_t cid, const AbstractType* type) | 55 CompileType(bool is_nullable, intptr_t cid, const AbstractType* type) |
56 : is_nullable_(is_nullable), cid_(cid), type_(type) { } | 56 : is_nullable_(is_nullable), cid_(cid), type_(type) {} |
57 | 57 |
58 CompileType(const CompileType& other) | 58 CompileType(const CompileType& other) |
59 : ValueObject(), | 59 : ValueObject(), |
60 is_nullable_(other.is_nullable_), | 60 is_nullable_(other.is_nullable_), |
61 cid_(other.cid_), | 61 cid_(other.cid_), |
62 type_(other.type_) { } | 62 type_(other.type_) {} |
63 | 63 |
64 CompileType& operator=(const CompileType& other) { | 64 CompileType& operator=(const CompileType& other) { |
65 is_nullable_ = other.is_nullable_; | 65 is_nullable_ = other.is_nullable_; |
66 cid_ = other.cid_; | 66 cid_ = other.cid_; |
67 type_ = other.type_; | 67 type_ = other.type_; |
68 return *this; | 68 return *this; |
69 } | 69 } |
70 | 70 |
71 bool is_nullable() const { return is_nullable_; } | 71 bool is_nullable() const { return is_nullable_; } |
72 | 72 |
73 // Return type such that concrete value's type in runtime is guaranteed to | 73 // Return type such that concrete value's type in runtime is guaranteed to |
74 // be subtype of it. | 74 // be subtype of it. |
75 const AbstractType* ToAbstractType(); | 75 const AbstractType* ToAbstractType(); |
76 | 76 |
77 // Return class id such that it is either kDynamicCid or in runtime | 77 // Return class id such that it is either kDynamicCid or in runtime |
(...skipping 11 matching lines...) Expand all Loading... |
89 // Returns true if the value is known to be always null. | 89 // Returns true if the value is known to be always null. |
90 bool IsNull(); | 90 bool IsNull(); |
91 | 91 |
92 // Returns true if this type is more specific than given type. | 92 // Returns true if this type is more specific than given type. |
93 bool IsMoreSpecificThan(const AbstractType& other); | 93 bool IsMoreSpecificThan(const AbstractType& other); |
94 | 94 |
95 // Returns true if value of this type is assignable to a location of the | 95 // Returns true if value of this type is assignable to a location of the |
96 // given type. | 96 // given type. |
97 bool IsAssignableTo(const AbstractType& type) { | 97 bool IsAssignableTo(const AbstractType& type) { |
98 bool is_instance; | 98 bool is_instance; |
99 return CanComputeIsInstanceOf(type, kNullable, &is_instance) && | 99 return CanComputeIsInstanceOf(type, kNullable, &is_instance) && is_instance; |
100 is_instance; | |
101 } | 100 } |
102 | 101 |
103 // Create a new CompileType representing given combination of class id and | 102 // Create a new CompileType representing given combination of class id and |
104 // abstract type. The pair is assumed to be coherent. | 103 // abstract type. The pair is assumed to be coherent. |
105 static CompileType Create(intptr_t cid, const AbstractType& type); | 104 static CompileType Create(intptr_t cid, const AbstractType& type); |
106 | 105 |
107 CompileType CopyNonNullable() const { | 106 CompileType CopyNonNullable() const { |
108 return CompileType(kNonNullable, cid_, type_); | 107 return CompileType(kNonNullable, cid_, type_); |
109 } | 108 } |
110 | 109 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 | 143 |
145 // Create non-nullable String type. | 144 // Create non-nullable String type. |
146 static CompileType String(); | 145 static CompileType String(); |
147 | 146 |
148 // Perform a join operation over the type lattice. | 147 // Perform a join operation over the type lattice. |
149 void Union(CompileType* other); | 148 void Union(CompileType* other); |
150 | 149 |
151 // Returns true if this and other types are the same. | 150 // Returns true if this and other types are the same. |
152 bool IsEqualTo(CompileType* other) { | 151 bool IsEqualTo(CompileType* other) { |
153 return (is_nullable_ == other->is_nullable_) && | 152 return (is_nullable_ == other->is_nullable_) && |
154 (ToNullableCid() == other->ToNullableCid()) && | 153 (ToNullableCid() == other->ToNullableCid()) && |
155 (ToAbstractType()->Equals(*other->ToAbstractType())); | 154 (ToAbstractType()->Equals(*other->ToAbstractType())); |
156 } | 155 } |
157 | 156 |
158 bool IsNone() const { | 157 bool IsNone() const { return (cid_ == kIllegalCid) && (type_ == NULL); } |
159 return (cid_ == kIllegalCid) && (type_ == NULL); | |
160 } | |
161 | 158 |
162 bool IsInt() { | 159 bool IsInt() { |
163 return !is_nullable() && | 160 return !is_nullable() && ((ToCid() == kSmiCid) || (ToCid() == kMintCid) || |
164 ((ToCid() == kSmiCid) || | 161 ((type_ != NULL) && |
165 (ToCid() == kMintCid) || | 162 (type_->Equals(Type::Handle(Type::IntType()))))); |
166 ((type_ != NULL) && (type_->Equals(Type::Handle(Type::IntType()))))); | |
167 } | 163 } |
168 | 164 |
169 void PrintTo(BufferFormatter* f) const; | 165 void PrintTo(BufferFormatter* f) const; |
170 const char* ToCString() const; | 166 const char* ToCString() const; |
171 | 167 |
172 private: | 168 private: |
173 bool CanComputeIsInstanceOf(const AbstractType& type, | 169 bool CanComputeIsInstanceOf(const AbstractType& type, |
174 bool is_nullable, | 170 bool is_nullable, |
175 bool* is_instance); | 171 bool* is_instance); |
176 | 172 |
177 bool is_nullable_; | 173 bool is_nullable_; |
178 intptr_t cid_; | 174 intptr_t cid_; |
179 const AbstractType* type_; | 175 const AbstractType* type_; |
180 }; | 176 }; |
181 | 177 |
182 | 178 |
183 // Zone allocated wrapper for the CompileType value. | 179 // Zone allocated wrapper for the CompileType value. |
184 class ZoneCompileType : public ZoneAllocated { | 180 class ZoneCompileType : public ZoneAllocated { |
185 public: | 181 public: |
186 static CompileType* Wrap(const CompileType& type) { | 182 static CompileType* Wrap(const CompileType& type) { |
187 ZoneCompileType* zone_type = new ZoneCompileType(type); | 183 ZoneCompileType* zone_type = new ZoneCompileType(type); |
188 return zone_type->ToCompileType(); | 184 return zone_type->ToCompileType(); |
189 } | 185 } |
190 | 186 |
191 CompileType* ToCompileType() { | 187 CompileType* ToCompileType() { return &type_; } |
192 return &type_; | |
193 } | |
194 | 188 |
195 protected: | 189 protected: |
196 explicit ZoneCompileType(const CompileType& type) : type_(type) { } | 190 explicit ZoneCompileType(const CompileType& type) : type_(type) {} |
197 | 191 |
198 CompileType type_; | 192 CompileType type_; |
199 }; | 193 }; |
200 | 194 |
201 | 195 |
202 // ConstrainedCompileType represents a compile type that is computed from | 196 // ConstrainedCompileType represents a compile type that is computed from |
203 // another compile type. | 197 // another compile type. |
204 class ConstrainedCompileType : public ZoneCompileType { | 198 class ConstrainedCompileType : public ZoneCompileType { |
205 public: | 199 public: |
206 virtual ~ConstrainedCompileType() { } | 200 virtual ~ConstrainedCompileType() {} |
207 | 201 |
208 // Recompute compile type. | 202 // Recompute compile type. |
209 virtual void Update() = 0; | 203 virtual void Update() = 0; |
210 | 204 |
211 protected: | 205 protected: |
212 explicit ConstrainedCompileType(const CompileType& type) | 206 explicit ConstrainedCompileType(const CompileType& type) |
213 : ZoneCompileType(type) { } | 207 : ZoneCompileType(type) {} |
214 }; | 208 }; |
215 | 209 |
216 | 210 |
217 // NotNullConstrainedCompileType represents not-null constraint applied to | 211 // NotNullConstrainedCompileType represents not-null constraint applied to |
218 // the source compile type. Result is non-nullable version of the incoming | 212 // the source compile type. Result is non-nullable version of the incoming |
219 // compile type. It is used to represent compile type propagated downwards | 213 // compile type. It is used to represent compile type propagated downwards |
220 // from strict comparison with the null constant. | 214 // from strict comparison with the null constant. |
221 class NotNullConstrainedCompileType : public ConstrainedCompileType { | 215 class NotNullConstrainedCompileType : public ConstrainedCompileType { |
222 public: | 216 public: |
223 explicit NotNullConstrainedCompileType(CompileType* source) | 217 explicit NotNullConstrainedCompileType(CompileType* source) |
224 : ConstrainedCompileType(source->CopyNonNullable()), source_(source) { } | 218 : ConstrainedCompileType(source->CopyNonNullable()), source_(source) {} |
225 | 219 |
226 virtual void Update() { | 220 virtual void Update() { type_ = source_->CopyNonNullable(); } |
227 type_ = source_->CopyNonNullable(); | |
228 } | |
229 | 221 |
230 private: | 222 private: |
231 CompileType* source_; | 223 CompileType* source_; |
232 }; | 224 }; |
233 | 225 |
234 | 226 |
235 class EffectSet : public ValueObject { | 227 class EffectSet : public ValueObject { |
236 public: | 228 public: |
237 enum Effects { | 229 enum Effects { |
238 kNoEffects = 0, | 230 kNoEffects = 0, |
239 kExternalization = 1, | 231 kExternalization = 1, |
240 kLastEffect = kExternalization | 232 kLastEffect = kExternalization |
241 }; | 233 }; |
242 | 234 |
243 EffectSet(const EffectSet& other) | 235 EffectSet(const EffectSet& other) : ValueObject(), effects_(other.effects_) {} |
244 : ValueObject(), effects_(other.effects_) { | |
245 } | |
246 | 236 |
247 bool IsNone() const { return effects_ == kNoEffects; } | 237 bool IsNone() const { return effects_ == kNoEffects; } |
248 | 238 |
249 static EffectSet None() { return EffectSet(kNoEffects); } | 239 static EffectSet None() { return EffectSet(kNoEffects); } |
250 static EffectSet All() { | 240 static EffectSet All() { |
251 ASSERT(EffectSet::kLastEffect == 1); | 241 ASSERT(EffectSet::kLastEffect == 1); |
252 return EffectSet(kExternalization); | 242 return EffectSet(kExternalization); |
253 } | 243 } |
254 | 244 |
255 static EffectSet Externalization() { | 245 static EffectSet Externalization() { return EffectSet(kExternalization); } |
256 return EffectSet(kExternalization); | |
257 } | |
258 | 246 |
259 bool ToInt() { return effects_; } | 247 bool ToInt() { return effects_; } |
260 | 248 |
261 private: | 249 private: |
262 explicit EffectSet(intptr_t effects) : effects_(effects) { } | 250 explicit EffectSet(intptr_t effects) : effects_(effects) {} |
263 | 251 |
264 intptr_t effects_; | 252 intptr_t effects_; |
265 }; | 253 }; |
266 | 254 |
267 | 255 |
268 class Value : public ZoneAllocated { | 256 class Value : public ZoneAllocated { |
269 public: | 257 public: |
270 // A forward iterator that allows removing the current value from the | 258 // A forward iterator that allows removing the current value from the |
271 // underlying use list during iteration. | 259 // underlying use list during iteration. |
272 class Iterator { | 260 class Iterator { |
273 public: | 261 public: |
274 explicit Iterator(Value* head) : next_(head) { Advance(); } | 262 explicit Iterator(Value* head) : next_(head) { Advance(); } |
275 Value* Current() const { return current_; } | 263 Value* Current() const { return current_; } |
276 bool Done() const { return current_ == NULL; } | 264 bool Done() const { return current_ == NULL; } |
277 void Advance() { | 265 void Advance() { |
278 // Pre-fetch next on advance and cache it. | 266 // Pre-fetch next on advance and cache it. |
279 current_ = next_; | 267 current_ = next_; |
280 if (next_ != NULL) next_ = next_->next_use(); | 268 if (next_ != NULL) next_ = next_->next_use(); |
281 } | 269 } |
| 270 |
282 private: | 271 private: |
283 Value* current_; | 272 Value* current_; |
284 Value* next_; | 273 Value* next_; |
285 }; | 274 }; |
286 | 275 |
287 explicit Value(Definition* definition) | 276 explicit Value(Definition* definition) |
288 : definition_(definition), | 277 : definition_(definition), |
289 previous_use_(NULL), | 278 previous_use_(NULL), |
290 next_use_(NULL), | 279 next_use_(NULL), |
291 instruction_(NULL), | 280 instruction_(NULL), |
292 use_index_(-1), | 281 use_index_(-1), |
293 reaching_type_(NULL) { } | 282 reaching_type_(NULL) {} |
294 | 283 |
295 Definition* definition() const { return definition_; } | 284 Definition* definition() const { return definition_; } |
296 void set_definition(Definition* definition) { definition_ = definition; } | 285 void set_definition(Definition* definition) { definition_ = definition; } |
297 | 286 |
298 Value* previous_use() const { return previous_use_; } | 287 Value* previous_use() const { return previous_use_; } |
299 void set_previous_use(Value* previous) { previous_use_ = previous; } | 288 void set_previous_use(Value* previous) { previous_use_ = previous; } |
300 | 289 |
301 Value* next_use() const { return next_use_; } | 290 Value* next_use() const { return next_use_; } |
302 void set_next_use(Value* next) { next_use_ = next; } | 291 void set_next_use(Value* next) { next_use_ = next; } |
303 | 292 |
304 bool IsSingleUse() const { | 293 bool IsSingleUse() const { |
305 return (next_use_ == NULL) && (previous_use_ == NULL); | 294 return (next_use_ == NULL) && (previous_use_ == NULL); |
306 } | 295 } |
307 | 296 |
308 Instruction* instruction() const { return instruction_; } | 297 Instruction* instruction() const { return instruction_; } |
309 void set_instruction(Instruction* instruction) { instruction_ = instruction; } | 298 void set_instruction(Instruction* instruction) { instruction_ = instruction; } |
310 | 299 |
311 intptr_t use_index() const { return use_index_; } | 300 intptr_t use_index() const { return use_index_; } |
312 void set_use_index(intptr_t index) { use_index_ = index; } | 301 void set_use_index(intptr_t index) { use_index_ = index; } |
313 | 302 |
314 static void AddToList(Value* value, Value** list); | 303 static void AddToList(Value* value, Value** list); |
315 void RemoveFromUseList(); | 304 void RemoveFromUseList(); |
316 | 305 |
317 // Change the definition after use lists have been computed. | 306 // Change the definition after use lists have been computed. |
318 inline void BindTo(Definition* definition); | 307 inline void BindTo(Definition* definition); |
319 inline void BindToEnvironment(Definition* definition); | 308 inline void BindToEnvironment(Definition* definition); |
320 | 309 |
321 Value* Copy(Zone* zone) { return new(zone) Value(definition_); } | 310 Value* Copy(Zone* zone) { return new (zone) Value(definition_); } |
322 | 311 |
323 // This function must only be used when the new Value is dominated by | 312 // This function must only be used when the new Value is dominated by |
324 // the original Value. | 313 // the original Value. |
325 Value* CopyWithType() { | 314 Value* CopyWithType() { |
326 Value* copy = new Value(definition_); | 315 Value* copy = new Value(definition_); |
327 copy->reaching_type_ = reaching_type_; | 316 copy->reaching_type_ = reaching_type_; |
328 return copy; | 317 return copy; |
329 } | 318 } |
330 | 319 |
331 CompileType* Type(); | 320 CompileType* Type(); |
332 | 321 |
333 void SetReachingType(CompileType* type) { | 322 void SetReachingType(CompileType* type) { reaching_type_ = type; } |
334 reaching_type_ = type; | |
335 } | |
336 | 323 |
337 void PrintTo(BufferFormatter* f) const; | 324 void PrintTo(BufferFormatter* f) const; |
338 | 325 |
339 const char* ToCString() const; | 326 const char* ToCString() const; |
340 | 327 |
341 bool IsSmiValue() { return Type()->ToCid() == kSmiCid; } | 328 bool IsSmiValue() { return Type()->ToCid() == kSmiCid; } |
342 | 329 |
343 // Return true if the value represents a constant. | 330 // Return true if the value represents a constant. |
344 bool BindsToConstant() const; | 331 bool BindsToConstant() const; |
345 | 332 |
(...skipping 19 matching lines...) Expand all Loading... |
365 intptr_t use_index_; | 352 intptr_t use_index_; |
366 | 353 |
367 CompileType* reaching_type_; | 354 CompileType* reaching_type_; |
368 | 355 |
369 DISALLOW_COPY_AND_ASSIGN(Value); | 356 DISALLOW_COPY_AND_ASSIGN(Value); |
370 }; | 357 }; |
371 | 358 |
372 | 359 |
373 // An embedded container with N elements of type T. Used (with partial | 360 // An embedded container with N elements of type T. Used (with partial |
374 // specialization for N=0) because embedded arrays cannot have size 0. | 361 // specialization for N=0) because embedded arrays cannot have size 0. |
375 template<typename T, intptr_t N> | 362 template <typename T, intptr_t N> |
376 class EmbeddedArray { | 363 class EmbeddedArray { |
377 public: | 364 public: |
378 EmbeddedArray() : elements_() { } | 365 EmbeddedArray() : elements_() {} |
379 | 366 |
380 intptr_t length() const { return N; } | 367 intptr_t length() const { return N; } |
381 | 368 |
382 const T& operator[](intptr_t i) const { | 369 const T& operator[](intptr_t i) const { |
383 ASSERT(i < length()); | 370 ASSERT(i < length()); |
384 return elements_[i]; | 371 return elements_[i]; |
385 } | 372 } |
386 | 373 |
387 T& operator[](intptr_t i) { | 374 T& operator[](intptr_t i) { |
388 ASSERT(i < length()); | 375 ASSERT(i < length()); |
389 return elements_[i]; | 376 return elements_[i]; |
390 } | 377 } |
391 | 378 |
392 const T& At(intptr_t i) const { | 379 const T& At(intptr_t i) const { return (*this)[i]; } |
393 return (*this)[i]; | |
394 } | |
395 | 380 |
396 void SetAt(intptr_t i, const T& val) { | 381 void SetAt(intptr_t i, const T& val) { (*this)[i] = val; } |
397 (*this)[i] = val; | |
398 } | |
399 | 382 |
400 private: | 383 private: |
401 T elements_[N]; | 384 T elements_[N]; |
402 }; | 385 }; |
403 | 386 |
404 | 387 |
405 template<typename T> | 388 template <typename T> |
406 class EmbeddedArray<T, 0> { | 389 class EmbeddedArray<T, 0> { |
407 public: | 390 public: |
408 intptr_t length() const { return 0; } | 391 intptr_t length() const { return 0; } |
409 const T& operator[](intptr_t i) const { | 392 const T& operator[](intptr_t i) const { |
410 UNREACHABLE(); | 393 UNREACHABLE(); |
411 static T sentinel = 0; | 394 static T sentinel = 0; |
412 return sentinel; | 395 return sentinel; |
413 } | 396 } |
414 T& operator[](intptr_t i) { | 397 T& operator[](intptr_t i) { |
415 UNREACHABLE(); | 398 UNREACHABLE(); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 M(UnboxedIntConverter) \ | 548 M(UnboxedIntConverter) \ |
566 M(GrowRegExpStack) \ | 549 M(GrowRegExpStack) \ |
567 M(Deoptimize) | 550 M(Deoptimize) |
568 | 551 |
569 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ | 552 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ |
570 M(BlockEntry) \ | 553 M(BlockEntry) \ |
571 M(BoxInteger) \ | 554 M(BoxInteger) \ |
572 M(UnboxInteger) \ | 555 M(UnboxInteger) \ |
573 M(Comparison) \ | 556 M(Comparison) \ |
574 M(UnaryIntegerOp) \ | 557 M(UnaryIntegerOp) \ |
575 M(BinaryIntegerOp) \ | 558 M(BinaryIntegerOp) |
576 | 559 |
577 #define FORWARD_DECLARATION(type) class type##Instr; | 560 #define FORWARD_DECLARATION(type) class type##Instr; |
578 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 561 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
579 FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION) | 562 FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION) |
580 #undef FORWARD_DECLARATION | 563 #undef FORWARD_DECLARATION |
581 | 564 |
582 #define DEFINE_INSTRUCTION_TYPE_CHECK(type) \ | 565 #define DEFINE_INSTRUCTION_TYPE_CHECK(type) \ |
583 virtual type##Instr* As##type() { return this; } \ | 566 virtual type##Instr* As##type() { return this; } \ |
584 virtual const char* DebugName() const { return #type; } \ | 567 virtual const char* DebugName() const { return #type; } |
585 | 568 |
586 // Functions required in all concrete instruction classes. | 569 // Functions required in all concrete instruction classes. |
587 #define DECLARE_INSTRUCTION_NO_BACKEND(type) \ | 570 #define DECLARE_INSTRUCTION_NO_BACKEND(type) \ |
588 virtual Tag tag() const { return k##type; } \ | 571 virtual Tag tag() const { return k##type; } \ |
589 virtual void Accept(FlowGraphVisitor* visitor); \ | 572 virtual void Accept(FlowGraphVisitor* visitor); \ |
590 DEFINE_INSTRUCTION_TYPE_CHECK(type) | 573 DEFINE_INSTRUCTION_TYPE_CHECK(type) |
591 | 574 |
592 #define DECLARE_INSTRUCTION_BACKEND() \ | 575 #define DECLARE_INSTRUCTION_BACKEND() \ |
593 virtual LocationSummary* MakeLocationSummary(Zone* zone, \ | 576 virtual LocationSummary* MakeLocationSummary(Zone* zone, bool optimizing) \ |
594 bool optimizing) const; \ | 577 const; \ |
595 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ | 578 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
596 | 579 |
597 // Functions required in all concrete instruction classes. | 580 // Functions required in all concrete instruction classes. |
598 #define DECLARE_INSTRUCTION(type) \ | 581 #define DECLARE_INSTRUCTION(type) \ |
599 DECLARE_INSTRUCTION_NO_BACKEND(type) \ | 582 DECLARE_INSTRUCTION_NO_BACKEND(type) \ |
600 DECLARE_INSTRUCTION_BACKEND() \ | 583 DECLARE_INSTRUCTION_BACKEND() |
601 | 584 |
602 #ifndef PRODUCT | 585 #ifndef PRODUCT |
603 #define PRINT_TO_SUPPORT \ | 586 #define PRINT_TO_SUPPORT virtual void PrintTo(BufferFormatter* f) const; |
604 virtual void PrintTo(BufferFormatter* f) const; | |
605 #else | 587 #else |
606 #define PRINT_TO_SUPPORT | 588 #define PRINT_TO_SUPPORT |
607 #endif // !PRODUCT | 589 #endif // !PRODUCT |
608 | 590 |
609 #ifndef PRODUCT | 591 #ifndef PRODUCT |
610 #define PRINT_OPERANDS_TO_SUPPORT \ | 592 #define PRINT_OPERANDS_TO_SUPPORT \ |
611 virtual void PrintOperandsTo(BufferFormatter* f) const; | 593 virtual void PrintOperandsTo(BufferFormatter* f) const; |
612 #else | 594 #else |
613 #define PRINT_OPERANDS_TO_SUPPORT | 595 #define PRINT_OPERANDS_TO_SUPPORT |
614 #endif // !PRODUCT | 596 #endif // !PRODUCT |
615 | 597 |
616 class Instruction : public ZoneAllocated { | 598 class Instruction : public ZoneAllocated { |
617 public: | 599 public: |
618 #define DECLARE_TAG(type) k##type, | 600 #define DECLARE_TAG(type) k##type, |
619 enum Tag { | 601 enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) }; |
620 FOR_EACH_INSTRUCTION(DECLARE_TAG) | |
621 }; | |
622 #undef DECLARE_TAG | 602 #undef DECLARE_TAG |
623 | 603 |
624 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) | 604 explicit Instruction(intptr_t deopt_id = Thread::kNoDeoptId) |
625 : deopt_id_(deopt_id), | 605 : deopt_id_(deopt_id), |
626 lifetime_position_(kNoPlaceId), | 606 lifetime_position_(kNoPlaceId), |
627 previous_(NULL), | 607 previous_(NULL), |
628 next_(NULL), | 608 next_(NULL), |
629 env_(NULL), | 609 env_(NULL), |
630 locs_(NULL), | 610 locs_(NULL), |
631 inlining_id_(-1) { } | 611 inlining_id_(-1) {} |
632 | 612 |
633 virtual ~Instruction() { } | 613 virtual ~Instruction() {} |
634 | 614 |
635 virtual Tag tag() const = 0; | 615 virtual Tag tag() const = 0; |
636 | 616 |
637 intptr_t deopt_id() const { | 617 intptr_t deopt_id() const { |
638 ASSERT(CanDeoptimize() || CanBecomeDeoptimizationTarget()); | 618 ASSERT(CanDeoptimize() || CanBecomeDeoptimizationTarget()); |
639 return GetDeoptId(); | 619 return GetDeoptId(); |
640 } | 620 } |
641 | 621 |
642 const ICData* GetICData( | 622 const ICData* GetICData( |
643 const ZoneGrowableArray<const ICData*>& ic_data_array) const; | 623 const ZoneGrowableArray<const ICData*>& ic_data_array) const; |
644 | 624 |
645 virtual TokenPosition token_pos() const { | 625 virtual TokenPosition token_pos() const { return TokenPosition::kNoSource; } |
646 return TokenPosition::kNoSource; | |
647 } | |
648 | 626 |
649 virtual intptr_t InputCount() const = 0; | 627 virtual intptr_t InputCount() const = 0; |
650 virtual Value* InputAt(intptr_t i) const = 0; | 628 virtual Value* InputAt(intptr_t i) const = 0; |
651 void SetInputAt(intptr_t i, Value* value) { | 629 void SetInputAt(intptr_t i, Value* value) { |
652 ASSERT(value != NULL); | 630 ASSERT(value != NULL); |
653 value->set_instruction(this); | 631 value->set_instruction(this); |
654 value->set_use_index(i); | 632 value->set_use_index(i); |
655 RawSetInputAt(i, value); | 633 RawSetInputAt(i, value); |
656 } | 634 } |
657 | 635 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 virtual void PrintTo(BufferFormatter* f) const; | 710 virtual void PrintTo(BufferFormatter* f) const; |
733 virtual void PrintOperandsTo(BufferFormatter* f) const; | 711 virtual void PrintOperandsTo(BufferFormatter* f) const; |
734 #endif | 712 #endif |
735 | 713 |
736 #define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type) \ | 714 #define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type) \ |
737 bool Is##Name() { return (As##Name() != NULL); } \ | 715 bool Is##Name() { return (As##Name() != NULL); } \ |
738 virtual Type* As##Name() { return NULL; } | 716 virtual Type* As##Name() { return NULL; } |
739 #define INSTRUCTION_TYPE_CHECK(Name) \ | 717 #define INSTRUCTION_TYPE_CHECK(Name) \ |
740 DECLARE_INSTRUCTION_TYPE_CHECK(Name, Name##Instr) | 718 DECLARE_INSTRUCTION_TYPE_CHECK(Name, Name##Instr) |
741 | 719 |
742 DECLARE_INSTRUCTION_TYPE_CHECK(Definition, Definition) | 720 DECLARE_INSTRUCTION_TYPE_CHECK(Definition, Definition) |
743 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 721 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
744 FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 722 FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
745 | 723 |
746 #undef INSTRUCTION_TYPE_CHECK | 724 #undef INSTRUCTION_TYPE_CHECK |
747 #undef DECLARE_INSTRUCTION_TYPE_CHECK | 725 #undef DECLARE_INSTRUCTION_TYPE_CHECK |
748 | 726 |
749 // Returns structure describing location constraints required | 727 // Returns structure describing location constraints required |
750 // to emit native code for this instruction. | 728 // to emit native code for this instruction. |
751 LocationSummary* locs() { | 729 LocationSummary* locs() { |
752 ASSERT(locs_ != NULL); | 730 ASSERT(locs_ != NULL); |
753 return locs_; | 731 return locs_; |
754 } | 732 } |
755 | 733 |
756 bool HasLocs() const { return locs_ != NULL; } | 734 bool HasLocs() const { return locs_ != NULL; } |
757 | 735 |
758 virtual LocationSummary* MakeLocationSummary(Zone* zone, | 736 virtual LocationSummary* MakeLocationSummary(Zone* zone, |
759 bool is_optimizing) const = 0; | 737 bool is_optimizing) const = 0; |
760 | 738 |
761 void InitializeLocationSummary(Zone* zone, bool optimizing) { | 739 void InitializeLocationSummary(Zone* zone, bool optimizing) { |
762 ASSERT(locs_ == NULL); | 740 ASSERT(locs_ == NULL); |
763 locs_ = MakeLocationSummary(zone, optimizing); | 741 locs_ = MakeLocationSummary(zone, optimizing); |
764 } | 742 } |
765 | 743 |
766 static LocationSummary* MakeCallSummary(Zone* zone); | 744 static LocationSummary* MakeCallSummary(Zone* zone); |
767 | 745 |
768 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 746 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
769 UNIMPLEMENTED(); | |
770 } | |
771 | 747 |
772 Environment* env() const { return env_; } | 748 Environment* env() const { return env_; } |
773 void SetEnvironment(Environment* deopt_env); | 749 void SetEnvironment(Environment* deopt_env); |
774 void RemoveEnvironment(); | 750 void RemoveEnvironment(); |
775 | 751 |
776 intptr_t lifetime_position() const { return lifetime_position_; } | 752 intptr_t lifetime_position() const { return lifetime_position_; } |
777 void set_lifetime_position(intptr_t pos) { | 753 void set_lifetime_position(intptr_t pos) { lifetime_position_ = pos; } |
778 lifetime_position_ = pos; | |
779 } | |
780 | 754 |
781 bool HasUnmatchedInputRepresentations() const; | 755 bool HasUnmatchedInputRepresentations() const; |
782 | 756 |
783 // Returns representation expected for the input operand at the given index. | 757 // Returns representation expected for the input operand at the given index. |
784 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 758 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
785 return kTagged; | 759 return kTagged; |
786 } | 760 } |
787 | 761 |
788 // Representation of the value produced by this computation. | 762 // Representation of the value produced by this computation. |
789 virtual Representation representation() const { | 763 virtual Representation representation() const { return kTagged; } |
790 return kTagged; | |
791 } | |
792 | 764 |
793 bool WasEliminated() const { | 765 bool WasEliminated() const { return next() == NULL; } |
794 return next() == NULL; | |
795 } | |
796 | 766 |
797 // Returns deoptimization id that corresponds to the deoptimization target | 767 // Returns deoptimization id that corresponds to the deoptimization target |
798 // that input operands conversions inserted for this instruction can jump | 768 // that input operands conversions inserted for this instruction can jump |
799 // to. | 769 // to. |
800 virtual intptr_t DeoptimizationTarget() const { | 770 virtual intptr_t DeoptimizationTarget() const { |
801 UNREACHABLE(); | 771 UNREACHABLE(); |
802 return Thread::kNoDeoptId; | 772 return Thread::kNoDeoptId; |
803 } | 773 } |
804 | 774 |
805 // Returns a replacement for the instruction or NULL if the instruction can | 775 // Returns a replacement for the instruction or NULL if the instruction can |
806 // be eliminated. By default returns the this instruction which means no | 776 // be eliminated. By default returns the this instruction which means no |
807 // change. | 777 // change. |
808 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 778 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
809 | 779 |
810 // Insert this instruction before 'next' after use lists are computed. | 780 // Insert this instruction before 'next' after use lists are computed. |
811 // Instructions cannot be inserted before a block entry or any other | 781 // Instructions cannot be inserted before a block entry or any other |
812 // instruction without a previous instruction. | 782 // instruction without a previous instruction. |
813 void InsertBefore(Instruction* next) { InsertAfter(next->previous()); } | 783 void InsertBefore(Instruction* next) { InsertAfter(next->previous()); } |
814 | 784 |
815 // Insert this instruction after 'prev' after use lists are computed. | 785 // Insert this instruction after 'prev' after use lists are computed. |
816 void InsertAfter(Instruction* prev); | 786 void InsertAfter(Instruction* prev); |
817 | 787 |
818 // Append an instruction to the current one and return the tail. | 788 // Append an instruction to the current one and return the tail. |
819 // This function updated def-use chains of the newly appended | 789 // This function updated def-use chains of the newly appended |
820 // instruction. | 790 // instruction. |
821 Instruction* AppendInstruction(Instruction* tail); | 791 Instruction* AppendInstruction(Instruction* tail); |
822 | 792 |
823 virtual bool AllowsDCE() const { | 793 virtual bool AllowsDCE() const { return false; } |
824 return false; | |
825 } | |
826 | 794 |
827 // Returns true if CSE and LICM are allowed for this instruction. | 795 // Returns true if CSE and LICM are allowed for this instruction. |
828 virtual bool AllowsCSE() const { | 796 virtual bool AllowsCSE() const { return false; } |
829 return false; | |
830 } | |
831 | 797 |
832 // Returns set of effects created by this instruction. | 798 // Returns set of effects created by this instruction. |
833 virtual EffectSet Effects() const = 0; | 799 virtual EffectSet Effects() const = 0; |
834 | 800 |
835 // Returns set of effects that affect this instruction. | 801 // Returns set of effects that affect this instruction. |
836 virtual EffectSet Dependencies() const { | 802 virtual EffectSet Dependencies() const { |
837 UNREACHABLE(); | 803 UNREACHABLE(); |
838 return EffectSet::All(); | 804 return EffectSet::All(); |
839 } | 805 } |
840 | 806 |
(...skipping 28 matching lines...) Expand all Loading... |
869 UNREACHABLE(); | 835 UNREACHABLE(); |
870 return false; | 836 return false; |
871 } | 837 } |
872 | 838 |
873 virtual void InheritDeoptTarget(Zone* zone, Instruction* other); | 839 virtual void InheritDeoptTarget(Zone* zone, Instruction* other); |
874 | 840 |
875 bool NeedsEnvironment() const { | 841 bool NeedsEnvironment() const { |
876 return CanDeoptimize() || CanBecomeDeoptimizationTarget(); | 842 return CanDeoptimize() || CanBecomeDeoptimizationTarget(); |
877 } | 843 } |
878 | 844 |
879 virtual bool CanBecomeDeoptimizationTarget() const { | 845 virtual bool CanBecomeDeoptimizationTarget() const { return false; } |
880 return false; | |
881 } | |
882 | 846 |
883 void InheritDeoptTargetAfter(FlowGraph* flow_graph, | 847 void InheritDeoptTargetAfter(FlowGraph* flow_graph, |
884 Definition* call, | 848 Definition* call, |
885 Definition* result); | 849 Definition* result); |
886 | 850 |
887 virtual bool MayThrow() const = 0; | 851 virtual bool MayThrow() const = 0; |
888 | 852 |
889 bool IsDominatedBy(Instruction* dom); | 853 bool IsDominatedBy(Instruction* dom); |
890 | 854 |
891 void ClearEnv() { env_ = NULL; } | 855 void ClearEnv() { env_ = NULL; } |
892 | 856 |
893 void Unsupported(FlowGraphCompiler* compiler); | 857 void Unsupported(FlowGraphCompiler* compiler); |
894 | 858 |
895 protected: | 859 protected: |
896 // GetDeoptId and/or CopyDeoptIdFrom. | 860 // GetDeoptId and/or CopyDeoptIdFrom. |
897 friend class CallSiteInliner; | 861 friend class CallSiteInliner; |
898 friend class LICM; | 862 friend class LICM; |
899 friend class ComparisonInstr; | 863 friend class ComparisonInstr; |
900 friend class Scheduler; | 864 friend class Scheduler; |
901 friend class BlockEntryInstr; | 865 friend class BlockEntryInstr; |
902 friend class CatchBlockEntryInstr; // deopt_id_ | 866 friend class CatchBlockEntryInstr; // deopt_id_ |
903 | 867 |
904 // Fetch deopt id without checking if this computation can deoptimize. | 868 // Fetch deopt id without checking if this computation can deoptimize. |
905 intptr_t GetDeoptId() const { | 869 intptr_t GetDeoptId() const { return deopt_id_; } |
906 return deopt_id_; | |
907 } | |
908 | 870 |
909 void CopyDeoptIdFrom(const Instruction& instr) { | 871 void CopyDeoptIdFrom(const Instruction& instr) { |
910 deopt_id_ = instr.deopt_id_; | 872 deopt_id_ = instr.deopt_id_; |
911 } | 873 } |
912 | 874 |
913 private: | 875 private: |
914 friend class BranchInstr; // For RawSetInputAt. | 876 friend class BranchInstr; // For RawSetInputAt. |
915 friend class IfThenElseInstr; // For RawSetInputAt. | 877 friend class IfThenElseInstr; // For RawSetInputAt. |
916 | 878 |
917 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; | 879 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; |
918 | 880 |
919 enum { | 881 enum { kNoPlaceId = -1 }; |
920 kNoPlaceId = -1 | |
921 }; | |
922 | 882 |
923 intptr_t deopt_id_; | 883 intptr_t deopt_id_; |
924 union { | 884 union { |
925 intptr_t lifetime_position_; // Position used by register allocator. | 885 intptr_t lifetime_position_; // Position used by register allocator. |
926 intptr_t place_id_; | 886 intptr_t place_id_; |
927 }; | 887 }; |
928 Instruction* previous_; | 888 Instruction* previous_; |
929 Instruction* next_; | 889 Instruction* next_; |
930 Environment* env_; | 890 Environment* env_; |
931 LocationSummary* locs_; | 891 LocationSummary* locs_; |
932 intptr_t inlining_id_; | 892 intptr_t inlining_id_; |
933 | 893 |
934 DISALLOW_COPY_AND_ASSIGN(Instruction); | 894 DISALLOW_COPY_AND_ASSIGN(Instruction); |
935 }; | 895 }; |
936 | 896 |
937 | 897 |
938 class PureInstruction : public Instruction { | 898 class PureInstruction : public Instruction { |
939 public: | 899 public: |
940 explicit PureInstruction(intptr_t deopt_id) | 900 explicit PureInstruction(intptr_t deopt_id) : Instruction(deopt_id) {} |
941 : Instruction(deopt_id) { } | |
942 | 901 |
943 virtual bool AllowsCSE() const { return true; } | 902 virtual bool AllowsCSE() const { return true; } |
944 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 903 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
945 | 904 |
946 virtual EffectSet Effects() const { return EffectSet::None(); } | 905 virtual EffectSet Effects() const { return EffectSet::None(); } |
947 }; | 906 }; |
948 | 907 |
949 | 908 |
950 // Types to be used as ThrowsTrait for TemplateInstruction/TemplateDefinition. | 909 // Types to be used as ThrowsTrait for TemplateInstruction/TemplateDefinition. |
951 struct Throws { | 910 struct Throws { |
952 static const bool kCanThrow = true; | 911 static const bool kCanThrow = true; |
953 }; | 912 }; |
954 | 913 |
955 | 914 |
956 struct NoThrow { | 915 struct NoThrow { |
957 static const bool kCanThrow = false; | 916 static const bool kCanThrow = false; |
958 }; | 917 }; |
959 | 918 |
960 | 919 |
961 // Types to be used as CSETrait for TemplateInstruction/TemplateDefinition. | 920 // Types to be used as CSETrait for TemplateInstruction/TemplateDefinition. |
962 // Pure instructions are those that allow CSE and have no effects and | 921 // Pure instructions are those that allow CSE and have no effects and |
963 // no dependencies. | 922 // no dependencies. |
964 template<typename DefaultBase, typename PureBase> | 923 template <typename DefaultBase, typename PureBase> |
965 struct Pure { | 924 struct Pure { |
966 typedef PureBase Base; | 925 typedef PureBase Base; |
967 }; | 926 }; |
968 | 927 |
969 | 928 |
970 template<typename DefaultBase, typename PureBase> | 929 template <typename DefaultBase, typename PureBase> |
971 struct NoCSE { | 930 struct NoCSE { |
972 typedef DefaultBase Base; | 931 typedef DefaultBase Base; |
973 }; | 932 }; |
974 | 933 |
975 | 934 |
976 template<intptr_t N, | 935 template <intptr_t N, |
977 typename ThrowsTrait, | 936 typename ThrowsTrait, |
978 template<typename Default, typename Pure> class CSETrait = NoCSE> | 937 template <typename Default, typename Pure> class CSETrait = NoCSE> |
979 class TemplateInstruction: public CSETrait<Instruction, PureInstruction>::Base { | 938 class TemplateInstruction |
| 939 : public CSETrait<Instruction, PureInstruction>::Base { |
980 public: | 940 public: |
981 explicit TemplateInstruction(intptr_t deopt_id = Thread::kNoDeoptId) | 941 explicit TemplateInstruction(intptr_t deopt_id = Thread::kNoDeoptId) |
982 : CSETrait<Instruction, PureInstruction>::Base(deopt_id), inputs_() { } | 942 : CSETrait<Instruction, PureInstruction>::Base(deopt_id), inputs_() {} |
983 | 943 |
984 virtual intptr_t InputCount() const { return N; } | 944 virtual intptr_t InputCount() const { return N; } |
985 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 945 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
986 | 946 |
987 virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } | 947 virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } |
988 | 948 |
989 protected: | 949 protected: |
990 EmbeddedArray<Value*, N> inputs_; | 950 EmbeddedArray<Value*, N> inputs_; |
991 | 951 |
992 private: | 952 private: |
993 virtual void RawSetInputAt(intptr_t i, Value* value) { | 953 virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
994 inputs_[i] = value; | |
995 } | |
996 }; | 954 }; |
997 | 955 |
998 | 956 |
999 class MoveOperands : public ZoneAllocated { | 957 class MoveOperands : public ZoneAllocated { |
1000 public: | 958 public: |
1001 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } | 959 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) {} |
1002 | 960 |
1003 Location src() const { return src_; } | 961 Location src() const { return src_; } |
1004 Location dest() const { return dest_; } | 962 Location dest() const { return dest_; } |
1005 | 963 |
1006 Location* src_slot() { return &src_; } | 964 Location* src_slot() { return &src_; } |
1007 Location* dest_slot() { return &dest_; } | 965 Location* dest_slot() { return &dest_; } |
1008 | 966 |
1009 void set_src(const Location& value) { src_ = value; } | 967 void set_src(const Location& value) { src_ = value; } |
1010 void set_dest(const Location& value) { dest_ = value; } | 968 void set_dest(const Location& value) { dest_ = value; } |
1011 | 969 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1049 private: | 1007 private: |
1050 Location dest_; | 1008 Location dest_; |
1051 Location src_; | 1009 Location src_; |
1052 | 1010 |
1053 DISALLOW_COPY_AND_ASSIGN(MoveOperands); | 1011 DISALLOW_COPY_AND_ASSIGN(MoveOperands); |
1054 }; | 1012 }; |
1055 | 1013 |
1056 | 1014 |
1057 class ParallelMoveInstr : public TemplateInstruction<0, NoThrow> { | 1015 class ParallelMoveInstr : public TemplateInstruction<0, NoThrow> { |
1058 public: | 1016 public: |
1059 ParallelMoveInstr() : moves_(4) { } | 1017 ParallelMoveInstr() : moves_(4) {} |
1060 | 1018 |
1061 DECLARE_INSTRUCTION(ParallelMove) | 1019 DECLARE_INSTRUCTION(ParallelMove) |
1062 | 1020 |
1063 virtual intptr_t ArgumentCount() const { return 0; } | 1021 virtual intptr_t ArgumentCount() const { return 0; } |
1064 | 1022 |
1065 virtual bool CanDeoptimize() const { return false; } | 1023 virtual bool CanDeoptimize() const { return false; } |
1066 | 1024 |
1067 virtual EffectSet Effects() const { | 1025 virtual EffectSet Effects() const { |
1068 UNREACHABLE(); // This instruction never visited by optimization passes. | 1026 UNREACHABLE(); // This instruction never visited by optimization passes. |
1069 return EffectSet::None(); | 1027 return EffectSet::None(); |
(...skipping 16 matching lines...) Expand all Loading... |
1086 | 1044 |
1087 bool IsRedundant() const; | 1045 bool IsRedundant() const; |
1088 | 1046 |
1089 virtual TokenPosition token_pos() const { | 1047 virtual TokenPosition token_pos() const { |
1090 return TokenPosition::kParallelMove; | 1048 return TokenPosition::kParallelMove; |
1091 } | 1049 } |
1092 | 1050 |
1093 PRINT_TO_SUPPORT | 1051 PRINT_TO_SUPPORT |
1094 | 1052 |
1095 private: | 1053 private: |
1096 GrowableArray<MoveOperands*> moves_; // Elements cannot be null. | 1054 GrowableArray<MoveOperands*> moves_; // Elements cannot be null. |
1097 | 1055 |
1098 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); | 1056 DISALLOW_COPY_AND_ASSIGN(ParallelMoveInstr); |
1099 }; | 1057 }; |
1100 | 1058 |
1101 | 1059 |
1102 // Basic block entries are administrative nodes. There is a distinguished | 1060 // Basic block entries are administrative nodes. There is a distinguished |
1103 // graph entry with no predecessor. Joins are the only nodes with multiple | 1061 // graph entry with no predecessor. Joins are the only nodes with multiple |
1104 // predecessors. Targets are all other basic block entries. The types | 1062 // predecessors. Targets are all other basic block entries. The types |
1105 // enforce edge-split form---joins are forbidden as the successors of | 1063 // enforce edge-split form---joins are forbidden as the successors of |
1106 // branches. | 1064 // branches. |
1107 class BlockEntryInstr : public Instruction { | 1065 class BlockEntryInstr : public Instruction { |
1108 public: | 1066 public: |
1109 virtual intptr_t PredecessorCount() const = 0; | 1067 virtual intptr_t PredecessorCount() const = 0; |
1110 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; | 1068 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; |
1111 | 1069 |
1112 intptr_t preorder_number() const { return preorder_number_; } | 1070 intptr_t preorder_number() const { return preorder_number_; } |
1113 void set_preorder_number(intptr_t number) { preorder_number_ = number; } | 1071 void set_preorder_number(intptr_t number) { preorder_number_ = number; } |
1114 | 1072 |
1115 intptr_t postorder_number() const { return postorder_number_; } | 1073 intptr_t postorder_number() const { return postorder_number_; } |
1116 void set_postorder_number(intptr_t number) { postorder_number_ = number; } | 1074 void set_postorder_number(intptr_t number) { postorder_number_ = number; } |
1117 | 1075 |
1118 intptr_t block_id() const { return block_id_; } | 1076 intptr_t block_id() const { return block_id_; } |
1119 | 1077 |
1120 // NOTE: These are SSA positions and not token positions. These are used by | 1078 // NOTE: These are SSA positions and not token positions. These are used by |
1121 // the register allocator. | 1079 // the register allocator. |
1122 void set_start_pos(intptr_t pos) { start_pos_ = pos; } | 1080 void set_start_pos(intptr_t pos) { start_pos_ = pos; } |
1123 intptr_t start_pos() const { return start_pos_; } | 1081 intptr_t start_pos() const { return start_pos_; } |
1124 void set_end_pos(intptr_t pos) { end_pos_ = pos; } | 1082 void set_end_pos(intptr_t pos) { end_pos_ = pos; } |
1125 intptr_t end_pos() const { return end_pos_; } | 1083 intptr_t end_pos() const { return end_pos_; } |
1126 | 1084 |
1127 BlockEntryInstr* dominator() const { return dominator_; } | 1085 BlockEntryInstr* dominator() const { return dominator_; } |
1128 BlockEntryInstr* ImmediateDominator() const; | 1086 BlockEntryInstr* ImmediateDominator() const; |
1129 | 1087 |
1130 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { | 1088 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { |
1131 return dominated_blocks_; | 1089 return dominated_blocks_; |
1132 } | 1090 } |
1133 | 1091 |
1134 void AddDominatedBlock(BlockEntryInstr* block) { | 1092 void AddDominatedBlock(BlockEntryInstr* block) { |
1135 block->set_dominator(this); | 1093 block->set_dominator(this); |
1136 dominated_blocks_.Add(block); | 1094 dominated_blocks_.Add(block); |
1137 } | 1095 } |
1138 void ClearDominatedBlocks() { dominated_blocks_.Clear(); } | 1096 void ClearDominatedBlocks() { dominated_blocks_.Clear(); } |
1139 | 1097 |
1140 bool Dominates(BlockEntryInstr* other) const; | 1098 bool Dominates(BlockEntryInstr* other) const; |
1141 | 1099 |
1142 Instruction* last_instruction() const { return last_instruction_; } | 1100 Instruction* last_instruction() const { return last_instruction_; } |
1143 void set_last_instruction(Instruction* instr) { last_instruction_ = instr; } | 1101 void set_last_instruction(Instruction* instr) { last_instruction_ = instr; } |
1144 | 1102 |
1145 ParallelMoveInstr* parallel_move() const { | 1103 ParallelMoveInstr* parallel_move() const { return parallel_move_; } |
1146 return parallel_move_; | |
1147 } | |
1148 | 1104 |
1149 bool HasParallelMove() const { | 1105 bool HasParallelMove() const { return parallel_move_ != NULL; } |
1150 return parallel_move_ != NULL; | |
1151 } | |
1152 | 1106 |
1153 bool HasNonRedundantParallelMove() const { | 1107 bool HasNonRedundantParallelMove() const { |
1154 return HasParallelMove() && !parallel_move()->IsRedundant(); | 1108 return HasParallelMove() && !parallel_move()->IsRedundant(); |
1155 } | 1109 } |
1156 | 1110 |
1157 ParallelMoveInstr* GetParallelMove() { | 1111 ParallelMoveInstr* GetParallelMove() { |
1158 if (parallel_move_ == NULL) { | 1112 if (parallel_move_ == NULL) { |
1159 parallel_move_ = new ParallelMoveInstr(); | 1113 parallel_move_ = new ParallelMoveInstr(); |
1160 } | 1114 } |
1161 return parallel_move_; | 1115 return parallel_move_; |
1162 } | 1116 } |
1163 | 1117 |
1164 // Discover basic-block structure of the current block. Must be called | 1118 // Discover basic-block structure of the current block. Must be called |
1165 // on all graph blocks in preorder to yield valid results. As a side effect, | 1119 // on all graph blocks in preorder to yield valid results. As a side effect, |
1166 // the block entry instructions in the graph are assigned preorder numbers. | 1120 // the block entry instructions in the graph are assigned preorder numbers. |
1167 // The array 'preorder' maps preorder block numbers to the block entry | 1121 // The array 'preorder' maps preorder block numbers to the block entry |
1168 // instruction with that number. The depth first spanning tree is recorded | 1122 // instruction with that number. The depth first spanning tree is recorded |
1169 // in the array 'parent', which maps preorder block numbers to the preorder | 1123 // in the array 'parent', which maps preorder block numbers to the preorder |
1170 // number of the block's spanning-tree parent. As a side effect of this | 1124 // number of the block's spanning-tree parent. As a side effect of this |
1171 // function, the set of basic block predecessors (e.g., block entry | 1125 // function, the set of basic block predecessors (e.g., block entry |
1172 // instructions of predecessor blocks) and also the last instruction in the | 1126 // instructions of predecessor blocks) and also the last instruction in the |
1173 // block is recorded in each entry instruction. Returns true when called the | 1127 // block is recorded in each entry instruction. Returns true when called the |
1174 // first time on this particular block within one graph traversal, and false | 1128 // first time on this particular block within one graph traversal, and false |
1175 // on all successive calls. | 1129 // on all successive calls. |
1176 bool DiscoverBlock( | 1130 bool DiscoverBlock(BlockEntryInstr* predecessor, |
1177 BlockEntryInstr* predecessor, | 1131 GrowableArray<BlockEntryInstr*>* preorder, |
1178 GrowableArray<BlockEntryInstr*>* preorder, | 1132 GrowableArray<intptr_t>* parent); |
1179 GrowableArray<intptr_t>* parent); | |
1180 | 1133 |
1181 // Perform a depth first search to prune code not reachable from an OSR | 1134 // Perform a depth first search to prune code not reachable from an OSR |
1182 // entry point. | 1135 // entry point. |
1183 bool PruneUnreachable(GraphEntryInstr* graph_entry, | 1136 bool PruneUnreachable(GraphEntryInstr* graph_entry, |
1184 Instruction* parent, | 1137 Instruction* parent, |
1185 intptr_t osr_id, | 1138 intptr_t osr_id, |
1186 BitVector* block_marks); | 1139 BitVector* block_marks); |
1187 | 1140 |
1188 virtual intptr_t InputCount() const { return 0; } | 1141 virtual intptr_t InputCount() const { return 0; } |
1189 virtual Value* InputAt(intptr_t i) const { | 1142 virtual Value* InputAt(intptr_t i) const { |
(...skipping 10 matching lines...) Expand all Loading... |
1200 } | 1153 } |
1201 | 1154 |
1202 virtual bool CanDeoptimize() const { return false; } | 1155 virtual bool CanDeoptimize() const { return false; } |
1203 | 1156 |
1204 virtual EffectSet Effects() const { return EffectSet::None(); } | 1157 virtual EffectSet Effects() const { return EffectSet::None(); } |
1205 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 1158 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
1206 | 1159 |
1207 virtual bool MayThrow() const { return false; } | 1160 virtual bool MayThrow() const { return false; } |
1208 | 1161 |
1209 intptr_t try_index() const { return try_index_; } | 1162 intptr_t try_index() const { return try_index_; } |
1210 void set_try_index(intptr_t index) { | 1163 void set_try_index(intptr_t index) { try_index_ = index; } |
1211 try_index_ = index; | |
1212 } | |
1213 | 1164 |
1214 // True for blocks inside a try { } region. | 1165 // True for blocks inside a try { } region. |
1215 bool InsideTryBlock() const { | 1166 bool InsideTryBlock() const { |
1216 return try_index_ != CatchClauseNode::kInvalidTryIndex; | 1167 return try_index_ != CatchClauseNode::kInvalidTryIndex; |
1217 } | 1168 } |
1218 | 1169 |
1219 BitVector* loop_info() const { return loop_info_; } | 1170 BitVector* loop_info() const { return loop_info_; } |
1220 void set_loop_info(BitVector* loop_info) { | 1171 void set_loop_info(BitVector* loop_info) { loop_info_ = loop_info; } |
1221 loop_info_ = loop_info; | |
1222 } | |
1223 | 1172 |
1224 virtual BlockEntryInstr* GetBlock() { | 1173 virtual BlockEntryInstr* GetBlock() { return this; } |
1225 return this; | |
1226 } | |
1227 | 1174 |
1228 virtual TokenPosition token_pos() const { | 1175 virtual TokenPosition token_pos() const { |
1229 return TokenPosition::kControlFlow; | 1176 return TokenPosition::kControlFlow; |
1230 } | 1177 } |
1231 | 1178 |
1232 // Helper to mutate the graph during inlining. This block should be | 1179 // Helper to mutate the graph during inlining. This block should be |
1233 // replaced with new_block as a predecessor of all of this block's | 1180 // replaced with new_block as a predecessor of all of this block's |
1234 // successors. | 1181 // successors. |
1235 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); | 1182 void ReplaceAsPredecessorWith(BlockEntryInstr* new_block); |
1236 | 1183 |
(...skipping 13 matching lines...) Expand all Loading... |
1250 : Instruction(Thread::Current()->GetNextDeoptId()), | 1197 : Instruction(Thread::Current()->GetNextDeoptId()), |
1251 block_id_(block_id), | 1198 block_id_(block_id), |
1252 try_index_(try_index), | 1199 try_index_(try_index), |
1253 preorder_number_(-1), | 1200 preorder_number_(-1), |
1254 postorder_number_(-1), | 1201 postorder_number_(-1), |
1255 dominator_(NULL), | 1202 dominator_(NULL), |
1256 dominated_blocks_(1), | 1203 dominated_blocks_(1), |
1257 last_instruction_(NULL), | 1204 last_instruction_(NULL), |
1258 offset_(-1), | 1205 offset_(-1), |
1259 parallel_move_(NULL), | 1206 parallel_move_(NULL), |
1260 loop_info_(NULL) { | 1207 loop_info_(NULL) {} |
1261 } | |
1262 | 1208 |
1263 private: | 1209 private: |
1264 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } | 1210 virtual void RawSetInputAt(intptr_t i, Value* value) { UNREACHABLE(); } |
1265 | 1211 |
1266 virtual void ClearPredecessors() = 0; | 1212 virtual void ClearPredecessors() = 0; |
1267 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 1213 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
1268 | 1214 |
1269 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 1215 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
1270 | 1216 |
1271 intptr_t block_id_; | 1217 intptr_t block_id_; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1387 // Number of stack slots reserved for compiling try-catch. For functions | 1333 // Number of stack slots reserved for compiling try-catch. For functions |
1388 // without try-catch, this is 0. Otherwise, it is the number of local | 1334 // without try-catch, this is 0. Otherwise, it is the number of local |
1389 // variables. | 1335 // variables. |
1390 intptr_t fixed_slot_count() const { return fixed_slot_count_; } | 1336 intptr_t fixed_slot_count() const { return fixed_slot_count_; } |
1391 void set_fixed_slot_count(intptr_t count) { | 1337 void set_fixed_slot_count(intptr_t count) { |
1392 ASSERT(count >= 0); | 1338 ASSERT(count >= 0); |
1393 fixed_slot_count_ = count; | 1339 fixed_slot_count_ = count; |
1394 } | 1340 } |
1395 TargetEntryInstr* normal_entry() const { return normal_entry_; } | 1341 TargetEntryInstr* normal_entry() const { return normal_entry_; } |
1396 | 1342 |
1397 const ParsedFunction& parsed_function() const { | 1343 const ParsedFunction& parsed_function() const { return parsed_function_; } |
1398 return parsed_function_; | |
1399 } | |
1400 | 1344 |
1401 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { | 1345 const GrowableArray<CatchBlockEntryInstr*>& catch_entries() const { |
1402 return catch_entries_; | 1346 return catch_entries_; |
1403 } | 1347 } |
1404 | 1348 |
1405 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const { | 1349 const GrowableArray<IndirectEntryInstr*>& indirect_entries() const { |
1406 return indirect_entries_; | 1350 return indirect_entries_; |
1407 } | 1351 } |
1408 | 1352 |
1409 PRINT_TO_SUPPORT | 1353 PRINT_TO_SUPPORT |
(...skipping 15 matching lines...) Expand all Loading... |
1425 | 1369 |
1426 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 1370 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
1427 }; | 1371 }; |
1428 | 1372 |
1429 | 1373 |
1430 class JoinEntryInstr : public BlockEntryInstr { | 1374 class JoinEntryInstr : public BlockEntryInstr { |
1431 public: | 1375 public: |
1432 JoinEntryInstr(intptr_t block_id, intptr_t try_index) | 1376 JoinEntryInstr(intptr_t block_id, intptr_t try_index) |
1433 : BlockEntryInstr(block_id, try_index), | 1377 : BlockEntryInstr(block_id, try_index), |
1434 predecessors_(2), // Two is the assumed to be the common case. | 1378 predecessors_(2), // Two is the assumed to be the common case. |
1435 phis_(NULL) { } | 1379 phis_(NULL) {} |
1436 | 1380 |
1437 DECLARE_INSTRUCTION(JoinEntry) | 1381 DECLARE_INSTRUCTION(JoinEntry) |
1438 | 1382 |
1439 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } | 1383 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } |
1440 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { | 1384 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { |
1441 return predecessors_[index]; | 1385 return predecessors_[index]; |
1442 } | 1386 } |
1443 | 1387 |
1444 // Returns -1 if pred is not in the list. | 1388 // Returns -1 if pred is not in the list. |
1445 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; | 1389 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; |
(...skipping 27 matching lines...) Expand all Loading... |
1473 | 1417 |
1474 GrowableArray<BlockEntryInstr*> predecessors_; | 1418 GrowableArray<BlockEntryInstr*> predecessors_; |
1475 ZoneGrowableArray<PhiInstr*>* phis_; | 1419 ZoneGrowableArray<PhiInstr*>* phis_; |
1476 | 1420 |
1477 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); | 1421 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); |
1478 }; | 1422 }; |
1479 | 1423 |
1480 | 1424 |
1481 class PhiIterator : public ValueObject { | 1425 class PhiIterator : public ValueObject { |
1482 public: | 1426 public: |
1483 explicit PhiIterator(JoinEntryInstr* join) | 1427 explicit PhiIterator(JoinEntryInstr* join) : phis_(join->phis()), index_(0) {} |
1484 : phis_(join->phis()), index_(0) { } | |
1485 | 1428 |
1486 void Advance() { | 1429 void Advance() { |
1487 ASSERT(!Done()); | 1430 ASSERT(!Done()); |
1488 index_++; | 1431 index_++; |
1489 } | 1432 } |
1490 | 1433 |
1491 bool Done() const { | 1434 bool Done() const { return (phis_ == NULL) || (index_ >= phis_->length()); } |
1492 return (phis_ == NULL) || (index_ >= phis_->length()); | |
1493 } | |
1494 | 1435 |
1495 PhiInstr* Current() const { | 1436 PhiInstr* Current() const { return (*phis_)[index_]; } |
1496 return (*phis_)[index_]; | |
1497 } | |
1498 | 1437 |
1499 private: | 1438 private: |
1500 ZoneGrowableArray<PhiInstr*>* phis_; | 1439 ZoneGrowableArray<PhiInstr*>* phis_; |
1501 intptr_t index_; | 1440 intptr_t index_; |
1502 }; | 1441 }; |
1503 | 1442 |
1504 | 1443 |
1505 class TargetEntryInstr : public BlockEntryInstr { | 1444 class TargetEntryInstr : public BlockEntryInstr { |
1506 public: | 1445 public: |
1507 TargetEntryInstr(intptr_t block_id, intptr_t try_index) | 1446 TargetEntryInstr(intptr_t block_id, intptr_t try_index) |
1508 : BlockEntryInstr(block_id, try_index), | 1447 : BlockEntryInstr(block_id, try_index), |
1509 predecessor_(NULL), | 1448 predecessor_(NULL), |
1510 edge_weight_(0.0) { } | 1449 edge_weight_(0.0) {} |
1511 | 1450 |
1512 DECLARE_INSTRUCTION(TargetEntry) | 1451 DECLARE_INSTRUCTION(TargetEntry) |
1513 | 1452 |
1514 double edge_weight() const { return edge_weight_; } | 1453 double edge_weight() const { return edge_weight_; } |
1515 void set_edge_weight(double weight) { edge_weight_ = weight; } | 1454 void set_edge_weight(double weight) { edge_weight_ = weight; } |
1516 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } | 1455 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } |
1517 | 1456 |
1518 virtual intptr_t PredecessorCount() const { | 1457 virtual intptr_t PredecessorCount() const { |
1519 return (predecessor_ == NULL) ? 0 : 1; | 1458 return (predecessor_ == NULL) ? 0 : 1; |
1520 } | 1459 } |
(...skipping 18 matching lines...) Expand all Loading... |
1539 | 1478 |
1540 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 1479 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
1541 }; | 1480 }; |
1542 | 1481 |
1543 | 1482 |
1544 class IndirectEntryInstr : public JoinEntryInstr { | 1483 class IndirectEntryInstr : public JoinEntryInstr { |
1545 public: | 1484 public: |
1546 IndirectEntryInstr(intptr_t block_id, | 1485 IndirectEntryInstr(intptr_t block_id, |
1547 intptr_t indirect_id, | 1486 intptr_t indirect_id, |
1548 intptr_t try_index) | 1487 intptr_t try_index) |
1549 : JoinEntryInstr(block_id, try_index), | 1488 : JoinEntryInstr(block_id, try_index), indirect_id_(indirect_id) {} |
1550 indirect_id_(indirect_id) { } | |
1551 | 1489 |
1552 DECLARE_INSTRUCTION(IndirectEntry) | 1490 DECLARE_INSTRUCTION(IndirectEntry) |
1553 | 1491 |
1554 intptr_t indirect_id() const { return indirect_id_; } | 1492 intptr_t indirect_id() const { return indirect_id_; } |
1555 | 1493 |
1556 PRINT_TO_SUPPORT | 1494 PRINT_TO_SUPPORT |
1557 | 1495 |
1558 private: | 1496 private: |
1559 const intptr_t indirect_id_; | 1497 const intptr_t indirect_id_; |
1560 }; | 1498 }; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 | 1534 |
1597 GraphEntryInstr* graph_entry() const { return graph_entry_; } | 1535 GraphEntryInstr* graph_entry() const { return graph_entry_; } |
1598 | 1536 |
1599 const LocalVariable& exception_var() const { return exception_var_; } | 1537 const LocalVariable& exception_var() const { return exception_var_; } |
1600 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } | 1538 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } |
1601 | 1539 |
1602 bool needs_stacktrace() const { return needs_stacktrace_; } | 1540 bool needs_stacktrace() const { return needs_stacktrace_; } |
1603 | 1541 |
1604 // Returns try index for the try block to which this catch handler | 1542 // Returns try index for the try block to which this catch handler |
1605 // corresponds. | 1543 // corresponds. |
1606 intptr_t catch_try_index() const { | 1544 intptr_t catch_try_index() const { return catch_try_index_; } |
1607 return catch_try_index_; | |
1608 } | |
1609 GrowableArray<Definition*>* initial_definitions() { | 1545 GrowableArray<Definition*>* initial_definitions() { |
1610 return &initial_definitions_; | 1546 return &initial_definitions_; |
1611 } | 1547 } |
1612 | 1548 |
1613 PRINT_TO_SUPPORT | 1549 PRINT_TO_SUPPORT |
1614 | 1550 |
1615 private: | 1551 private: |
1616 friend class BlockEntryInstr; // Access to predecessor_ when inlining. | 1552 friend class BlockEntryInstr; // Access to predecessor_ when inlining. |
1617 | 1553 |
1618 virtual void ClearPredecessors() { predecessor_ = NULL; } | 1554 virtual void ClearPredecessors() { predecessor_ = NULL; } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1662 } | 1598 } |
1663 | 1599 |
1664 bool IsUnknown() const { return value_ == kUnknown; } | 1600 bool IsUnknown() const { return value_ == kUnknown; } |
1665 bool IsAliased() const { return value_ == kAliased; } | 1601 bool IsAliased() const { return value_ == kAliased; } |
1666 bool IsNotAliased() const { return (value_ & kNotAliased) != 0; } | 1602 bool IsNotAliased() const { return (value_ & kNotAliased) != 0; } |
1667 bool IsAllocationSinkingCandidate() const { | 1603 bool IsAllocationSinkingCandidate() const { |
1668 return value_ == kAllocationSinkingCandidate; | 1604 return value_ == kAllocationSinkingCandidate; |
1669 } | 1605 } |
1670 | 1606 |
1671 AliasIdentity(const AliasIdentity& other) | 1607 AliasIdentity(const AliasIdentity& other) |
1672 : ValueObject(), value_(other.value_) { | 1608 : ValueObject(), value_(other.value_) {} |
1673 } | |
1674 | 1609 |
1675 AliasIdentity& operator=(const AliasIdentity& other) { | 1610 AliasIdentity& operator=(const AliasIdentity& other) { |
1676 value_ = other.value_; | 1611 value_ = other.value_; |
1677 return *this; | 1612 return *this; |
1678 } | 1613 } |
1679 | 1614 |
1680 private: | 1615 private: |
1681 explicit AliasIdentity(intptr_t value) : value_(value) { } | 1616 explicit AliasIdentity(intptr_t value) : value_(value) {} |
1682 | 1617 |
1683 enum { | 1618 enum { |
1684 kUnknown = 0, | 1619 kUnknown = 0, |
1685 kNotAliased = 1, | 1620 kNotAliased = 1, |
1686 kAliased = 2, | 1621 kAliased = 2, |
1687 kAllocationSinkingCandidate = 3, | 1622 kAllocationSinkingCandidate = 3, |
1688 }; | 1623 }; |
1689 | 1624 |
1690 COMPILE_ASSERT((kUnknown & kNotAliased) == 0); | 1625 COMPILE_ASSERT((kUnknown & kNotAliased) == 0); |
1691 COMPILE_ASSERT((kAliased & kNotAliased) == 0); | 1626 COMPILE_ASSERT((kAliased & kNotAliased) == 0); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1735 if (type_ == NULL) { | 1670 if (type_ == NULL) { |
1736 type_ = ZoneCompileType::Wrap(ComputeType()); | 1671 type_ = ZoneCompileType::Wrap(ComputeType()); |
1737 } | 1672 } |
1738 return type_; | 1673 return type_; |
1739 } | 1674 } |
1740 | 1675 |
1741 // Does this define a mint? | 1676 // Does this define a mint? |
1742 inline bool IsMintDefinition(); | 1677 inline bool IsMintDefinition(); |
1743 | 1678 |
1744 bool IsInt32Definition() { | 1679 bool IsInt32Definition() { |
1745 return IsBinaryInt32Op() || | 1680 return IsBinaryInt32Op() || IsBoxInt32() || IsUnboxInt32() || |
1746 IsBoxInt32() || | |
1747 IsUnboxInt32() || | |
1748 IsUnboxedIntConverter(); | 1681 IsUnboxedIntConverter(); |
1749 } | 1682 } |
1750 | 1683 |
1751 // Compute compile type for this definition. It is safe to use this | 1684 // Compute compile type for this definition. It is safe to use this |
1752 // approximation even before type propagator was run (e.g. during graph | 1685 // approximation even before type propagator was run (e.g. during graph |
1753 // building). | 1686 // building). |
1754 virtual CompileType ComputeType() const { | 1687 virtual CompileType ComputeType() const { return CompileType::Dynamic(); } |
1755 return CompileType::Dynamic(); | |
1756 } | |
1757 | 1688 |
1758 // Update CompileType of the definition. Returns true if the type has changed. | 1689 // Update CompileType of the definition. Returns true if the type has changed. |
1759 virtual bool RecomputeType() { | 1690 virtual bool RecomputeType() { return false; } |
1760 return false; | |
1761 } | |
1762 | 1691 |
1763 PRINT_OPERANDS_TO_SUPPORT | 1692 PRINT_OPERANDS_TO_SUPPORT |
1764 PRINT_TO_SUPPORT | 1693 PRINT_TO_SUPPORT |
1765 | 1694 |
1766 bool UpdateType(CompileType new_type) { | 1695 bool UpdateType(CompileType new_type) { |
1767 if (type_ == NULL) { | 1696 if (type_ == NULL) { |
1768 type_ = ZoneCompileType::Wrap(new_type); | 1697 type_ = ZoneCompileType::Wrap(new_type); |
1769 return true; | 1698 return true; |
1770 } | 1699 } |
1771 | 1700 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 return this; | 1758 return this; |
1830 } | 1759 } |
1831 | 1760 |
1832 void SetReplacement(Definition* other) { | 1761 void SetReplacement(Definition* other) { |
1833 ASSERT(ssa_temp_index_ >= 0); | 1762 ASSERT(ssa_temp_index_ >= 0); |
1834 ASSERT(WasEliminated()); | 1763 ASSERT(WasEliminated()); |
1835 ssa_temp_index_ = kReplacementMarker; | 1764 ssa_temp_index_ = kReplacementMarker; |
1836 temp_index_ = reinterpret_cast<intptr_t>(other); | 1765 temp_index_ = reinterpret_cast<intptr_t>(other); |
1837 } | 1766 } |
1838 | 1767 |
1839 virtual AliasIdentity Identity() const { | 1768 virtual AliasIdentity Identity() const { return AliasIdentity::Unknown(); } |
1840 return AliasIdentity::Unknown(); | |
1841 } | |
1842 | 1769 |
1843 virtual void SetIdentity(AliasIdentity identity) { | 1770 virtual void SetIdentity(AliasIdentity identity) { UNREACHABLE(); } |
1844 UNREACHABLE(); | |
1845 } | |
1846 | 1771 |
1847 Definition* OriginalDefinition(); | 1772 Definition* OriginalDefinition(); |
1848 | 1773 |
1849 virtual Definition* AsDefinition() { return this; } | 1774 virtual Definition* AsDefinition() { return this; } |
1850 | 1775 |
1851 protected: | 1776 protected: |
1852 friend class RangeAnalysis; | 1777 friend class RangeAnalysis; |
1853 friend class Value; | 1778 friend class Value; |
1854 | 1779 |
1855 Range* range_; | 1780 Range* range_; |
(...skipping 21 matching lines...) Expand all Loading... |
1877 | 1802 |
1878 inline void Value::BindToEnvironment(Definition* def) { | 1803 inline void Value::BindToEnvironment(Definition* def) { |
1879 RemoveFromUseList(); | 1804 RemoveFromUseList(); |
1880 set_definition(def); | 1805 set_definition(def); |
1881 def->AddEnvUse(this); | 1806 def->AddEnvUse(this); |
1882 } | 1807 } |
1883 | 1808 |
1884 | 1809 |
1885 class PureDefinition : public Definition { | 1810 class PureDefinition : public Definition { |
1886 public: | 1811 public: |
1887 explicit PureDefinition(intptr_t deopt_id) | 1812 explicit PureDefinition(intptr_t deopt_id) : Definition(deopt_id) {} |
1888 : Definition(deopt_id) { } | |
1889 | 1813 |
1890 virtual bool AllowsCSE() const { return true; } | 1814 virtual bool AllowsCSE() const { return true; } |
1891 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 1815 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
1892 | 1816 |
1893 virtual EffectSet Effects() const { return EffectSet::None(); } | 1817 virtual EffectSet Effects() const { return EffectSet::None(); } |
1894 }; | 1818 }; |
1895 | 1819 |
1896 | 1820 |
1897 template<intptr_t N, | 1821 template <intptr_t N, |
1898 typename ThrowsTrait, | 1822 typename ThrowsTrait, |
1899 template<typename Impure, typename Pure> class CSETrait = NoCSE> | 1823 template <typename Impure, typename Pure> class CSETrait = NoCSE> |
1900 class TemplateDefinition : public CSETrait<Definition, PureDefinition>::Base { | 1824 class TemplateDefinition : public CSETrait<Definition, PureDefinition>::Base { |
1901 public: | 1825 public: |
1902 explicit TemplateDefinition(intptr_t deopt_id = Thread::kNoDeoptId) | 1826 explicit TemplateDefinition(intptr_t deopt_id = Thread::kNoDeoptId) |
1903 : CSETrait<Definition, PureDefinition>::Base(deopt_id), inputs_() { } | 1827 : CSETrait<Definition, PureDefinition>::Base(deopt_id), inputs_() {} |
1904 | 1828 |
1905 virtual intptr_t InputCount() const { return N; } | 1829 virtual intptr_t InputCount() const { return N; } |
1906 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 1830 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
1907 | 1831 |
1908 virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } | 1832 virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } |
1909 | 1833 |
1910 protected: | 1834 protected: |
1911 EmbeddedArray<Value*, N> inputs_; | 1835 EmbeddedArray<Value*, N> inputs_; |
1912 | 1836 |
1913 private: | 1837 private: |
1914 friend class BranchInstr; | 1838 friend class BranchInstr; |
1915 friend class IfThenElseInstr; | 1839 friend class IfThenElseInstr; |
1916 | 1840 |
1917 virtual void RawSetInputAt(intptr_t i, Value* value) { | 1841 virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
1918 inputs_[i] = value; | |
1919 } | |
1920 }; | 1842 }; |
1921 | 1843 |
1922 | 1844 |
1923 struct BranchLabels { | 1845 struct BranchLabels { |
1924 Label* true_label; | 1846 Label* true_label; |
1925 Label* false_label; | 1847 Label* false_label; |
1926 Label* fall_through; | 1848 Label* fall_through; |
1927 }; | 1849 }; |
1928 | 1850 |
1929 | 1851 |
1930 class InductionVariableInfo; | 1852 class InductionVariableInfo; |
1931 | 1853 |
1932 | 1854 |
1933 class PhiInstr : public Definition { | 1855 class PhiInstr : public Definition { |
1934 public: | 1856 public: |
1935 PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) | 1857 PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) |
1936 : block_(block), | 1858 : block_(block), |
1937 inputs_(num_inputs), | 1859 inputs_(num_inputs), |
1938 representation_(kTagged), | 1860 representation_(kTagged), |
1939 reaching_defs_(NULL), | 1861 reaching_defs_(NULL), |
1940 loop_variable_info_(NULL), | 1862 loop_variable_info_(NULL), |
1941 is_alive_(false), | 1863 is_alive_(false), |
1942 is_receiver_(kUnknownReceiver) { | 1864 is_receiver_(kUnknownReceiver) { |
1943 for (intptr_t i = 0; i < num_inputs; ++i) { | 1865 for (intptr_t i = 0; i < num_inputs; ++i) { |
1944 inputs_.Add(NULL); | 1866 inputs_.Add(NULL); |
1945 } | 1867 } |
1946 } | 1868 } |
1947 | 1869 |
1948 // Get the block entry for that instruction. | 1870 // Get the block entry for that instruction. |
1949 virtual BlockEntryInstr* GetBlock() { return block(); } | 1871 virtual BlockEntryInstr* GetBlock() { return block(); } |
1950 JoinEntryInstr* block() const { return block_; } | 1872 JoinEntryInstr* block() const { return block_; } |
1951 | 1873 |
1952 virtual CompileType ComputeType() const; | 1874 virtual CompileType ComputeType() const; |
1953 virtual bool RecomputeType(); | 1875 virtual bool RecomputeType(); |
1954 | 1876 |
1955 intptr_t InputCount() const { return inputs_.length(); } | 1877 intptr_t InputCount() const { return inputs_.length(); } |
1956 | 1878 |
1957 Value* InputAt(intptr_t i) const { return inputs_[i]; } | 1879 Value* InputAt(intptr_t i) const { return inputs_[i]; } |
1958 | 1880 |
1959 virtual bool CanDeoptimize() const { return false; } | 1881 virtual bool CanDeoptimize() const { return false; } |
1960 | 1882 |
1961 virtual EffectSet Effects() const { return EffectSet::None(); } | 1883 virtual EffectSet Effects() const { return EffectSet::None(); } |
1962 | 1884 |
1963 // Phi is alive if it reaches a non-environment use. | 1885 // Phi is alive if it reaches a non-environment use. |
1964 bool is_alive() const { return is_alive_; } | 1886 bool is_alive() const { return is_alive_; } |
1965 void mark_alive() { is_alive_ = true; } | 1887 void mark_alive() { is_alive_ = true; } |
1966 void mark_dead() { is_alive_ = false; } | 1888 void mark_dead() { is_alive_ = false; } |
1967 | 1889 |
1968 virtual Representation RequiredInputRepresentation(intptr_t i) const { | 1890 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
1969 return representation_; | 1891 return representation_; |
1970 } | 1892 } |
1971 | 1893 |
1972 virtual Representation representation() const { | 1894 virtual Representation representation() const { return representation_; } |
1973 return representation_; | |
1974 } | |
1975 | 1895 |
1976 virtual void set_representation(Representation r) { | 1896 virtual void set_representation(Representation r) { representation_ = r; } |
1977 representation_ = r; | |
1978 } | |
1979 | 1897 |
1980 virtual intptr_t Hashcode() const { | 1898 virtual intptr_t Hashcode() const { |
1981 UNREACHABLE(); | 1899 UNREACHABLE(); |
1982 return 0; | 1900 return 0; |
1983 } | 1901 } |
1984 | 1902 |
1985 DECLARE_INSTRUCTION(Phi) | 1903 DECLARE_INSTRUCTION(Phi) |
1986 | 1904 |
1987 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 1905 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
1988 | 1906 |
1989 BitVector* reaching_defs() const { | 1907 BitVector* reaching_defs() const { return reaching_defs_; } |
1990 return reaching_defs_; | |
1991 } | |
1992 | 1908 |
1993 void set_reaching_defs(BitVector* reaching_defs) { | 1909 void set_reaching_defs(BitVector* reaching_defs) { |
1994 reaching_defs_ = reaching_defs; | 1910 reaching_defs_ = reaching_defs; |
1995 } | 1911 } |
1996 | 1912 |
1997 virtual bool MayThrow() const { return false; } | 1913 virtual bool MayThrow() const { return false; } |
1998 | 1914 |
1999 // A phi is redundant if all input operands are the same. | 1915 // A phi is redundant if all input operands are the same. |
2000 bool IsRedundant() const; | 1916 bool IsRedundant() const; |
2001 | 1917 |
2002 void set_induction_variable_info(InductionVariableInfo* info) { | 1918 void set_induction_variable_info(InductionVariableInfo* info) { |
2003 loop_variable_info_ = info; | 1919 loop_variable_info_ = info; |
2004 } | 1920 } |
2005 | 1921 |
2006 InductionVariableInfo* induction_variable_info() { | 1922 InductionVariableInfo* induction_variable_info() { |
2007 return loop_variable_info_; | 1923 return loop_variable_info_; |
2008 } | 1924 } |
2009 | 1925 |
2010 PRINT_TO_SUPPORT | 1926 PRINT_TO_SUPPORT |
2011 | 1927 |
2012 enum ReceiverType { | 1928 enum ReceiverType { kUnknownReceiver = -1, kNotReceiver = 0, kReceiver = 1 }; |
2013 kUnknownReceiver = -1, | |
2014 kNotReceiver = 0, | |
2015 kReceiver = 1 | |
2016 }; | |
2017 | 1929 |
2018 ReceiverType is_receiver() const { | 1930 ReceiverType is_receiver() const { |
2019 return static_cast<ReceiverType>(is_receiver_); | 1931 return static_cast<ReceiverType>(is_receiver_); |
2020 } | 1932 } |
2021 | 1933 |
2022 void set_is_receiver(ReceiverType is_receiver) { | 1934 void set_is_receiver(ReceiverType is_receiver) { is_receiver_ = is_receiver; } |
2023 is_receiver_ = is_receiver; | |
2024 } | |
2025 | 1935 |
2026 private: | 1936 private: |
2027 // Direct access to inputs_ in order to resize it due to unreachable | 1937 // Direct access to inputs_ in order to resize it due to unreachable |
2028 // predecessors. | 1938 // predecessors. |
2029 friend class ConstantPropagator; | 1939 friend class ConstantPropagator; |
2030 | 1940 |
2031 void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } | 1941 void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
2032 | 1942 |
2033 JoinEntryInstr* block_; | 1943 JoinEntryInstr* block_; |
2034 GrowableArray<Value*> inputs_; | 1944 GrowableArray<Value*> inputs_; |
2035 Representation representation_; | 1945 Representation representation_; |
2036 BitVector* reaching_defs_; | 1946 BitVector* reaching_defs_; |
2037 InductionVariableInfo* loop_variable_info_; | 1947 InductionVariableInfo* loop_variable_info_; |
2038 bool is_alive_; | 1948 bool is_alive_; |
2039 int8_t is_receiver_; | 1949 int8_t is_receiver_; |
2040 | 1950 |
2041 DISALLOW_COPY_AND_ASSIGN(PhiInstr); | 1951 DISALLOW_COPY_AND_ASSIGN(PhiInstr); |
2042 }; | 1952 }; |
2043 | 1953 |
2044 | 1954 |
2045 class ParameterInstr : public Definition { | 1955 class ParameterInstr : public Definition { |
2046 public: | 1956 public: |
2047 ParameterInstr(intptr_t index, | 1957 ParameterInstr(intptr_t index, |
2048 BlockEntryInstr* block, | 1958 BlockEntryInstr* block, |
2049 Register base_reg = FPREG) | 1959 Register base_reg = FPREG) |
2050 : index_(index), base_reg_(base_reg), block_(block) { } | 1960 : index_(index), base_reg_(base_reg), block_(block) {} |
2051 | 1961 |
2052 DECLARE_INSTRUCTION(Parameter) | 1962 DECLARE_INSTRUCTION(Parameter) |
2053 | 1963 |
2054 intptr_t index() const { return index_; } | 1964 intptr_t index() const { return index_; } |
2055 Register base_reg() const { return base_reg_; } | 1965 Register base_reg() const { return base_reg_; } |
2056 | 1966 |
2057 // Get the block entry for that instruction. | 1967 // Get the block entry for that instruction. |
2058 virtual BlockEntryInstr* GetBlock() { return block_; } | 1968 virtual BlockEntryInstr* GetBlock() { return block_; } |
2059 | 1969 |
2060 intptr_t InputCount() const { return 0; } | 1970 intptr_t InputCount() const { return 0; } |
(...skipping 24 matching lines...) Expand all Loading... |
2085 const intptr_t index_; | 1995 const intptr_t index_; |
2086 const Register base_reg_; | 1996 const Register base_reg_; |
2087 BlockEntryInstr* block_; | 1997 BlockEntryInstr* block_; |
2088 | 1998 |
2089 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); | 1999 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); |
2090 }; | 2000 }; |
2091 | 2001 |
2092 | 2002 |
2093 class PushArgumentInstr : public TemplateDefinition<1, NoThrow> { | 2003 class PushArgumentInstr : public TemplateDefinition<1, NoThrow> { |
2094 public: | 2004 public: |
2095 explicit PushArgumentInstr(Value* value) { | 2005 explicit PushArgumentInstr(Value* value) { SetInputAt(0, value); } |
2096 SetInputAt(0, value); | |
2097 } | |
2098 | 2006 |
2099 DECLARE_INSTRUCTION(PushArgument) | 2007 DECLARE_INSTRUCTION(PushArgument) |
2100 | 2008 |
2101 virtual CompileType ComputeType() const; | 2009 virtual CompileType ComputeType() const; |
2102 | 2010 |
2103 Value* value() const { return InputAt(0); } | 2011 Value* value() const { return InputAt(0); } |
2104 | 2012 |
2105 virtual bool CanDeoptimize() const { return false; } | 2013 virtual bool CanDeoptimize() const { return false; } |
2106 | 2014 |
2107 virtual EffectSet Effects() const { return EffectSet::None(); } | 2015 virtual EffectSet Effects() const { return EffectSet::None(); } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2149 const TokenPosition token_pos_; | 2057 const TokenPosition token_pos_; |
2150 | 2058 |
2151 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); | 2059 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); |
2152 }; | 2060 }; |
2153 | 2061 |
2154 | 2062 |
2155 class ThrowInstr : public TemplateInstruction<0, Throws> { | 2063 class ThrowInstr : public TemplateInstruction<0, Throws> { |
2156 public: | 2064 public: |
2157 explicit ThrowInstr(TokenPosition token_pos) | 2065 explicit ThrowInstr(TokenPosition token_pos) |
2158 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), | 2066 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), |
2159 token_pos_(token_pos) { | 2067 token_pos_(token_pos) {} |
2160 } | |
2161 | 2068 |
2162 DECLARE_INSTRUCTION(Throw) | 2069 DECLARE_INSTRUCTION(Throw) |
2163 | 2070 |
2164 virtual intptr_t ArgumentCount() const { return 1; } | 2071 virtual intptr_t ArgumentCount() const { return 1; } |
2165 | 2072 |
2166 virtual TokenPosition token_pos() const { return token_pos_; } | 2073 virtual TokenPosition token_pos() const { return token_pos_; } |
2167 | 2074 |
2168 virtual bool CanDeoptimize() const { return true; } | 2075 virtual bool CanDeoptimize() const { return true; } |
2169 | 2076 |
2170 virtual EffectSet Effects() const { return EffectSet::None(); } | 2077 virtual EffectSet Effects() const { return EffectSet::None(); } |
2171 | 2078 |
2172 private: | 2079 private: |
2173 const TokenPosition token_pos_; | 2080 const TokenPosition token_pos_; |
2174 | 2081 |
2175 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); | 2082 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); |
2176 }; | 2083 }; |
2177 | 2084 |
2178 | 2085 |
2179 class ReThrowInstr : public TemplateInstruction<0, Throws> { | 2086 class ReThrowInstr : public TemplateInstruction<0, Throws> { |
2180 public: | 2087 public: |
2181 // 'catch_try_index' can be CatchClauseNode::kInvalidTryIndex if the | 2088 // 'catch_try_index' can be CatchClauseNode::kInvalidTryIndex if the |
2182 // rethrow has been artifically generated by the parser. | 2089 // rethrow has been artifically generated by the parser. |
2183 ReThrowInstr(TokenPosition token_pos, intptr_t catch_try_index) | 2090 ReThrowInstr(TokenPosition token_pos, intptr_t catch_try_index) |
2184 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), | 2091 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), |
2185 token_pos_(token_pos), | 2092 token_pos_(token_pos), |
2186 catch_try_index_(catch_try_index) { | 2093 catch_try_index_(catch_try_index) {} |
2187 } | |
2188 | 2094 |
2189 DECLARE_INSTRUCTION(ReThrow) | 2095 DECLARE_INSTRUCTION(ReThrow) |
2190 | 2096 |
2191 virtual intptr_t ArgumentCount() const { return 2; } | 2097 virtual intptr_t ArgumentCount() const { return 2; } |
2192 | 2098 |
2193 virtual TokenPosition token_pos() const { return token_pos_; } | 2099 virtual TokenPosition token_pos() const { return token_pos_; } |
2194 intptr_t catch_try_index() const { return catch_try_index_; } | 2100 intptr_t catch_try_index() const { return catch_try_index_; } |
2195 | 2101 |
2196 virtual bool CanDeoptimize() const { return true; } | 2102 virtual bool CanDeoptimize() const { return true; } |
2197 | 2103 |
2198 virtual EffectSet Effects() const { return EffectSet::None(); } | 2104 virtual EffectSet Effects() const { return EffectSet::None(); } |
2199 | 2105 |
2200 private: | 2106 private: |
2201 const TokenPosition token_pos_; | 2107 const TokenPosition token_pos_; |
2202 const intptr_t catch_try_index_; | 2108 const intptr_t catch_try_index_; |
2203 | 2109 |
2204 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); | 2110 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); |
2205 }; | 2111 }; |
2206 | 2112 |
2207 | 2113 |
2208 class StopInstr : public TemplateInstruction<0, NoThrow> { | 2114 class StopInstr : public TemplateInstruction<0, NoThrow> { |
2209 public: | 2115 public: |
2210 explicit StopInstr(const char* message) | 2116 explicit StopInstr(const char* message) : message_(message) { |
2211 : message_(message) { | |
2212 ASSERT(message != NULL); | 2117 ASSERT(message != NULL); |
2213 } | 2118 } |
2214 | 2119 |
2215 const char* message() const { return message_; } | 2120 const char* message() const { return message_; } |
2216 | 2121 |
2217 DECLARE_INSTRUCTION(Stop); | 2122 DECLARE_INSTRUCTION(Stop); |
2218 | 2123 |
2219 virtual intptr_t ArgumentCount() const { return 0; } | 2124 virtual intptr_t ArgumentCount() const { return 0; } |
2220 | 2125 |
2221 virtual bool CanDeoptimize() const { return false; } | 2126 virtual bool CanDeoptimize() const { return false; } |
2222 | 2127 |
2223 virtual EffectSet Effects() const { return EffectSet::None(); } | 2128 virtual EffectSet Effects() const { return EffectSet::None(); } |
2224 | 2129 |
2225 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 2130 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
2226 | 2131 |
2227 private: | 2132 private: |
2228 const char* message_; | 2133 const char* message_; |
2229 | 2134 |
2230 DISALLOW_COPY_AND_ASSIGN(StopInstr); | 2135 DISALLOW_COPY_AND_ASSIGN(StopInstr); |
2231 }; | 2136 }; |
2232 | 2137 |
2233 | 2138 |
2234 class GotoInstr : public TemplateInstruction<0, NoThrow> { | 2139 class GotoInstr : public TemplateInstruction<0, NoThrow> { |
2235 public: | 2140 public: |
2236 explicit GotoInstr(JoinEntryInstr* entry) | 2141 explicit GotoInstr(JoinEntryInstr* entry) |
2237 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), | 2142 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), |
2238 block_(NULL), | 2143 block_(NULL), |
2239 successor_(entry), | 2144 successor_(entry), |
2240 edge_weight_(0.0), | 2145 edge_weight_(0.0), |
2241 parallel_move_(NULL) { | 2146 parallel_move_(NULL) {} |
2242 } | |
2243 | 2147 |
2244 DECLARE_INSTRUCTION(Goto) | 2148 DECLARE_INSTRUCTION(Goto) |
2245 | 2149 |
2246 BlockEntryInstr* block() const { return block_; } | 2150 BlockEntryInstr* block() const { return block_; } |
2247 void set_block(BlockEntryInstr* block) { block_ = block; } | 2151 void set_block(BlockEntryInstr* block) { block_ = block; } |
2248 | 2152 |
2249 JoinEntryInstr* successor() const { return successor_; } | 2153 JoinEntryInstr* successor() const { return successor_; } |
2250 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } | 2154 void set_successor(JoinEntryInstr* successor) { successor_ = successor; } |
2251 virtual intptr_t SuccessorCount() const; | 2155 virtual intptr_t SuccessorCount() const; |
2252 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 2156 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
2253 | 2157 |
2254 double edge_weight() const { return edge_weight_; } | 2158 double edge_weight() const { return edge_weight_; } |
2255 void set_edge_weight(double weight) { edge_weight_ = weight; } | 2159 void set_edge_weight(double weight) { edge_weight_ = weight; } |
2256 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } | 2160 void adjust_edge_weight(double scale_factor) { edge_weight_ *= scale_factor; } |
2257 | 2161 |
2258 virtual bool CanBecomeDeoptimizationTarget() const { | 2162 virtual bool CanBecomeDeoptimizationTarget() const { |
2259 // Goto instruction can be used as a deoptimization target when LICM | 2163 // Goto instruction can be used as a deoptimization target when LICM |
2260 // hoists instructions out of the loop. | 2164 // hoists instructions out of the loop. |
2261 return true; | 2165 return true; |
2262 } | 2166 } |
2263 | 2167 |
2264 virtual bool CanDeoptimize() const { return false; } | 2168 virtual bool CanDeoptimize() const { return false; } |
2265 | 2169 |
2266 virtual EffectSet Effects() const { return EffectSet::None(); } | 2170 virtual EffectSet Effects() const { return EffectSet::None(); } |
2267 | 2171 |
2268 ParallelMoveInstr* parallel_move() const { | 2172 ParallelMoveInstr* parallel_move() const { return parallel_move_; } |
2269 return parallel_move_; | |
2270 } | |
2271 | 2173 |
2272 bool HasParallelMove() const { | 2174 bool HasParallelMove() const { return parallel_move_ != NULL; } |
2273 return parallel_move_ != NULL; | |
2274 } | |
2275 | 2175 |
2276 bool HasNonRedundantParallelMove() const { | 2176 bool HasNonRedundantParallelMove() const { |
2277 return HasParallelMove() && !parallel_move()->IsRedundant(); | 2177 return HasParallelMove() && !parallel_move()->IsRedundant(); |
2278 } | 2178 } |
2279 | 2179 |
2280 ParallelMoveInstr* GetParallelMove() { | 2180 ParallelMoveInstr* GetParallelMove() { |
2281 if (parallel_move_ == NULL) { | 2181 if (parallel_move_ == NULL) { |
2282 parallel_move_ = new ParallelMoveInstr(); | 2182 parallel_move_ = new ParallelMoveInstr(); |
2283 } | 2183 } |
2284 return parallel_move_; | 2184 return parallel_move_; |
(...skipping 23 matching lines...) Expand all Loading... |
2308 // In order to preserve split-edge form, an indirect goto does not itself point | 2208 // In order to preserve split-edge form, an indirect goto does not itself point |
2309 // to its targets. Instead, for each possible target, the successors_ field | 2209 // to its targets. Instead, for each possible target, the successors_ field |
2310 // will contain an ordinary goto instruction that jumps to the target. | 2210 // will contain an ordinary goto instruction that jumps to the target. |
2311 // TODO(zerny): Implement direct support instead of embedding gotos. | 2211 // TODO(zerny): Implement direct support instead of embedding gotos. |
2312 // | 2212 // |
2313 // Byte offsets of all possible targets are stored in the offsets_ array. The | 2213 // Byte offsets of all possible targets are stored in the offsets_ array. The |
2314 // desired offset is looked up while the generated code is executing, and passed | 2214 // desired offset is looked up while the generated code is executing, and passed |
2315 // to IndirectGoto as an input. | 2215 // to IndirectGoto as an input. |
2316 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> { | 2216 class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> { |
2317 public: | 2217 public: |
2318 IndirectGotoInstr(TypedData* offsets, | 2218 IndirectGotoInstr(TypedData* offsets, Value* offset_from_start) |
2319 Value* offset_from_start) | 2219 : offsets_(*offsets) { |
2320 : offsets_(*offsets) { | |
2321 SetInputAt(0, offset_from_start); | 2220 SetInputAt(0, offset_from_start); |
2322 } | 2221 } |
2323 | 2222 |
2324 DECLARE_INSTRUCTION(IndirectGoto) | 2223 DECLARE_INSTRUCTION(IndirectGoto) |
2325 | 2224 |
2326 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2225 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
2327 ASSERT(idx == 0); | 2226 ASSERT(idx == 0); |
2328 return kNoRepresentation; | 2227 return kNoRepresentation; |
2329 } | 2228 } |
2330 | 2229 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 Token::Kind kind() const { return kind_; } | 2266 Token::Kind kind() const { return kind_; } |
2368 | 2267 |
2369 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; | 2268 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0; |
2370 | 2269 |
2371 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2270 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
2372 BranchInstr* branch) = 0; | 2271 BranchInstr* branch) = 0; |
2373 | 2272 |
2374 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 2273 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
2375 BranchLabels labels) = 0; | 2274 BranchLabels labels) = 0; |
2376 | 2275 |
2377 void SetDeoptId(const Instruction& instr) { | 2276 void SetDeoptId(const Instruction& instr) { CopyDeoptIdFrom(instr); } |
2378 CopyDeoptIdFrom(instr); | |
2379 } | |
2380 | 2277 |
2381 // Operation class id is computed from collected ICData. | 2278 // Operation class id is computed from collected ICData. |
2382 void set_operation_cid(intptr_t value) { operation_cid_ = value; } | 2279 void set_operation_cid(intptr_t value) { operation_cid_ = value; } |
2383 intptr_t operation_cid() const { return operation_cid_; } | 2280 intptr_t operation_cid() const { return operation_cid_; } |
2384 | 2281 |
2385 virtual void NegateComparison() { | 2282 virtual void NegateComparison() { kind_ = Token::NegateComparison(kind_); } |
2386 kind_ = Token::NegateComparison(kind_); | |
2387 } | |
2388 | 2283 |
2389 virtual bool CanBecomeDeoptimizationTarget() const { return true; } | 2284 virtual bool CanBecomeDeoptimizationTarget() const { return true; } |
2390 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } | 2285 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } |
2391 | 2286 |
2392 virtual bool AttributesEqual(Instruction* other) const { | 2287 virtual bool AttributesEqual(Instruction* other) const { |
2393 ComparisonInstr* other_comparison = other->AsComparison(); | 2288 ComparisonInstr* other_comparison = other->AsComparison(); |
2394 return kind() == other_comparison->kind() && | 2289 return kind() == other_comparison->kind() && |
2395 (operation_cid() == other_comparison->operation_cid()); | 2290 (operation_cid() == other_comparison->operation_cid()); |
2396 } | 2291 } |
2397 | 2292 |
2398 DEFINE_INSTRUCTION_TYPE_CHECK(Comparison) | 2293 DEFINE_INSTRUCTION_TYPE_CHECK(Comparison) |
2399 | 2294 |
2400 protected: | 2295 protected: |
2401 ComparisonInstr(TokenPosition token_pos, | 2296 ComparisonInstr(TokenPosition token_pos, |
2402 Token::Kind kind, | 2297 Token::Kind kind, |
2403 intptr_t deopt_id = Thread::kNoDeoptId) | 2298 intptr_t deopt_id = Thread::kNoDeoptId) |
2404 : Definition(deopt_id), | 2299 : Definition(deopt_id), |
2405 token_pos_(token_pos), | 2300 token_pos_(token_pos), |
2406 kind_(kind), | 2301 kind_(kind), |
2407 operation_cid_(kIllegalCid) { | 2302 operation_cid_(kIllegalCid) {} |
2408 } | |
2409 | 2303 |
2410 private: | 2304 private: |
2411 const TokenPosition token_pos_; | 2305 const TokenPosition token_pos_; |
2412 Token::Kind kind_; | 2306 Token::Kind kind_; |
2413 intptr_t operation_cid_; // Set by optimizer. | 2307 intptr_t operation_cid_; // Set by optimizer. |
2414 | 2308 |
2415 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr); | 2309 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr); |
2416 }; | 2310 }; |
2417 | 2311 |
2418 | 2312 |
2419 class PureComparison : public ComparisonInstr { | 2313 class PureComparison : public ComparisonInstr { |
2420 public: | 2314 public: |
2421 virtual bool AllowsCSE() const { return true; } | 2315 virtual bool AllowsCSE() const { return true; } |
2422 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 2316 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
2423 | 2317 |
2424 virtual EffectSet Effects() const { return EffectSet::None(); } | 2318 virtual EffectSet Effects() const { return EffectSet::None(); } |
2425 | 2319 |
2426 protected: | 2320 protected: |
2427 PureComparison(TokenPosition token_pos, Token::Kind kind, intptr_t deopt_id) | 2321 PureComparison(TokenPosition token_pos, Token::Kind kind, intptr_t deopt_id) |
2428 : ComparisonInstr(token_pos, kind, deopt_id) { } | 2322 : ComparisonInstr(token_pos, kind, deopt_id) {} |
2429 }; | 2323 }; |
2430 | 2324 |
2431 | 2325 |
2432 template<intptr_t N, | 2326 template <intptr_t N, |
2433 typename ThrowsTrait, | 2327 typename ThrowsTrait, |
2434 template<typename Impure, typename Pure> class CSETrait = NoCSE> | 2328 template <typename Impure, typename Pure> class CSETrait = NoCSE> |
2435 class TemplateComparison : public CSETrait< | 2329 class TemplateComparison |
2436 ComparisonInstr, PureComparison>::Base { | 2330 : public CSETrait<ComparisonInstr, PureComparison>::Base { |
2437 public: | 2331 public: |
2438 TemplateComparison(TokenPosition token_pos, | 2332 TemplateComparison(TokenPosition token_pos, |
2439 Token::Kind kind, | 2333 Token::Kind kind, |
2440 intptr_t deopt_id = Thread::kNoDeoptId) | 2334 intptr_t deopt_id = Thread::kNoDeoptId) |
2441 : CSETrait<ComparisonInstr, PureComparison>::Base( | 2335 : CSETrait<ComparisonInstr, PureComparison>::Base(token_pos, |
2442 token_pos, kind, deopt_id), | 2336 kind, |
2443 inputs_() { } | 2337 deopt_id), |
| 2338 inputs_() {} |
2444 | 2339 |
2445 virtual intptr_t InputCount() const { return N; } | 2340 virtual intptr_t InputCount() const { return N; } |
2446 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 2341 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
2447 | 2342 |
2448 virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } | 2343 virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } |
2449 | 2344 |
2450 protected: | 2345 protected: |
2451 EmbeddedArray<Value*, N> inputs_; | 2346 EmbeddedArray<Value*, N> inputs_; |
2452 | 2347 |
2453 private: | 2348 private: |
2454 virtual void RawSetInputAt(intptr_t i, Value* value) { | 2349 virtual void RawSetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
2455 inputs_[i] = value; | |
2456 } | |
2457 }; | 2350 }; |
2458 | 2351 |
2459 | 2352 |
2460 class BranchInstr : public Instruction { | 2353 class BranchInstr : public Instruction { |
2461 public: | 2354 public: |
2462 explicit BranchInstr(ComparisonInstr* comparison) | 2355 explicit BranchInstr(ComparisonInstr* comparison) |
2463 : Instruction(Thread::Current()->GetNextDeoptId()), | 2356 : Instruction(Thread::Current()->GetNextDeoptId()), |
2464 comparison_(comparison), | 2357 comparison_(comparison), |
2465 is_checked_(false), | 2358 is_checked_(false), |
2466 constrained_type_(NULL), | 2359 constrained_type_(NULL), |
(...skipping 19 matching lines...) Expand all Loading... |
2486 virtual bool CanDeoptimize() const { | 2379 virtual bool CanDeoptimize() const { |
2487 // Branches need a deoptimization info in checked mode if they | 2380 // Branches need a deoptimization info in checked mode if they |
2488 // can throw a type check error. | 2381 // can throw a type check error. |
2489 return comparison()->CanDeoptimize() || is_checked(); | 2382 return comparison()->CanDeoptimize() || is_checked(); |
2490 } | 2383 } |
2491 | 2384 |
2492 virtual bool CanBecomeDeoptimizationTarget() const { | 2385 virtual bool CanBecomeDeoptimizationTarget() const { |
2493 return comparison()->CanBecomeDeoptimizationTarget(); | 2386 return comparison()->CanBecomeDeoptimizationTarget(); |
2494 } | 2387 } |
2495 | 2388 |
2496 virtual EffectSet Effects() const { | 2389 virtual EffectSet Effects() const { return comparison()->Effects(); } |
2497 return comparison()->Effects(); | |
2498 } | |
2499 | 2390 |
2500 ComparisonInstr* comparison() const { return comparison_; } | 2391 ComparisonInstr* comparison() const { return comparison_; } |
2501 void SetComparison(ComparisonInstr* comp); | 2392 void SetComparison(ComparisonInstr* comp); |
2502 | 2393 |
2503 void set_is_checked(bool value) { is_checked_ = value; } | 2394 void set_is_checked(bool value) { is_checked_ = value; } |
2504 bool is_checked() const { return is_checked_; } | 2395 bool is_checked() const { return is_checked_; } |
2505 | 2396 |
2506 virtual intptr_t DeoptimizationTarget() const { | 2397 virtual intptr_t DeoptimizationTarget() const { |
2507 return comparison()->DeoptimizationTarget(); | 2398 return comparison()->DeoptimizationTarget(); |
2508 } | 2399 } |
2509 | 2400 |
2510 virtual Representation RequiredInputRepresentation(intptr_t i) const { | 2401 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
2511 return comparison()->RequiredInputRepresentation(i); | 2402 return comparison()->RequiredInputRepresentation(i); |
2512 } | 2403 } |
2513 | 2404 |
2514 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 2405 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
2515 | 2406 |
2516 // Set compile type constrained by the comparison of this branch. | 2407 // Set compile type constrained by the comparison of this branch. |
2517 // FlowGraphPropagator propagates it downwards into either true or false | 2408 // FlowGraphPropagator propagates it downwards into either true or false |
2518 // successor. | 2409 // successor. |
2519 void set_constrained_type(ConstrainedCompileType* type) { | 2410 void set_constrained_type(ConstrainedCompileType* type) { |
2520 constrained_type_ = type; | 2411 constrained_type_ = type; |
2521 } | 2412 } |
2522 | 2413 |
2523 // Return compile type constrained by the comparison of this branch. | 2414 // Return compile type constrained by the comparison of this branch. |
2524 ConstrainedCompileType* constrained_type() const { | 2415 ConstrainedCompileType* constrained_type() const { return constrained_type_; } |
2525 return constrained_type_; | |
2526 } | |
2527 | 2416 |
2528 void set_constant_target(TargetEntryInstr* target) { | 2417 void set_constant_target(TargetEntryInstr* target) { |
2529 ASSERT(target == true_successor() || target == false_successor()); | 2418 ASSERT(target == true_successor() || target == false_successor()); |
2530 constant_target_ = target; | 2419 constant_target_ = target; |
2531 } | 2420 } |
2532 TargetEntryInstr* constant_target() const { | 2421 TargetEntryInstr* constant_target() const { return constant_target_; } |
2533 return constant_target_; | |
2534 } | |
2535 | 2422 |
2536 virtual void InheritDeoptTarget(Zone* zone, Instruction* other); | 2423 virtual void InheritDeoptTarget(Zone* zone, Instruction* other); |
2537 | 2424 |
2538 virtual bool MayThrow() const { | 2425 virtual bool MayThrow() const { return comparison()->MayThrow(); } |
2539 return comparison()->MayThrow(); | |
2540 } | |
2541 | 2426 |
2542 TargetEntryInstr* true_successor() const { return true_successor_; } | 2427 TargetEntryInstr* true_successor() const { return true_successor_; } |
2543 TargetEntryInstr* false_successor() const { return false_successor_; } | 2428 TargetEntryInstr* false_successor() const { return false_successor_; } |
2544 | 2429 |
2545 TargetEntryInstr** true_successor_address() { return &true_successor_; } | 2430 TargetEntryInstr** true_successor_address() { return &true_successor_; } |
2546 TargetEntryInstr** false_successor_address() { return &false_successor_; } | 2431 TargetEntryInstr** false_successor_address() { return &false_successor_; } |
2547 | 2432 |
2548 virtual intptr_t SuccessorCount() const; | 2433 virtual intptr_t SuccessorCount() const; |
2549 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 2434 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
2550 | 2435 |
(...skipping 11 matching lines...) Expand all Loading... |
2562 ConstrainedCompileType* constrained_type_; | 2447 ConstrainedCompileType* constrained_type_; |
2563 TargetEntryInstr* constant_target_; | 2448 TargetEntryInstr* constant_target_; |
2564 | 2449 |
2565 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 2450 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
2566 }; | 2451 }; |
2567 | 2452 |
2568 | 2453 |
2569 class DeoptimizeInstr : public TemplateInstruction<0, NoThrow, Pure> { | 2454 class DeoptimizeInstr : public TemplateInstruction<0, NoThrow, Pure> { |
2570 public: | 2455 public: |
2571 DeoptimizeInstr(ICData::DeoptReasonId deopt_reason, intptr_t deopt_id) | 2456 DeoptimizeInstr(ICData::DeoptReasonId deopt_reason, intptr_t deopt_id) |
2572 : TemplateInstruction(deopt_id), | 2457 : TemplateInstruction(deopt_id), deopt_reason_(deopt_reason) {} |
2573 deopt_reason_(deopt_reason) { | |
2574 } | |
2575 | 2458 |
2576 virtual bool CanDeoptimize() const { return true; } | 2459 virtual bool CanDeoptimize() const { return true; } |
2577 | 2460 |
2578 virtual bool AttributesEqual(Instruction* other) const { | 2461 virtual bool AttributesEqual(Instruction* other) const { return true; } |
2579 return true; | |
2580 } | |
2581 | 2462 |
2582 DECLARE_INSTRUCTION(Deoptimize) | 2463 DECLARE_INSTRUCTION(Deoptimize) |
2583 | 2464 |
2584 private: | 2465 private: |
2585 const ICData::DeoptReasonId deopt_reason_; | 2466 const ICData::DeoptReasonId deopt_reason_; |
2586 | 2467 |
2587 DISALLOW_COPY_AND_ASSIGN(DeoptimizeInstr); | 2468 DISALLOW_COPY_AND_ASSIGN(DeoptimizeInstr); |
2588 }; | 2469 }; |
2589 | 2470 |
2590 | 2471 |
2591 class RedefinitionInstr : public TemplateDefinition<1, NoThrow> { | 2472 class RedefinitionInstr : public TemplateDefinition<1, NoThrow> { |
2592 public: | 2473 public: |
2593 explicit RedefinitionInstr(Value* value) { | 2474 explicit RedefinitionInstr(Value* value) { SetInputAt(0, value); } |
2594 SetInputAt(0, value); | |
2595 } | |
2596 | 2475 |
2597 DECLARE_INSTRUCTION(Redefinition) | 2476 DECLARE_INSTRUCTION(Redefinition) |
2598 | 2477 |
2599 Value* value() const { return inputs_[0]; } | 2478 Value* value() const { return inputs_[0]; } |
2600 | 2479 |
2601 virtual CompileType ComputeType() const; | 2480 virtual CompileType ComputeType() const; |
2602 virtual bool RecomputeType(); | 2481 virtual bool RecomputeType(); |
2603 | 2482 |
2604 virtual bool CanDeoptimize() const { return false; } | 2483 virtual bool CanDeoptimize() const { return false; } |
2605 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 2484 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
2606 virtual EffectSet Effects() const { return EffectSet::None(); } | 2485 virtual EffectSet Effects() const { return EffectSet::None(); } |
2607 | 2486 |
2608 private: | 2487 private: |
2609 DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr); | 2488 DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr); |
2610 }; | 2489 }; |
2611 | 2490 |
2612 | 2491 |
2613 class ConstraintInstr : public TemplateDefinition<1, NoThrow> { | 2492 class ConstraintInstr : public TemplateDefinition<1, NoThrow> { |
2614 public: | 2493 public: |
2615 ConstraintInstr(Value* value, Range* constraint) | 2494 ConstraintInstr(Value* value, Range* constraint) |
2616 : constraint_(constraint), | 2495 : constraint_(constraint), target_(NULL) { |
2617 target_(NULL) { | |
2618 SetInputAt(0, value); | 2496 SetInputAt(0, value); |
2619 } | 2497 } |
2620 | 2498 |
2621 DECLARE_INSTRUCTION(Constraint) | 2499 DECLARE_INSTRUCTION(Constraint) |
2622 | 2500 |
2623 virtual CompileType ComputeType() const; | 2501 virtual CompileType ComputeType() const; |
2624 | 2502 |
2625 virtual bool CanDeoptimize() const { return false; } | 2503 virtual bool CanDeoptimize() const { return false; } |
2626 | 2504 |
2627 virtual EffectSet Effects() const { return EffectSet::None(); } | 2505 virtual EffectSet Effects() const { return EffectSet::None(); } |
2628 | 2506 |
2629 virtual bool AttributesEqual(Instruction* other) const { | 2507 virtual bool AttributesEqual(Instruction* other) const { |
2630 UNREACHABLE(); | 2508 UNREACHABLE(); |
2631 return false; | 2509 return false; |
2632 } | 2510 } |
2633 | 2511 |
2634 Value* value() const { return inputs_[0]; } | 2512 Value* value() const { return inputs_[0]; } |
2635 Range* constraint() const { return constraint_; } | 2513 Range* constraint() const { return constraint_; } |
2636 | 2514 |
2637 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 2515 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
2638 | 2516 |
2639 // Constraints for branches have their target block stored in order | 2517 // Constraints for branches have their target block stored in order |
2640 // to find the comparison that generated the constraint: | 2518 // to find the comparison that generated the constraint: |
2641 // target->predecessor->last_instruction->comparison. | 2519 // target->predecessor->last_instruction->comparison. |
2642 void set_target(TargetEntryInstr* target) { | 2520 void set_target(TargetEntryInstr* target) { target_ = target; } |
2643 target_ = target; | 2521 TargetEntryInstr* target() const { return target_; } |
2644 } | |
2645 TargetEntryInstr* target() const { | |
2646 return target_; | |
2647 } | |
2648 | 2522 |
2649 PRINT_OPERANDS_TO_SUPPORT | 2523 PRINT_OPERANDS_TO_SUPPORT |
2650 | 2524 |
2651 private: | 2525 private: |
2652 Range* constraint_; | 2526 Range* constraint_; |
2653 TargetEntryInstr* target_; | 2527 TargetEntryInstr* target_; |
2654 | 2528 |
2655 DISALLOW_COPY_AND_ASSIGN(ConstraintInstr); | 2529 DISALLOW_COPY_AND_ASSIGN(ConstraintInstr); |
2656 }; | 2530 }; |
2657 | 2531 |
(...skipping 29 matching lines...) Expand all Loading... |
2687 | 2561 |
2688 | 2562 |
2689 // Merged ConstantInstr -> UnboxedXXX into UnboxedConstantInstr. | 2563 // Merged ConstantInstr -> UnboxedXXX into UnboxedConstantInstr. |
2690 // TODO(srdjan): Implemented currently for doubles only, should implement | 2564 // TODO(srdjan): Implemented currently for doubles only, should implement |
2691 // for other unboxing instructions. | 2565 // for other unboxing instructions. |
2692 class UnboxedConstantInstr : public ConstantInstr { | 2566 class UnboxedConstantInstr : public ConstantInstr { |
2693 public: | 2567 public: |
2694 explicit UnboxedConstantInstr(const Object& value, | 2568 explicit UnboxedConstantInstr(const Object& value, |
2695 Representation representation); | 2569 Representation representation); |
2696 | 2570 |
2697 virtual Representation representation() const { | 2571 virtual Representation representation() const { return representation_; } |
2698 return representation_; | |
2699 } | |
2700 | 2572 |
2701 // Either NULL or the address of the unboxed constant. | 2573 // Either NULL or the address of the unboxed constant. |
2702 uword constant_address() const { return constant_address_; } | 2574 uword constant_address() const { return constant_address_; } |
2703 | 2575 |
2704 DECLARE_INSTRUCTION(UnboxedConstant) | 2576 DECLARE_INSTRUCTION(UnboxedConstant) |
2705 | 2577 |
2706 private: | 2578 private: |
2707 const Representation representation_; | 2579 const Representation representation_; |
2708 uword constant_address_; // Either NULL or points to the untagged constant. | 2580 uword constant_address_; // Either NULL or points to the untagged constant. |
2709 | 2581 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2795 | 2667 |
2796 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); | 2668 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); |
2797 }; | 2669 }; |
2798 | 2670 |
2799 | 2671 |
2800 // Denotes the current context, normally held in a register. This is | 2672 // Denotes the current context, normally held in a register. This is |
2801 // a computation, not a value, because it's mutable. | 2673 // a computation, not a value, because it's mutable. |
2802 class CurrentContextInstr : public TemplateDefinition<0, NoThrow> { | 2674 class CurrentContextInstr : public TemplateDefinition<0, NoThrow> { |
2803 public: | 2675 public: |
2804 CurrentContextInstr() | 2676 CurrentContextInstr() |
2805 : TemplateDefinition(Thread::Current()->GetNextDeoptId()) { | 2677 : TemplateDefinition(Thread::Current()->GetNextDeoptId()) {} |
2806 } | |
2807 | 2678 |
2808 DECLARE_INSTRUCTION(CurrentContext) | 2679 DECLARE_INSTRUCTION(CurrentContext) |
2809 virtual CompileType ComputeType() const; | 2680 virtual CompileType ComputeType() const; |
2810 | 2681 |
2811 virtual bool CanDeoptimize() const { return false; } | 2682 virtual bool CanDeoptimize() const { return false; } |
2812 | 2683 |
2813 virtual EffectSet Effects() const { return EffectSet::None(); } | 2684 virtual EffectSet Effects() const { return EffectSet::None(); } |
2814 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 2685 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
2815 virtual bool AttributesEqual(Instruction* other) const { return true; } | 2686 virtual bool AttributesEqual(Instruction* other) const { return true; } |
2816 | 2687 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2891 ic_data_ = GetICData(ic_data_array); | 2762 ic_data_ = GetICData(ic_data_array); |
2892 ASSERT(function_name.IsNotTemporaryScopedHandle()); | 2763 ASSERT(function_name.IsNotTemporaryScopedHandle()); |
2893 ASSERT(!arguments->is_empty()); | 2764 ASSERT(!arguments->is_empty()); |
2894 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); | 2765 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); |
2895 ASSERT(Token::IsBinaryOperator(token_kind) || | 2766 ASSERT(Token::IsBinaryOperator(token_kind) || |
2896 Token::IsEqualityOperator(token_kind) || | 2767 Token::IsEqualityOperator(token_kind) || |
2897 Token::IsRelationalOperator(token_kind) || | 2768 Token::IsRelationalOperator(token_kind) || |
2898 Token::IsUnaryOperator(token_kind) || | 2769 Token::IsUnaryOperator(token_kind) || |
2899 Token::IsIndexOperator(token_kind) || | 2770 Token::IsIndexOperator(token_kind) || |
2900 Token::IsTypeTestOperator(token_kind) || | 2771 Token::IsTypeTestOperator(token_kind) || |
2901 Token::IsTypeCastOperator(token_kind) || | 2772 Token::IsTypeCastOperator(token_kind) || token_kind == Token::kGET || |
2902 token_kind == Token::kGET || | 2773 token_kind == Token::kSET || token_kind == Token::kILLEGAL); |
2903 token_kind == Token::kSET || | |
2904 token_kind == Token::kILLEGAL); | |
2905 } | 2774 } |
2906 | 2775 |
2907 DECLARE_INSTRUCTION(InstanceCall) | 2776 DECLARE_INSTRUCTION(InstanceCall) |
2908 | 2777 |
2909 const ICData* ic_data() const { return ic_data_; } | 2778 const ICData* ic_data() const { return ic_data_; } |
2910 bool HasICData() const { | 2779 bool HasICData() const { return (ic_data() != NULL) && !ic_data()->IsNull(); } |
2911 return (ic_data() != NULL) && !ic_data()->IsNull(); | |
2912 } | |
2913 | 2780 |
2914 // ICData can be replaced by optimizer. | 2781 // ICData can be replaced by optimizer. |
2915 void set_ic_data(const ICData* value) { ic_data_ = value; } | 2782 void set_ic_data(const ICData* value) { ic_data_ = value; } |
2916 | 2783 |
2917 virtual TokenPosition token_pos() const { return token_pos_; } | 2784 virtual TokenPosition token_pos() const { return token_pos_; } |
2918 const String& function_name() const { return function_name_; } | 2785 const String& function_name() const { return function_name_; } |
2919 Token::Kind token_kind() const { return token_kind_; } | 2786 Token::Kind token_kind() const { return token_kind_; } |
2920 virtual intptr_t ArgumentCount() const { return arguments_->length(); } | 2787 virtual intptr_t ArgumentCount() const { return arguments_->length(); } |
2921 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { | 2788 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { |
2922 return (*arguments_)[index]; | 2789 return (*arguments_)[index]; |
2923 } | 2790 } |
2924 const Array& argument_names() const { return argument_names_; } | 2791 const Array& argument_names() const { return argument_names_; } |
2925 intptr_t checked_argument_count() const { return checked_argument_count_; } | 2792 intptr_t checked_argument_count() const { return checked_argument_count_; } |
2926 | 2793 |
2927 bool has_unique_selector() const { return has_unique_selector_; } | 2794 bool has_unique_selector() const { return has_unique_selector_; } |
2928 void set_has_unique_selector(bool b) { | 2795 void set_has_unique_selector(bool b) { has_unique_selector_ = b; } |
2929 has_unique_selector_ = b; | |
2930 } | |
2931 | 2796 |
2932 virtual bool CanDeoptimize() const { return true; } | 2797 virtual bool CanDeoptimize() const { return true; } |
2933 | 2798 |
2934 virtual bool CanBecomeDeoptimizationTarget() const { | 2799 virtual bool CanBecomeDeoptimizationTarget() const { |
2935 // Instance calls that are specialized by the optimizer need a | 2800 // Instance calls that are specialized by the optimizer need a |
2936 // deoptimization descriptor before the call. | 2801 // deoptimization descriptor before the call. |
2937 return true; | 2802 return true; |
2938 } | 2803 } |
2939 | 2804 |
2940 virtual EffectSet Effects() const { return EffectSet::All(); } | 2805 virtual EffectSet Effects() const { return EffectSet::All(); } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3030 DECLARE_INSTRUCTION(StrictCompare) | 2895 DECLARE_INSTRUCTION(StrictCompare) |
3031 | 2896 |
3032 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); | 2897 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
3033 | 2898 |
3034 virtual CompileType ComputeType() const; | 2899 virtual CompileType ComputeType() const; |
3035 | 2900 |
3036 virtual bool CanDeoptimize() const { return false; } | 2901 virtual bool CanDeoptimize() const { return false; } |
3037 | 2902 |
3038 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 2903 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
3039 | 2904 |
3040 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2905 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
3041 BranchInstr* branch); | |
3042 | 2906 |
3043 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 2907 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
3044 BranchLabels labels); | 2908 BranchLabels labels); |
3045 | 2909 |
3046 bool needs_number_check() const { return needs_number_check_; } | 2910 bool needs_number_check() const { return needs_number_check_; } |
3047 void set_needs_number_check(bool value) { needs_number_check_ = value; } | 2911 void set_needs_number_check(bool value) { needs_number_check_ = value; } |
3048 | 2912 |
3049 bool AttributesEqual(Instruction* other) const; | 2913 bool AttributesEqual(Instruction* other) const; |
3050 | 2914 |
3051 PRINT_OPERANDS_TO_SUPPORT | 2915 PRINT_OPERANDS_TO_SUPPORT |
(...skipping 26 matching lines...) Expand all Loading... |
3078 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); | 2942 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
3079 | 2943 |
3080 virtual CompileType ComputeType() const; | 2944 virtual CompileType ComputeType() const; |
3081 | 2945 |
3082 virtual bool CanDeoptimize() const { return false; } | 2946 virtual bool CanDeoptimize() const { return false; } |
3083 | 2947 |
3084 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2948 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
3085 return kTagged; | 2949 return kTagged; |
3086 } | 2950 } |
3087 | 2951 |
3088 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2952 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
3089 BranchInstr* branch); | |
3090 | 2953 |
3091 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 2954 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
3092 BranchLabels labels); | 2955 BranchLabels labels); |
3093 | 2956 |
3094 private: | 2957 private: |
3095 DISALLOW_COPY_AND_ASSIGN(TestSmiInstr); | 2958 DISALLOW_COPY_AND_ASSIGN(TestSmiInstr); |
3096 }; | 2959 }; |
3097 | 2960 |
3098 | 2961 |
3099 // Checks the input value cid against cids stored in a table and returns either | 2962 // Checks the input value cid against cids stored in a table and returns either |
(...skipping 28 matching lines...) Expand all Loading... |
3128 virtual bool CanDeoptimize() const { | 2991 virtual bool CanDeoptimize() const { |
3129 return GetDeoptId() != Thread::kNoDeoptId; | 2992 return GetDeoptId() != Thread::kNoDeoptId; |
3130 } | 2993 } |
3131 | 2994 |
3132 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2995 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
3133 return kTagged; | 2996 return kTagged; |
3134 } | 2997 } |
3135 | 2998 |
3136 virtual bool AttributesEqual(Instruction* other) const; | 2999 virtual bool AttributesEqual(Instruction* other) const; |
3137 | 3000 |
3138 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 3001 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
3139 BranchInstr* branch); | |
3140 | 3002 |
3141 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 3003 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
3142 BranchLabels labels); | 3004 BranchLabels labels); |
3143 | 3005 |
3144 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } | 3006 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } |
3145 | 3007 |
3146 PRINT_OPERANDS_TO_SUPPORT | 3008 PRINT_OPERANDS_TO_SUPPORT |
3147 | 3009 |
3148 private: | 3010 private: |
3149 const ZoneGrowableArray<intptr_t>& cid_results_; | 3011 const ZoneGrowableArray<intptr_t>& cid_results_; |
(...skipping 18 matching lines...) Expand all Loading... |
3168 } | 3030 } |
3169 | 3031 |
3170 DECLARE_INSTRUCTION(EqualityCompare) | 3032 DECLARE_INSTRUCTION(EqualityCompare) |
3171 | 3033 |
3172 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); | 3034 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
3173 | 3035 |
3174 virtual CompileType ComputeType() const; | 3036 virtual CompileType ComputeType() const; |
3175 | 3037 |
3176 virtual bool CanDeoptimize() const { return false; } | 3038 virtual bool CanDeoptimize() const { return false; } |
3177 | 3039 |
3178 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 3040 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
3179 BranchInstr* branch); | |
3180 | 3041 |
3181 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 3042 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
3182 BranchLabels labels); | 3043 BranchLabels labels); |
3183 | 3044 |
3184 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 3045 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
3185 ASSERT((idx == 0) || (idx == 1)); | 3046 ASSERT((idx == 0) || (idx == 1)); |
3186 if (operation_cid() == kDoubleCid) return kUnboxedDouble; | 3047 if (operation_cid() == kDoubleCid) return kUnboxedDouble; |
3187 if (operation_cid() == kMintCid) return kUnboxedMint; | 3048 if (operation_cid() == kMintCid) return kUnboxedMint; |
3188 return kTagged; | 3049 return kTagged; |
3189 } | 3050 } |
(...skipping 21 matching lines...) Expand all Loading... |
3211 } | 3072 } |
3212 | 3073 |
3213 DECLARE_INSTRUCTION(RelationalOp) | 3074 DECLARE_INSTRUCTION(RelationalOp) |
3214 | 3075 |
3215 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); | 3076 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
3216 | 3077 |
3217 virtual CompileType ComputeType() const; | 3078 virtual CompileType ComputeType() const; |
3218 | 3079 |
3219 virtual bool CanDeoptimize() const { return false; } | 3080 virtual bool CanDeoptimize() const { return false; } |
3220 | 3081 |
3221 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 3082 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
3222 BranchInstr* branch); | |
3223 | 3083 |
3224 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 3084 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
3225 BranchLabels labels); | 3085 BranchLabels labels); |
3226 | 3086 |
3227 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 3087 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
3228 ASSERT((idx == 0) || (idx == 1)); | 3088 ASSERT((idx == 0) || (idx == 1)); |
3229 if (operation_cid() == kDoubleCid) return kUnboxedDouble; | 3089 if (operation_cid() == kDoubleCid) return kUnboxedDouble; |
3230 if (operation_cid() == kMintCid) return kUnboxedMint; | 3090 if (operation_cid() == kMintCid) return kUnboxedMint; |
3231 return kTagged; | 3091 return kTagged; |
3232 } | 3092 } |
3233 | 3093 |
3234 PRINT_OPERANDS_TO_SUPPORT | 3094 PRINT_OPERANDS_TO_SUPPORT |
3235 | 3095 |
3236 private: | 3096 private: |
3237 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); | 3097 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); |
3238 }; | 3098 }; |
3239 | 3099 |
3240 | 3100 |
3241 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for | 3101 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for |
3242 // materialization of true and false constants. | 3102 // materialization of true and false constants. |
3243 class IfThenElseInstr : public Definition { | 3103 class IfThenElseInstr : public Definition { |
3244 public: | 3104 public: |
3245 IfThenElseInstr(ComparisonInstr* comparison, | 3105 IfThenElseInstr(ComparisonInstr* comparison, Value* if_true, Value* if_false) |
3246 Value* if_true, | |
3247 Value* if_false) | |
3248 : Definition(Thread::Current()->GetNextDeoptId()), | 3106 : Definition(Thread::Current()->GetNextDeoptId()), |
3249 comparison_(comparison), | 3107 comparison_(comparison), |
3250 if_true_(Smi::Cast(if_true->BoundConstant()).Value()), | 3108 if_true_(Smi::Cast(if_true->BoundConstant()).Value()), |
3251 if_false_(Smi::Cast(if_false->BoundConstant()).Value()) { | 3109 if_false_(Smi::Cast(if_false->BoundConstant()).Value()) { |
3252 // Adjust uses at the comparison. | 3110 // Adjust uses at the comparison. |
3253 ASSERT(comparison->env() == NULL); | 3111 ASSERT(comparison->env() == NULL); |
3254 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) { | 3112 for (intptr_t i = comparison->InputCount() - 1; i >= 0; --i) { |
3255 comparison->InputAt(i)->set_instruction(this); | 3113 comparison->InputAt(i)->set_instruction(this); |
3256 } | 3114 } |
3257 } | 3115 } |
3258 | 3116 |
3259 // Returns true if this combination of comparison and values flowing on | 3117 // Returns true if this combination of comparison and values flowing on |
3260 // the true and false paths is supported on the current platform. | 3118 // the true and false paths is supported on the current platform. |
3261 static bool Supports(ComparisonInstr* comparison, Value* v1, Value* v2); | 3119 static bool Supports(ComparisonInstr* comparison, Value* v1, Value* v2); |
3262 | 3120 |
3263 DECLARE_INSTRUCTION(IfThenElse) | 3121 DECLARE_INSTRUCTION(IfThenElse) |
3264 | 3122 |
3265 intptr_t InputCount() const { return comparison()->InputCount(); } | 3123 intptr_t InputCount() const { return comparison()->InputCount(); } |
3266 | 3124 |
3267 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } | 3125 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } |
3268 | 3126 |
3269 virtual bool CanDeoptimize() const { | 3127 virtual bool CanDeoptimize() const { return comparison()->CanDeoptimize(); } |
3270 return comparison()->CanDeoptimize(); | |
3271 } | |
3272 | 3128 |
3273 virtual bool CanBecomeDeoptimizationTarget() const { | 3129 virtual bool CanBecomeDeoptimizationTarget() const { |
3274 return comparison()->CanBecomeDeoptimizationTarget(); | 3130 return comparison()->CanBecomeDeoptimizationTarget(); |
3275 } | 3131 } |
3276 | 3132 |
3277 virtual intptr_t DeoptimizationTarget() const { | 3133 virtual intptr_t DeoptimizationTarget() const { |
3278 return comparison()->DeoptimizationTarget(); | 3134 return comparison()->DeoptimizationTarget(); |
3279 } | 3135 } |
3280 | 3136 |
3281 virtual Representation RequiredInputRepresentation(intptr_t i) const { | 3137 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3332 token_pos_(token_pos), | 3188 token_pos_(token_pos), |
3333 function_(function), | 3189 function_(function), |
3334 argument_names_(argument_names), | 3190 argument_names_(argument_names), |
3335 arguments_(arguments), | 3191 arguments_(arguments), |
3336 result_cid_(kDynamicCid), | 3192 result_cid_(kDynamicCid), |
3337 is_known_list_constructor_(false), | 3193 is_known_list_constructor_(false), |
3338 identity_(AliasIdentity::Unknown()) { | 3194 identity_(AliasIdentity::Unknown()) { |
3339 ic_data_ = GetICData(ic_data_array); | 3195 ic_data_ = GetICData(ic_data_array); |
3340 ASSERT(function.IsZoneHandle()); | 3196 ASSERT(function.IsZoneHandle()); |
3341 ASSERT(!function.IsNull()); | 3197 ASSERT(!function.IsNull()); |
3342 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); | 3198 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); |
3343 } | 3199 } |
3344 | 3200 |
3345 StaticCallInstr(TokenPosition token_pos, | 3201 StaticCallInstr(TokenPosition token_pos, |
3346 const Function& function, | 3202 const Function& function, |
3347 const Array& argument_names, | 3203 const Array& argument_names, |
3348 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 3204 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
3349 intptr_t deopt_id) | 3205 intptr_t deopt_id) |
3350 : TemplateDefinition(deopt_id), | 3206 : TemplateDefinition(deopt_id), |
3351 ic_data_(NULL), | 3207 ic_data_(NULL), |
3352 token_pos_(token_pos), | 3208 token_pos_(token_pos), |
3353 function_(function), | 3209 function_(function), |
3354 argument_names_(argument_names), | 3210 argument_names_(argument_names), |
3355 arguments_(arguments), | 3211 arguments_(arguments), |
3356 result_cid_(kDynamicCid), | 3212 result_cid_(kDynamicCid), |
3357 is_known_list_constructor_(false), | 3213 is_known_list_constructor_(false), |
3358 identity_(AliasIdentity::Unknown()) { | 3214 identity_(AliasIdentity::Unknown()) { |
3359 ASSERT(function.IsZoneHandle()); | 3215 ASSERT(function.IsZoneHandle()); |
3360 ASSERT(!function.IsNull()); | 3216 ASSERT(!function.IsNull()); |
3361 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); | 3217 ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap()); |
3362 } | 3218 } |
3363 | 3219 |
3364 // ICData for static calls carries call count. | 3220 // ICData for static calls carries call count. |
3365 const ICData* ic_data() const { return ic_data_; } | 3221 const ICData* ic_data() const { return ic_data_; } |
3366 bool HasICData() const { | 3222 bool HasICData() const { return (ic_data() != NULL) && !ic_data()->IsNull(); } |
3367 return (ic_data() != NULL) && !ic_data()->IsNull(); | |
3368 } | |
3369 | 3223 |
3370 DECLARE_INSTRUCTION(StaticCall) | 3224 DECLARE_INSTRUCTION(StaticCall) |
3371 virtual CompileType ComputeType() const; | 3225 virtual CompileType ComputeType() const; |
3372 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 3226 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
3373 | 3227 |
3374 // Accessors forwarded to the AST node. | 3228 // Accessors forwarded to the AST node. |
3375 const Function& function() const { return function_; } | 3229 const Function& function() const { return function_; } |
3376 const Array& argument_names() const { return argument_names_; } | 3230 const Array& argument_names() const { return argument_names_; } |
3377 virtual TokenPosition token_pos() const { return token_pos_; } | 3231 virtual TokenPosition token_pos() const { return token_pos_; } |
3378 | 3232 |
(...skipping 16 matching lines...) Expand all Loading... |
3395 | 3249 |
3396 virtual EffectSet Effects() const { return EffectSet::All(); } | 3250 virtual EffectSet Effects() const { return EffectSet::All(); } |
3397 | 3251 |
3398 void set_result_cid(intptr_t value) { result_cid_ = value; } | 3252 void set_result_cid(intptr_t value) { result_cid_ = value; } |
3399 | 3253 |
3400 bool is_known_list_constructor() const { return is_known_list_constructor_; } | 3254 bool is_known_list_constructor() const { return is_known_list_constructor_; } |
3401 void set_is_known_list_constructor(bool value) { | 3255 void set_is_known_list_constructor(bool value) { |
3402 is_known_list_constructor_ = value; | 3256 is_known_list_constructor_ = value; |
3403 } | 3257 } |
3404 | 3258 |
3405 bool IsRecognizedFactory() const { | 3259 bool IsRecognizedFactory() const { return is_known_list_constructor(); } |
3406 return is_known_list_constructor(); | |
3407 } | |
3408 | 3260 |
3409 virtual AliasIdentity Identity() const { return identity_; } | 3261 virtual AliasIdentity Identity() const { return identity_; } |
3410 virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; } | 3262 virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; } |
3411 | 3263 |
3412 PRINT_OPERANDS_TO_SUPPORT | 3264 PRINT_OPERANDS_TO_SUPPORT |
3413 | 3265 |
3414 private: | 3266 private: |
3415 const ICData* ic_data_; | 3267 const ICData* ic_data_; |
3416 const TokenPosition token_pos_; | 3268 const TokenPosition token_pos_; |
3417 const Function& function_; | 3269 const Function& function_; |
3418 const Array& argument_names_; | 3270 const Array& argument_names_; |
3419 ZoneGrowableArray<PushArgumentInstr*>* arguments_; | 3271 ZoneGrowableArray<PushArgumentInstr*>* arguments_; |
3420 intptr_t result_cid_; // For some library functions we know the result. | 3272 intptr_t result_cid_; // For some library functions we know the result. |
3421 | 3273 |
3422 // 'True' for recognized list constructors. | 3274 // 'True' for recognized list constructors. |
3423 bool is_known_list_constructor_; | 3275 bool is_known_list_constructor_; |
3424 | 3276 |
3425 AliasIdentity identity_; | 3277 AliasIdentity identity_; |
3426 | 3278 |
3427 DISALLOW_COPY_AND_ASSIGN(StaticCallInstr); | 3279 DISALLOW_COPY_AND_ASSIGN(StaticCallInstr); |
3428 }; | 3280 }; |
3429 | 3281 |
3430 | 3282 |
3431 class LoadLocalInstr : public TemplateDefinition<0, NoThrow> { | 3283 class LoadLocalInstr : public TemplateDefinition<0, NoThrow> { |
3432 public: | 3284 public: |
3433 LoadLocalInstr(const LocalVariable& local, | 3285 LoadLocalInstr(const LocalVariable& local, TokenPosition token_pos) |
3434 TokenPosition token_pos) | 3286 : local_(local), is_last_(false), token_pos_(token_pos) {} |
3435 : local_(local), is_last_(false), token_pos_(token_pos) { } | |
3436 | 3287 |
3437 DECLARE_INSTRUCTION(LoadLocal) | 3288 DECLARE_INSTRUCTION(LoadLocal) |
3438 virtual CompileType ComputeType() const; | 3289 virtual CompileType ComputeType() const; |
3439 | 3290 |
3440 const LocalVariable& local() const { return local_; } | 3291 const LocalVariable& local() const { return local_; } |
3441 | 3292 |
3442 virtual bool CanDeoptimize() const { return false; } | 3293 virtual bool CanDeoptimize() const { return false; } |
3443 | 3294 |
3444 virtual EffectSet Effects() const { | 3295 virtual EffectSet Effects() const { |
3445 UNREACHABLE(); // Eliminated by SSA construction. | 3296 UNREACHABLE(); // Eliminated by SSA construction. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3490 virtual EffectSet Effects() const { | 3341 virtual EffectSet Effects() const { |
3491 UNREACHABLE(); // Eliminated by SSA construction. | 3342 UNREACHABLE(); // Eliminated by SSA construction. |
3492 return EffectSet::None(); | 3343 return EffectSet::None(); |
3493 } | 3344 } |
3494 | 3345 |
3495 virtual bool MayThrow() const { | 3346 virtual bool MayThrow() const { |
3496 UNREACHABLE(); | 3347 UNREACHABLE(); |
3497 return false; | 3348 return false; |
3498 } | 3349 } |
3499 | 3350 |
3500 virtual TokenPosition token_pos() const { | 3351 virtual TokenPosition token_pos() const { return TokenPosition::kTempMove; } |
3501 return TokenPosition::kTempMove; | |
3502 } | |
3503 | 3352 |
3504 PRINT_OPERANDS_TO_SUPPORT | 3353 PRINT_OPERANDS_TO_SUPPORT |
3505 | 3354 |
3506 private: | 3355 private: |
3507 virtual void RawSetInputAt(intptr_t i, Value* value) { | 3356 virtual void RawSetInputAt(intptr_t i, Value* value) { value_ = value; } |
3508 value_ = value; | |
3509 } | |
3510 | 3357 |
3511 const intptr_t num_temps_; | 3358 const intptr_t num_temps_; |
3512 Value* value_; | 3359 Value* value_; |
3513 | 3360 |
3514 DISALLOW_COPY_AND_ASSIGN(DropTempsInstr); | 3361 DISALLOW_COPY_AND_ASSIGN(DropTempsInstr); |
3515 }; | 3362 }; |
3516 | 3363 |
3517 | 3364 |
3518 class StoreLocalInstr : public TemplateDefinition<1, NoThrow> { | 3365 class StoreLocalInstr : public TemplateDefinition<1, NoThrow> { |
3519 public: | 3366 public: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3558 | 3405 |
3559 | 3406 |
3560 class NativeCallInstr : public TemplateDefinition<0, Throws> { | 3407 class NativeCallInstr : public TemplateDefinition<0, Throws> { |
3561 public: | 3408 public: |
3562 explicit NativeCallInstr(NativeBodyNode* node) | 3409 explicit NativeCallInstr(NativeBodyNode* node) |
3563 : native_name_(&node->native_c_function_name()), | 3410 : native_name_(&node->native_c_function_name()), |
3564 function_(&node->function()), | 3411 function_(&node->function()), |
3565 native_c_function_(NULL), | 3412 native_c_function_(NULL), |
3566 is_bootstrap_native_(false), | 3413 is_bootstrap_native_(false), |
3567 link_lazily_(node->link_lazily()), | 3414 link_lazily_(node->link_lazily()), |
3568 token_pos_(node->token_pos()) { } | 3415 token_pos_(node->token_pos()) {} |
3569 | 3416 |
3570 NativeCallInstr(const String* name, | 3417 NativeCallInstr(const String* name, |
3571 const Function* function, | 3418 const Function* function, |
3572 bool link_lazily, | 3419 bool link_lazily, |
3573 TokenPosition position) | 3420 TokenPosition position) |
3574 : native_name_(name), | 3421 : native_name_(name), |
3575 function_(function), | 3422 function_(function), |
3576 native_c_function_(NULL), | 3423 native_c_function_(NULL), |
3577 is_bootstrap_native_(false), | 3424 is_bootstrap_native_(false), |
3578 link_lazily_(link_lazily), | 3425 link_lazily_(link_lazily), |
3579 token_pos_(position) { } | 3426 token_pos_(position) {} |
3580 | 3427 |
3581 DECLARE_INSTRUCTION(NativeCall) | 3428 DECLARE_INSTRUCTION(NativeCall) |
3582 | 3429 |
3583 const String& native_name() const { return *native_name_; } | 3430 const String& native_name() const { return *native_name_; } |
3584 const Function& function() const { return *function_; } | 3431 const Function& function() const { return *function_; } |
3585 NativeFunction native_c_function() const { return native_c_function_; } | 3432 NativeFunction native_c_function() const { return native_c_function_; } |
3586 bool is_bootstrap_native() const { return is_bootstrap_native_; } | 3433 bool is_bootstrap_native() const { return is_bootstrap_native_; } |
3587 bool link_lazily() const { return link_lazily_; } | 3434 bool link_lazily() const { return link_lazily_; } |
3588 virtual TokenPosition token_pos() const { return token_pos_; } | 3435 virtual TokenPosition token_pos() const { return token_pos_; } |
3589 | 3436 |
(...skipping 18 matching lines...) Expand all Loading... |
3608 bool is_bootstrap_native_; | 3455 bool is_bootstrap_native_; |
3609 bool link_lazily_; | 3456 bool link_lazily_; |
3610 const TokenPosition token_pos_; | 3457 const TokenPosition token_pos_; |
3611 | 3458 |
3612 DISALLOW_COPY_AND_ASSIGN(NativeCallInstr); | 3459 DISALLOW_COPY_AND_ASSIGN(NativeCallInstr); |
3613 }; | 3460 }; |
3614 | 3461 |
3615 | 3462 |
3616 class DebugStepCheckInstr : public TemplateInstruction<0, NoThrow> { | 3463 class DebugStepCheckInstr : public TemplateInstruction<0, NoThrow> { |
3617 public: | 3464 public: |
3618 DebugStepCheckInstr(TokenPosition token_pos, | 3465 DebugStepCheckInstr(TokenPosition token_pos, RawPcDescriptors::Kind stub_kind) |
3619 RawPcDescriptors::Kind stub_kind) | 3466 : token_pos_(token_pos), stub_kind_(stub_kind) {} |
3620 : token_pos_(token_pos), | |
3621 stub_kind_(stub_kind) { | |
3622 } | |
3623 | 3467 |
3624 DECLARE_INSTRUCTION(DebugStepCheck) | 3468 DECLARE_INSTRUCTION(DebugStepCheck) |
3625 | 3469 |
3626 virtual TokenPosition token_pos() const { return token_pos_; } | 3470 virtual TokenPosition token_pos() const { return token_pos_; } |
3627 virtual bool CanDeoptimize() const { return false; } | 3471 virtual bool CanDeoptimize() const { return false; } |
3628 virtual EffectSet Effects() const { return EffectSet::All(); } | 3472 virtual EffectSet Effects() const { return EffectSet::All(); } |
3629 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 3473 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
3630 | 3474 |
3631 private: | 3475 private: |
3632 const TokenPosition token_pos_; | 3476 const TokenPosition token_pos_; |
3633 const RawPcDescriptors::Kind stub_kind_; | 3477 const RawPcDescriptors::Kind stub_kind_; |
3634 | 3478 |
3635 DISALLOW_COPY_AND_ASSIGN(DebugStepCheckInstr); | 3479 DISALLOW_COPY_AND_ASSIGN(DebugStepCheckInstr); |
3636 }; | 3480 }; |
3637 | 3481 |
3638 | 3482 |
3639 enum StoreBarrierType { | 3483 enum StoreBarrierType { kNoStoreBarrier, kEmitStoreBarrier }; |
3640 kNoStoreBarrier, | |
3641 kEmitStoreBarrier | |
3642 }; | |
3643 | 3484 |
3644 | 3485 |
3645 class StoreInstanceFieldInstr : public TemplateDefinition<2, NoThrow> { | 3486 class StoreInstanceFieldInstr : public TemplateDefinition<2, NoThrow> { |
3646 public: | 3487 public: |
3647 StoreInstanceFieldInstr(const Field& field, | 3488 StoreInstanceFieldInstr(const Field& field, |
3648 Value* instance, | 3489 Value* instance, |
3649 Value* value, | 3490 Value* value, |
3650 StoreBarrierType emit_store_barrier, | 3491 StoreBarrierType emit_store_barrier, |
3651 TokenPosition token_pos) | 3492 TokenPosition token_pos) |
3652 : field_(field), | 3493 : field_(field), |
(...skipping 17 matching lines...) Expand all Loading... |
3670 token_pos_(token_pos), | 3511 token_pos_(token_pos), |
3671 is_initialization_(false) { | 3512 is_initialization_(false) { |
3672 SetInputAt(kInstancePos, instance); | 3513 SetInputAt(kInstancePos, instance); |
3673 SetInputAt(kValuePos, value); | 3514 SetInputAt(kValuePos, value); |
3674 } | 3515 } |
3675 | 3516 |
3676 DECLARE_INSTRUCTION(StoreInstanceField) | 3517 DECLARE_INSTRUCTION(StoreInstanceField) |
3677 | 3518 |
3678 void set_is_initialization(bool value) { is_initialization_ = value; } | 3519 void set_is_initialization(bool value) { is_initialization_ = value; } |
3679 | 3520 |
3680 enum { | 3521 enum { kInstancePos = 0, kValuePos = 1 }; |
3681 kInstancePos = 0, | |
3682 kValuePos = 1 | |
3683 }; | |
3684 | 3522 |
3685 Value* instance() const { return inputs_[kInstancePos]; } | 3523 Value* instance() const { return inputs_[kInstancePos]; } |
3686 Value* value() const { return inputs_[kValuePos]; } | 3524 Value* value() const { return inputs_[kValuePos]; } |
3687 bool is_initialization() const { return is_initialization_; } | 3525 bool is_initialization() const { return is_initialization_; } |
3688 | 3526 |
3689 virtual TokenPosition token_pos() const { return token_pos_; } | 3527 virtual TokenPosition token_pos() const { return token_pos_; } |
3690 | 3528 |
3691 const Field& field() const { return field_; } | 3529 const Field& field() const { return field_; } |
3692 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 3530 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
3693 | 3531 |
3694 bool ShouldEmitStoreBarrier() const { | 3532 bool ShouldEmitStoreBarrier() const { |
3695 return value()->NeedsStoreBuffer() | 3533 return value()->NeedsStoreBuffer() && |
3696 && (emit_store_barrier_ == kEmitStoreBarrier); | 3534 (emit_store_barrier_ == kEmitStoreBarrier); |
3697 } | 3535 } |
3698 | 3536 |
3699 virtual bool CanDeoptimize() const { return false; } | 3537 virtual bool CanDeoptimize() const { return false; } |
3700 | 3538 |
3701 // May require a deoptimization target for input conversions. | 3539 // May require a deoptimization target for input conversions. |
3702 virtual intptr_t DeoptimizationTarget() const { | 3540 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } |
3703 return GetDeoptId(); | |
3704 } | |
3705 | 3541 |
3706 // Currently CSE/LICM don't operate on any instructions that can be affected | 3542 // Currently CSE/LICM don't operate on any instructions that can be affected |
3707 // by stores/loads. LoadOptimizer handles loads separately. Hence stores | 3543 // by stores/loads. LoadOptimizer handles loads separately. Hence stores |
3708 // are marked as having no side-effects. | 3544 // are marked as having no side-effects. |
3709 virtual EffectSet Effects() const { return EffectSet::None(); } | 3545 virtual EffectSet Effects() const { return EffectSet::None(); } |
3710 | 3546 |
3711 bool IsUnboxedStore() const; | 3547 bool IsUnboxedStore() const; |
3712 | 3548 |
3713 bool IsPotentialUnboxedStore() const; | 3549 bool IsPotentialUnboxedStore() const; |
3714 | 3550 |
(...skipping 17 matching lines...) Expand all Loading... |
3732 const TokenPosition token_pos_; | 3568 const TokenPosition token_pos_; |
3733 // Marks initialiing stores. E.g. in the constructor. | 3569 // Marks initialiing stores. E.g. in the constructor. |
3734 bool is_initialization_; | 3570 bool is_initialization_; |
3735 | 3571 |
3736 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); | 3572 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); |
3737 }; | 3573 }; |
3738 | 3574 |
3739 | 3575 |
3740 class GuardFieldInstr : public TemplateInstruction<1, NoThrow, Pure> { | 3576 class GuardFieldInstr : public TemplateInstruction<1, NoThrow, Pure> { |
3741 public: | 3577 public: |
3742 GuardFieldInstr(Value* value, | 3578 GuardFieldInstr(Value* value, const Field& field, intptr_t deopt_id) |
3743 const Field& field, | 3579 : TemplateInstruction(deopt_id), field_(field) { |
3744 intptr_t deopt_id) | |
3745 : TemplateInstruction(deopt_id), | |
3746 field_(field) { | |
3747 SetInputAt(0, value); | 3580 SetInputAt(0, value); |
3748 CheckField(field); | 3581 CheckField(field); |
3749 } | 3582 } |
3750 | 3583 |
3751 Value* value() const { return inputs_[0]; } | 3584 Value* value() const { return inputs_[0]; } |
3752 | 3585 |
3753 const Field& field() const { return field_; } | 3586 const Field& field() const { return field_; } |
3754 | 3587 |
3755 virtual bool CanDeoptimize() const { return true; } | 3588 virtual bool CanDeoptimize() const { return true; } |
3756 virtual bool CanBecomeDeoptimizationTarget() const { | 3589 virtual bool CanBecomeDeoptimizationTarget() const { |
3757 // Ensure that we record kDeopt PC descriptor in unoptimized code. | 3590 // Ensure that we record kDeopt PC descriptor in unoptimized code. |
3758 return true; | 3591 return true; |
3759 } | 3592 } |
3760 | 3593 |
3761 PRINT_OPERANDS_TO_SUPPORT | 3594 PRINT_OPERANDS_TO_SUPPORT |
3762 | 3595 |
3763 private: | 3596 private: |
3764 const Field& field_; | 3597 const Field& field_; |
3765 | 3598 |
3766 DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr); | 3599 DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr); |
3767 }; | 3600 }; |
3768 | 3601 |
3769 | 3602 |
3770 class GuardFieldClassInstr : public GuardFieldInstr { | 3603 class GuardFieldClassInstr : public GuardFieldInstr { |
3771 public: | 3604 public: |
3772 GuardFieldClassInstr(Value* value, | 3605 GuardFieldClassInstr(Value* value, const Field& field, intptr_t deopt_id) |
3773 const Field& field, | |
3774 intptr_t deopt_id) | |
3775 : GuardFieldInstr(value, field, deopt_id) { | 3606 : GuardFieldInstr(value, field, deopt_id) { |
3776 CheckField(field); | 3607 CheckField(field); |
3777 } | 3608 } |
3778 | 3609 |
3779 DECLARE_INSTRUCTION(GuardFieldClass) | 3610 DECLARE_INSTRUCTION(GuardFieldClass) |
3780 | 3611 |
3781 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 3612 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
3782 | 3613 |
3783 virtual bool AttributesEqual(Instruction* other) const; | 3614 virtual bool AttributesEqual(Instruction* other) const; |
3784 | 3615 |
3785 private: | 3616 private: |
3786 DISALLOW_COPY_AND_ASSIGN(GuardFieldClassInstr); | 3617 DISALLOW_COPY_AND_ASSIGN(GuardFieldClassInstr); |
3787 }; | 3618 }; |
3788 | 3619 |
3789 | 3620 |
3790 class GuardFieldLengthInstr : public GuardFieldInstr { | 3621 class GuardFieldLengthInstr : public GuardFieldInstr { |
3791 public: | 3622 public: |
3792 GuardFieldLengthInstr(Value* value, | 3623 GuardFieldLengthInstr(Value* value, const Field& field, intptr_t deopt_id) |
3793 const Field& field, | |
3794 intptr_t deopt_id) | |
3795 : GuardFieldInstr(value, field, deopt_id) { | 3624 : GuardFieldInstr(value, field, deopt_id) { |
3796 CheckField(field); | 3625 CheckField(field); |
3797 } | 3626 } |
3798 | 3627 |
3799 DECLARE_INSTRUCTION(GuardFieldLength) | 3628 DECLARE_INSTRUCTION(GuardFieldLength) |
3800 | 3629 |
3801 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 3630 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
3802 | 3631 |
3803 virtual bool AttributesEqual(Instruction* other) const; | 3632 virtual bool AttributesEqual(Instruction* other) const; |
3804 | 3633 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3838 | 3667 |
3839 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr); | 3668 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr); |
3840 }; | 3669 }; |
3841 | 3670 |
3842 | 3671 |
3843 class StoreStaticFieldInstr : public TemplateDefinition<1, NoThrow> { | 3672 class StoreStaticFieldInstr : public TemplateDefinition<1, NoThrow> { |
3844 public: | 3673 public: |
3845 StoreStaticFieldInstr(const Field& field, | 3674 StoreStaticFieldInstr(const Field& field, |
3846 Value* value, | 3675 Value* value, |
3847 TokenPosition token_pos) | 3676 TokenPosition token_pos) |
3848 : field_(field), | 3677 : field_(field), token_pos_(token_pos) { |
3849 token_pos_(token_pos) { | |
3850 ASSERT(field.IsZoneHandle()); | 3678 ASSERT(field.IsZoneHandle()); |
3851 SetInputAt(kValuePos, value); | 3679 SetInputAt(kValuePos, value); |
3852 CheckField(field); | 3680 CheckField(field); |
3853 } | 3681 } |
3854 | 3682 |
3855 enum { | 3683 enum { kValuePos = 0 }; |
3856 kValuePos = 0 | |
3857 }; | |
3858 | 3684 |
3859 DECLARE_INSTRUCTION(StoreStaticField) | 3685 DECLARE_INSTRUCTION(StoreStaticField) |
3860 | 3686 |
3861 const Field& field() const { return field_; } | 3687 const Field& field() const { return field_; } |
3862 Value* value() const { return inputs_[kValuePos]; } | 3688 Value* value() const { return inputs_[kValuePos]; } |
3863 | 3689 |
3864 virtual bool CanDeoptimize() const { return false; } | 3690 virtual bool CanDeoptimize() const { return false; } |
3865 | 3691 |
3866 // Currently CSE/LICM don't operate on any instructions that can be affected | 3692 // Currently CSE/LICM don't operate on any instructions that can be affected |
3867 // by stores/loads. LoadOptimizer handles loads separately. Hence stores | 3693 // by stores/loads. LoadOptimizer handles loads separately. Hence stores |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4019 SetInputAt(0, char_code); | 3845 SetInputAt(0, char_code); |
4020 } | 3846 } |
4021 | 3847 |
4022 DECLARE_INSTRUCTION(OneByteStringFromCharCode) | 3848 DECLARE_INSTRUCTION(OneByteStringFromCharCode) |
4023 virtual CompileType ComputeType() const; | 3849 virtual CompileType ComputeType() const; |
4024 | 3850 |
4025 Value* char_code() const { return inputs_[0]; } | 3851 Value* char_code() const { return inputs_[0]; } |
4026 | 3852 |
4027 virtual bool CanDeoptimize() const { return false; } | 3853 virtual bool CanDeoptimize() const { return false; } |
4028 | 3854 |
4029 virtual bool AttributesEqual(Instruction* other) const { | 3855 virtual bool AttributesEqual(Instruction* other) const { return true; } |
4030 return true; | |
4031 } | |
4032 | 3856 |
4033 private: | 3857 private: |
4034 DISALLOW_COPY_AND_ASSIGN(OneByteStringFromCharCodeInstr); | 3858 DISALLOW_COPY_AND_ASSIGN(OneByteStringFromCharCodeInstr); |
4035 }; | 3859 }; |
4036 | 3860 |
4037 | 3861 |
4038 class StringToCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { | 3862 class StringToCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> { |
4039 public: | 3863 public: |
4040 StringToCharCodeInstr(Value* str, intptr_t cid) : cid_(cid) { | 3864 StringToCharCodeInstr(Value* str, intptr_t cid) : cid_(cid) { |
4041 ASSERT(str != NULL); | 3865 ASSERT(str != NULL); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4097 Value* index, | 3921 Value* index, |
4098 Value* value, | 3922 Value* value, |
4099 StoreBarrierType emit_store_barrier, | 3923 StoreBarrierType emit_store_barrier, |
4100 intptr_t index_scale, | 3924 intptr_t index_scale, |
4101 intptr_t class_id, | 3925 intptr_t class_id, |
4102 AlignmentType alignment, | 3926 AlignmentType alignment, |
4103 intptr_t deopt_id, | 3927 intptr_t deopt_id, |
4104 TokenPosition token_pos); | 3928 TokenPosition token_pos); |
4105 DECLARE_INSTRUCTION(StoreIndexed) | 3929 DECLARE_INSTRUCTION(StoreIndexed) |
4106 | 3930 |
4107 enum { | 3931 enum { kArrayPos = 0, kIndexPos = 1, kValuePos = 2 }; |
4108 kArrayPos = 0, | |
4109 kIndexPos = 1, | |
4110 kValuePos = 2 | |
4111 }; | |
4112 | 3932 |
4113 Value* array() const { return inputs_[kArrayPos]; } | 3933 Value* array() const { return inputs_[kArrayPos]; } |
4114 Value* index() const { return inputs_[kIndexPos]; } | 3934 Value* index() const { return inputs_[kIndexPos]; } |
4115 Value* value() const { return inputs_[kValuePos]; } | 3935 Value* value() const { return inputs_[kValuePos]; } |
4116 | 3936 |
4117 intptr_t index_scale() const { return index_scale_; } | 3937 intptr_t index_scale() const { return index_scale_; } |
4118 intptr_t class_id() const { return class_id_; } | 3938 intptr_t class_id() const { return class_id_; } |
4119 bool aligned() const { return alignment_ == kAlignedAccess; } | 3939 bool aligned() const { return alignment_ == kAlignedAccess; } |
4120 | 3940 |
4121 bool ShouldEmitStoreBarrier() const { | 3941 bool ShouldEmitStoreBarrier() const { |
4122 return value()->NeedsStoreBuffer() | 3942 return value()->NeedsStoreBuffer() && |
4123 && (emit_store_barrier_ == kEmitStoreBarrier); | 3943 (emit_store_barrier_ == kEmitStoreBarrier); |
4124 } | 3944 } |
4125 | 3945 |
4126 virtual bool CanDeoptimize() const { return false; } | 3946 virtual bool CanDeoptimize() const { return false; } |
4127 | 3947 |
4128 virtual Representation RequiredInputRepresentation(intptr_t idx) const; | 3948 virtual Representation RequiredInputRepresentation(intptr_t idx) const; |
4129 | 3949 |
4130 bool IsExternal() const { | 3950 bool IsExternal() const { |
4131 return array()->definition()->representation() == kUntagged; | 3951 return array()->definition()->representation() == kUntagged; |
4132 } | 3952 } |
4133 | 3953 |
(...skipping 12 matching lines...) Expand all Loading... |
4146 const AlignmentType alignment_; | 3966 const AlignmentType alignment_; |
4147 const TokenPosition token_pos_; | 3967 const TokenPosition token_pos_; |
4148 | 3968 |
4149 DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr); | 3969 DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr); |
4150 }; | 3970 }; |
4151 | 3971 |
4152 | 3972 |
4153 // Note overrideable, built-in: value ? false : true. | 3973 // Note overrideable, built-in: value ? false : true. |
4154 class BooleanNegateInstr : public TemplateDefinition<1, NoThrow> { | 3974 class BooleanNegateInstr : public TemplateDefinition<1, NoThrow> { |
4155 public: | 3975 public: |
4156 explicit BooleanNegateInstr(Value* value) { | 3976 explicit BooleanNegateInstr(Value* value) { SetInputAt(0, value); } |
4157 SetInputAt(0, value); | |
4158 } | |
4159 | 3977 |
4160 DECLARE_INSTRUCTION(BooleanNegate) | 3978 DECLARE_INSTRUCTION(BooleanNegate) |
4161 virtual CompileType ComputeType() const; | 3979 virtual CompileType ComputeType() const; |
4162 | 3980 |
4163 Value* value() const { return inputs_[0]; } | 3981 Value* value() const { return inputs_[0]; } |
4164 | 3982 |
4165 virtual bool CanDeoptimize() const { return false; } | 3983 virtual bool CanDeoptimize() const { return false; } |
4166 | 3984 |
4167 virtual EffectSet Effects() const { return EffectSet::None(); } | 3985 virtual EffectSet Effects() const { return EffectSet::None(); } |
4168 | 3986 |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4337 ASSERT(slots_.length() == values_->length()); | 4155 ASSERT(slots_.length() == values_->length()); |
4338 for (intptr_t i = 0; i < InputCount(); i++) { | 4156 for (intptr_t i = 0; i < InputCount(); i++) { |
4339 InputAt(i)->set_instruction(this); | 4157 InputAt(i)->set_instruction(this); |
4340 InputAt(i)->set_use_index(i); | 4158 InputAt(i)->set_use_index(i); |
4341 } | 4159 } |
4342 } | 4160 } |
4343 | 4161 |
4344 Definition* allocation() const { return allocation_; } | 4162 Definition* allocation() const { return allocation_; } |
4345 const Class& cls() const { return cls_; } | 4163 const Class& cls() const { return cls_; } |
4346 | 4164 |
4347 intptr_t num_variables() const { | 4165 intptr_t num_variables() const { return num_variables_; } |
4348 return num_variables_; | 4166 |
| 4167 intptr_t FieldOffsetAt(intptr_t i) const { |
| 4168 return slots_[i]->IsField() ? Field::Cast(*slots_[i]).Offset() |
| 4169 : Smi::Cast(*slots_[i]).Value(); |
4349 } | 4170 } |
4350 | 4171 |
4351 intptr_t FieldOffsetAt(intptr_t i) const { | 4172 const Location& LocationAt(intptr_t i) { return locations_[i]; } |
4352 return slots_[i]->IsField() | |
4353 ? Field::Cast(*slots_[i]).Offset() | |
4354 : Smi::Cast(*slots_[i]).Value(); | |
4355 } | |
4356 | |
4357 const Location& LocationAt(intptr_t i) { | |
4358 return locations_[i]; | |
4359 } | |
4360 | 4173 |
4361 DECLARE_INSTRUCTION(MaterializeObject) | 4174 DECLARE_INSTRUCTION(MaterializeObject) |
4362 | 4175 |
4363 virtual intptr_t InputCount() const { | 4176 virtual intptr_t InputCount() const { return values_->length(); } |
4364 return values_->length(); | |
4365 } | |
4366 | 4177 |
4367 virtual Value* InputAt(intptr_t i) const { | 4178 virtual Value* InputAt(intptr_t i) const { return (*values_)[i]; } |
4368 return (*values_)[i]; | |
4369 } | |
4370 | 4179 |
4371 // SelectRepresentations pass is run once more while MaterializeObject | 4180 // SelectRepresentations pass is run once more while MaterializeObject |
4372 // instructions are still in the graph. To avoid any redundant boxing | 4181 // instructions are still in the graph. To avoid any redundant boxing |
4373 // operations inserted by that pass we should indicate that this | 4182 // operations inserted by that pass we should indicate that this |
4374 // instruction can cope with any representation as it is essentially | 4183 // instruction can cope with any representation as it is essentially |
4375 // an environment use. | 4184 // an environment use. |
4376 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 4185 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
4377 ASSERT(0 <= idx && idx < InputCount()); | 4186 ASSERT(0 <= idx && idx < InputCount()); |
4378 return kNoRepresentation; | 4187 return kNoRepresentation; |
4379 } | 4188 } |
4380 | 4189 |
4381 virtual bool CanDeoptimize() const { return false; } | 4190 virtual bool CanDeoptimize() const { return false; } |
4382 virtual EffectSet Effects() const { return EffectSet::None(); } | 4191 virtual EffectSet Effects() const { return EffectSet::None(); } |
4383 | 4192 |
4384 Location* locations() { return locations_; } | 4193 Location* locations() { return locations_; } |
4385 void set_locations(Location* locations) { locations_ = locations; } | 4194 void set_locations(Location* locations) { locations_ = locations; } |
4386 | 4195 |
4387 virtual bool MayThrow() const { return false; } | 4196 virtual bool MayThrow() const { return false; } |
4388 | 4197 |
4389 void RemapRegisters(intptr_t* cpu_reg_slots, | 4198 void RemapRegisters(intptr_t* cpu_reg_slots, intptr_t* fpu_reg_slots); |
4390 intptr_t* fpu_reg_slots); | |
4391 | 4199 |
4392 bool was_visited_for_liveness() const { return visited_for_liveness_; } | 4200 bool was_visited_for_liveness() const { return visited_for_liveness_; } |
4393 void mark_visited_for_liveness() { | 4201 void mark_visited_for_liveness() { visited_for_liveness_ = true; } |
4394 visited_for_liveness_ = true; | |
4395 } | |
4396 | 4202 |
4397 PRINT_OPERANDS_TO_SUPPORT | 4203 PRINT_OPERANDS_TO_SUPPORT |
4398 | 4204 |
4399 private: | 4205 private: |
4400 virtual void RawSetInputAt(intptr_t i, Value* value) { | 4206 virtual void RawSetInputAt(intptr_t i, Value* value) { |
4401 (*values_)[i] = value; | 4207 (*values_)[i] = value; |
4402 } | 4208 } |
4403 | 4209 |
4404 Definition* allocation_; | 4210 Definition* allocation_; |
4405 const Class& cls_; | 4211 const Class& cls_; |
4406 intptr_t num_variables_; | 4212 intptr_t num_variables_; |
4407 const ZoneGrowableArray<const Object*>& slots_; | 4213 const ZoneGrowableArray<const Object*>& slots_; |
4408 ZoneGrowableArray<Value*>* values_; | 4214 ZoneGrowableArray<Value*>* values_; |
4409 Location* locations_; | 4215 Location* locations_; |
4410 | 4216 |
4411 bool visited_for_liveness_; | 4217 bool visited_for_liveness_; |
4412 bool registers_remapped_; | 4218 bool registers_remapped_; |
4413 | 4219 |
4414 DISALLOW_COPY_AND_ASSIGN(MaterializeObjectInstr); | 4220 DISALLOW_COPY_AND_ASSIGN(MaterializeObjectInstr); |
4415 }; | 4221 }; |
4416 | 4222 |
4417 | 4223 |
4418 class CreateArrayInstr : public TemplateDefinition<2, Throws> { | 4224 class CreateArrayInstr : public TemplateDefinition<2, Throws> { |
4419 public: | 4225 public: |
4420 CreateArrayInstr(TokenPosition token_pos, | 4226 CreateArrayInstr(TokenPosition token_pos, |
4421 Value* element_type, | 4227 Value* element_type, |
4422 Value* num_elements) | 4228 Value* num_elements) |
4423 : TemplateDefinition(Thread::Current()->GetNextDeoptId()), | 4229 : TemplateDefinition(Thread::Current()->GetNextDeoptId()), |
4424 token_pos_(token_pos), | 4230 token_pos_(token_pos), |
4425 identity_(AliasIdentity::Unknown()) { | 4231 identity_(AliasIdentity::Unknown()) { |
4426 SetInputAt(kElementTypePos, element_type); | 4232 SetInputAt(kElementTypePos, element_type); |
4427 SetInputAt(kLengthPos, num_elements); | 4233 SetInputAt(kLengthPos, num_elements); |
4428 } | 4234 } |
4429 | 4235 |
4430 enum { | 4236 enum { kElementTypePos = 0, kLengthPos = 1 }; |
4431 kElementTypePos = 0, | |
4432 kLengthPos = 1 | |
4433 }; | |
4434 | 4237 |
4435 DECLARE_INSTRUCTION(CreateArray) | 4238 DECLARE_INSTRUCTION(CreateArray) |
4436 virtual CompileType ComputeType() const; | 4239 virtual CompileType ComputeType() const; |
4437 | 4240 |
4438 virtual TokenPosition token_pos() const { return token_pos_; } | 4241 virtual TokenPosition token_pos() const { return token_pos_; } |
4439 Value* element_type() const { return inputs_[kElementTypePos]; } | 4242 Value* element_type() const { return inputs_[kElementTypePos]; } |
4440 Value* num_elements() const { return inputs_[kLengthPos]; } | 4243 Value* num_elements() const { return inputs_[kLengthPos]; } |
4441 | 4244 |
4442 // Throw needs environment, which is created only if instruction can | 4245 // Throw needs environment, which is created only if instruction can |
4443 // deoptimize. | 4246 // deoptimize. |
(...skipping 16 matching lines...) Expand all Loading... |
4460 // depends on it (e.g. out of loops). GC may cause collect | 4263 // depends on it (e.g. out of loops). GC may cause collect |
4461 // the array while the external data-array is still accessed. | 4264 // the array while the external data-array is still accessed. |
4462 // TODO(vegorov) enable LICMing this instruction by ensuring that array itself | 4265 // TODO(vegorov) enable LICMing this instruction by ensuring that array itself |
4463 // is kept alive. | 4266 // is kept alive. |
4464 class LoadUntaggedInstr : public TemplateDefinition<1, NoThrow> { | 4267 class LoadUntaggedInstr : public TemplateDefinition<1, NoThrow> { |
4465 public: | 4268 public: |
4466 LoadUntaggedInstr(Value* object, intptr_t offset) : offset_(offset) { | 4269 LoadUntaggedInstr(Value* object, intptr_t offset) : offset_(offset) { |
4467 SetInputAt(0, object); | 4270 SetInputAt(0, object); |
4468 } | 4271 } |
4469 | 4272 |
4470 virtual Representation representation() const { | 4273 virtual Representation representation() const { return kUntagged; } |
4471 return kUntagged; | |
4472 } | |
4473 DECLARE_INSTRUCTION(LoadUntagged) | 4274 DECLARE_INSTRUCTION(LoadUntagged) |
4474 virtual CompileType ComputeType() const; | 4275 virtual CompileType ComputeType() const; |
4475 | 4276 |
4476 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 4277 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
4477 ASSERT(idx == 0); | 4278 ASSERT(idx == 0); |
4478 // The object may be tagged or untagged (for external objects). | 4279 // The object may be tagged or untagged (for external objects). |
4479 return kNoRepresentation; | 4280 return kNoRepresentation; |
4480 } | 4281 } |
4481 | 4282 |
4482 Value* object() const { return inputs_[0]; } | 4283 Value* object() const { return inputs_[0]; } |
4483 intptr_t offset() const { return offset_; } | 4284 intptr_t offset() const { return offset_; } |
4484 | 4285 |
4485 virtual bool CanDeoptimize() const { return false; } | 4286 virtual bool CanDeoptimize() const { return false; } |
4486 | 4287 |
4487 virtual EffectSet Effects() const { return EffectSet::None(); } | 4288 virtual EffectSet Effects() const { return EffectSet::None(); } |
4488 virtual bool AttributesEqual(Instruction* other) const { return true; } | 4289 virtual bool AttributesEqual(Instruction* other) const { return true; } |
4489 | 4290 |
4490 private: | 4291 private: |
4491 intptr_t offset_; | 4292 intptr_t offset_; |
4492 | 4293 |
4493 DISALLOW_COPY_AND_ASSIGN(LoadUntaggedInstr); | 4294 DISALLOW_COPY_AND_ASSIGN(LoadUntaggedInstr); |
4494 }; | 4295 }; |
4495 | 4296 |
4496 | 4297 |
4497 class LoadClassIdInstr : public TemplateDefinition<1, NoThrow> { | 4298 class LoadClassIdInstr : public TemplateDefinition<1, NoThrow> { |
4498 public: | 4299 public: |
4499 explicit LoadClassIdInstr(Value* object) { | 4300 explicit LoadClassIdInstr(Value* object) { SetInputAt(0, object); } |
4500 SetInputAt(0, object); | |
4501 } | |
4502 | 4301 |
4503 virtual Representation representation() const { | 4302 virtual Representation representation() const { return kTagged; } |
4504 return kTagged; | |
4505 } | |
4506 DECLARE_INSTRUCTION(LoadClassId) | 4303 DECLARE_INSTRUCTION(LoadClassId) |
4507 virtual CompileType ComputeType() const; | 4304 virtual CompileType ComputeType() const; |
4508 | 4305 |
4509 Value* object() const { return inputs_[0]; } | 4306 Value* object() const { return inputs_[0]; } |
4510 | 4307 |
4511 virtual bool CanDeoptimize() const { return false; } | 4308 virtual bool CanDeoptimize() const { return false; } |
4512 | 4309 |
4513 virtual bool AllowsCSE() const { return true; } | 4310 virtual bool AllowsCSE() const { return true; } |
4514 virtual EffectSet Dependencies() const { | 4311 virtual EffectSet Dependencies() const { |
4515 return EffectSet::Externalization(); | 4312 return EffectSet::Externalization(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4572 virtual Representation representation() const; | 4369 virtual Representation representation() const; |
4573 | 4370 |
4574 bool IsUnboxedLoad() const; | 4371 bool IsUnboxedLoad() const; |
4575 | 4372 |
4576 bool IsPotentialUnboxedLoad() const; | 4373 bool IsPotentialUnboxedLoad() const; |
4577 | 4374 |
4578 void set_recognized_kind(MethodRecognizer::Kind kind) { | 4375 void set_recognized_kind(MethodRecognizer::Kind kind) { |
4579 recognized_kind_ = kind; | 4376 recognized_kind_ = kind; |
4580 } | 4377 } |
4581 | 4378 |
4582 MethodRecognizer::Kind recognized_kind() const { | 4379 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } |
4583 return recognized_kind_; | |
4584 } | |
4585 | 4380 |
4586 DECLARE_INSTRUCTION(LoadField) | 4381 DECLARE_INSTRUCTION(LoadField) |
4587 virtual CompileType ComputeType() const; | 4382 virtual CompileType ComputeType() const; |
4588 | 4383 |
4589 virtual bool CanDeoptimize() const { return false; } | 4384 virtual bool CanDeoptimize() const { return false; } |
4590 | 4385 |
4591 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 4386 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
4592 | 4387 |
4593 bool IsImmutableLengthLoad() const; | 4388 bool IsImmutableLengthLoad() const; |
4594 | 4389 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4629 token_pos_(token_pos), | 4424 token_pos_(token_pos), |
4630 type_(type), | 4425 type_(type), |
4631 instantiator_class_(instantiator_class) { | 4426 instantiator_class_(instantiator_class) { |
4632 ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle()); | 4427 ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle()); |
4633 SetInputAt(0, instantiator); | 4428 SetInputAt(0, instantiator); |
4634 } | 4429 } |
4635 | 4430 |
4636 DECLARE_INSTRUCTION(InstantiateType) | 4431 DECLARE_INSTRUCTION(InstantiateType) |
4637 | 4432 |
4638 Value* instantiator() const { return inputs_[0]; } | 4433 Value* instantiator() const { return inputs_[0]; } |
4639 const AbstractType& type() const { return type_; | 4434 const AbstractType& type() const { return type_; } |
4640 } | |
4641 const Class& instantiator_class() const { return instantiator_class_; } | 4435 const Class& instantiator_class() const { return instantiator_class_; } |
4642 virtual TokenPosition token_pos() const { return token_pos_; } | 4436 virtual TokenPosition token_pos() const { return token_pos_; } |
4643 | 4437 |
4644 virtual bool CanDeoptimize() const { return true; } | 4438 virtual bool CanDeoptimize() const { return true; } |
4645 | 4439 |
4646 virtual EffectSet Effects() const { return EffectSet::None(); } | 4440 virtual EffectSet Effects() const { return EffectSet::None(); } |
4647 | 4441 |
4648 PRINT_OPERANDS_TO_SUPPORT | 4442 PRINT_OPERANDS_TO_SUPPORT |
4649 | 4443 |
4650 private: | 4444 private: |
(...skipping 15 matching lines...) Expand all Loading... |
4666 token_pos_(token_pos), | 4460 token_pos_(token_pos), |
4667 type_arguments_(type_arguments), | 4461 type_arguments_(type_arguments), |
4668 instantiator_class_(instantiator_class) { | 4462 instantiator_class_(instantiator_class) { |
4669 ASSERT(type_arguments.IsZoneHandle()); | 4463 ASSERT(type_arguments.IsZoneHandle()); |
4670 SetInputAt(0, instantiator); | 4464 SetInputAt(0, instantiator); |
4671 } | 4465 } |
4672 | 4466 |
4673 DECLARE_INSTRUCTION(InstantiateTypeArguments) | 4467 DECLARE_INSTRUCTION(InstantiateTypeArguments) |
4674 | 4468 |
4675 Value* instantiator() const { return inputs_[0]; } | 4469 Value* instantiator() const { return inputs_[0]; } |
4676 const TypeArguments& type_arguments() const { | 4470 const TypeArguments& type_arguments() const { return type_arguments_; } |
4677 return type_arguments_; | |
4678 } | |
4679 const Class& instantiator_class() const { return instantiator_class_; } | 4471 const Class& instantiator_class() const { return instantiator_class_; } |
4680 virtual TokenPosition token_pos() const { return token_pos_; } | 4472 virtual TokenPosition token_pos() const { return token_pos_; } |
4681 | 4473 |
4682 virtual bool CanDeoptimize() const { return true; } | 4474 virtual bool CanDeoptimize() const { return true; } |
4683 | 4475 |
4684 virtual EffectSet Effects() const { return EffectSet::None(); } | 4476 virtual EffectSet Effects() const { return EffectSet::None(); } |
4685 | 4477 |
4686 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 4478 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
4687 | 4479 |
4688 PRINT_OPERANDS_TO_SUPPORT | 4480 PRINT_OPERANDS_TO_SUPPORT |
4689 | 4481 |
4690 private: | 4482 private: |
4691 const TokenPosition token_pos_; | 4483 const TokenPosition token_pos_; |
4692 const TypeArguments& type_arguments_; | 4484 const TypeArguments& type_arguments_; |
4693 const Class& instantiator_class_; | 4485 const Class& instantiator_class_; |
4694 | 4486 |
4695 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr); | 4487 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr); |
4696 }; | 4488 }; |
4697 | 4489 |
4698 | 4490 |
4699 class AllocateContextInstr : public TemplateDefinition<0, NoThrow> { | 4491 class AllocateContextInstr : public TemplateDefinition<0, NoThrow> { |
4700 public: | 4492 public: |
4701 AllocateContextInstr(TokenPosition token_pos, | 4493 AllocateContextInstr(TokenPosition token_pos, intptr_t num_context_variables) |
4702 intptr_t num_context_variables) | 4494 : token_pos_(token_pos), num_context_variables_(num_context_variables) {} |
4703 : token_pos_(token_pos), | |
4704 num_context_variables_(num_context_variables) { } | |
4705 | 4495 |
4706 DECLARE_INSTRUCTION(AllocateContext) | 4496 DECLARE_INSTRUCTION(AllocateContext) |
4707 virtual CompileType ComputeType() const; | 4497 virtual CompileType ComputeType() const; |
4708 | 4498 |
4709 virtual TokenPosition token_pos() const { return token_pos_; } | 4499 virtual TokenPosition token_pos() const { return token_pos_; } |
4710 intptr_t num_context_variables() const { return num_context_variables_; } | 4500 intptr_t num_context_variables() const { return num_context_variables_; } |
4711 | 4501 |
4712 virtual bool CanDeoptimize() const { return false; } | 4502 virtual bool CanDeoptimize() const { return false; } |
4713 | 4503 |
4714 virtual EffectSet Effects() const { return EffectSet::None(); } | 4504 virtual EffectSet Effects() const { return EffectSet::None(); } |
(...skipping 10 matching lines...) Expand all Loading... |
4725 | 4515 |
4726 class InitStaticFieldInstr : public TemplateInstruction<1, Throws> { | 4516 class InitStaticFieldInstr : public TemplateInstruction<1, Throws> { |
4727 public: | 4517 public: |
4728 InitStaticFieldInstr(Value* input, const Field& field) | 4518 InitStaticFieldInstr(Value* input, const Field& field) |
4729 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), | 4519 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), |
4730 field_(field) { | 4520 field_(field) { |
4731 SetInputAt(0, input); | 4521 SetInputAt(0, input); |
4732 CheckField(field); | 4522 CheckField(field); |
4733 } | 4523 } |
4734 | 4524 |
4735 virtual TokenPosition token_pos() const { | 4525 virtual TokenPosition token_pos() const { return field_.token_pos(); } |
4736 return field_.token_pos(); | |
4737 } | |
4738 const Field& field() const { return field_; } | 4526 const Field& field() const { return field_; } |
4739 | 4527 |
4740 DECLARE_INSTRUCTION(InitStaticField) | 4528 DECLARE_INSTRUCTION(InitStaticField) |
4741 | 4529 |
4742 virtual bool CanDeoptimize() const { return true; } | 4530 virtual bool CanDeoptimize() const { return true; } |
4743 virtual EffectSet Effects() const { return EffectSet::All(); } | 4531 virtual EffectSet Effects() const { return EffectSet::All(); } |
4744 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 4532 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
4745 | 4533 |
4746 private: | 4534 private: |
4747 const Field& field_; | 4535 const Field& field_; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4867 public: | 4655 public: |
4868 static BoxInstr* Create(Representation from, Value* value); | 4656 static BoxInstr* Create(Representation from, Value* value); |
4869 | 4657 |
4870 Value* value() const { return inputs_[0]; } | 4658 Value* value() const { return inputs_[0]; } |
4871 Representation from_representation() const { return from_representation_; } | 4659 Representation from_representation() const { return from_representation_; } |
4872 | 4660 |
4873 DECLARE_INSTRUCTION(Box) | 4661 DECLARE_INSTRUCTION(Box) |
4874 virtual CompileType ComputeType() const; | 4662 virtual CompileType ComputeType() const; |
4875 | 4663 |
4876 virtual bool CanDeoptimize() const { return false; } | 4664 virtual bool CanDeoptimize() const { return false; } |
4877 virtual intptr_t DeoptimizationTarget() const { | 4665 virtual intptr_t DeoptimizationTarget() const { return Thread::kNoDeoptId; } |
4878 return Thread::kNoDeoptId; | |
4879 } | |
4880 | 4666 |
4881 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 4667 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
4882 ASSERT(idx == 0); | 4668 ASSERT(idx == 0); |
4883 return from_representation(); | 4669 return from_representation(); |
4884 } | 4670 } |
4885 | 4671 |
4886 virtual bool AttributesEqual(Instruction* other) const { | 4672 virtual bool AttributesEqual(Instruction* other) const { |
4887 return other->AsBox()->from_representation() == from_representation(); | 4673 return other->AsBox()->from_representation() == from_representation(); |
4888 } | 4674 } |
4889 | 4675 |
4890 Definition* Canonicalize(FlowGraph* flow_graph); | 4676 Definition* Canonicalize(FlowGraph* flow_graph); |
4891 | 4677 |
4892 virtual TokenPosition token_pos() const { | 4678 virtual TokenPosition token_pos() const { return TokenPosition::kBox; } |
4893 return TokenPosition::kBox; | |
4894 } | |
4895 | 4679 |
4896 protected: | 4680 protected: |
4897 BoxInstr(Representation from_representation, Value* value) | 4681 BoxInstr(Representation from_representation, Value* value) |
4898 : from_representation_(from_representation) { | 4682 : from_representation_(from_representation) { |
4899 SetInputAt(0, value); | 4683 SetInputAt(0, value); |
4900 } | 4684 } |
4901 | 4685 |
4902 private: | 4686 private: |
4903 intptr_t ValueOffset() const { | 4687 intptr_t ValueOffset() const { |
4904 return Boxing::ValueOffset(from_representation()); | 4688 return Boxing::ValueOffset(from_representation()); |
4905 } | 4689 } |
4906 | 4690 |
4907 const Representation from_representation_; | 4691 const Representation from_representation_; |
4908 | 4692 |
4909 DISALLOW_COPY_AND_ASSIGN(BoxInstr); | 4693 DISALLOW_COPY_AND_ASSIGN(BoxInstr); |
4910 }; | 4694 }; |
4911 | 4695 |
4912 | 4696 |
4913 class BoxIntegerInstr : public BoxInstr { | 4697 class BoxIntegerInstr : public BoxInstr { |
4914 public: | 4698 public: |
4915 BoxIntegerInstr(Representation representation, Value* value) | 4699 BoxIntegerInstr(Representation representation, Value* value) |
4916 : BoxInstr(representation, value) { } | 4700 : BoxInstr(representation, value) {} |
4917 | 4701 |
4918 virtual bool ValueFitsSmi() const; | 4702 virtual bool ValueFitsSmi() const; |
4919 | 4703 |
4920 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 4704 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
4921 | 4705 |
4922 virtual CompileType ComputeType() const; | 4706 virtual CompileType ComputeType() const; |
4923 virtual bool RecomputeType(); | 4707 virtual bool RecomputeType(); |
4924 | 4708 |
4925 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 4709 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
4926 | 4710 |
4927 DEFINE_INSTRUCTION_TYPE_CHECK(BoxInteger) | 4711 DEFINE_INSTRUCTION_TYPE_CHECK(BoxInteger) |
4928 | 4712 |
4929 private: | 4713 private: |
4930 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); | 4714 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); |
4931 }; | 4715 }; |
4932 | 4716 |
4933 | 4717 |
4934 class BoxInteger32Instr : public BoxIntegerInstr { | 4718 class BoxInteger32Instr : public BoxIntegerInstr { |
4935 public: | 4719 public: |
4936 BoxInteger32Instr(Representation representation, Value* value) | 4720 BoxInteger32Instr(Representation representation, Value* value) |
4937 : BoxIntegerInstr(representation, value) { } | 4721 : BoxIntegerInstr(representation, value) {} |
4938 | 4722 |
4939 DECLARE_INSTRUCTION_BACKEND() | 4723 DECLARE_INSTRUCTION_BACKEND() |
4940 | 4724 |
4941 private: | 4725 private: |
4942 DISALLOW_COPY_AND_ASSIGN(BoxInteger32Instr); | 4726 DISALLOW_COPY_AND_ASSIGN(BoxInteger32Instr); |
4943 }; | 4727 }; |
4944 | 4728 |
4945 | 4729 |
4946 class BoxInt32Instr : public BoxInteger32Instr { | 4730 class BoxInt32Instr : public BoxInteger32Instr { |
4947 public: | 4731 public: |
4948 explicit BoxInt32Instr(Value* value) | 4732 explicit BoxInt32Instr(Value* value) |
4949 : BoxInteger32Instr(kUnboxedInt32, value) { } | 4733 : BoxInteger32Instr(kUnboxedInt32, value) {} |
4950 | 4734 |
4951 DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32) | 4735 DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32) |
4952 | 4736 |
4953 private: | 4737 private: |
4954 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); | 4738 DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr); |
4955 }; | 4739 }; |
4956 | 4740 |
4957 | 4741 |
4958 class BoxUint32Instr : public BoxInteger32Instr { | 4742 class BoxUint32Instr : public BoxInteger32Instr { |
4959 public: | 4743 public: |
4960 explicit BoxUint32Instr(Value* value) | 4744 explicit BoxUint32Instr(Value* value) |
4961 : BoxInteger32Instr(kUnboxedUint32, value) { } | 4745 : BoxInteger32Instr(kUnboxedUint32, value) {} |
4962 | 4746 |
4963 DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32) | 4747 DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32) |
4964 | 4748 |
4965 private: | 4749 private: |
4966 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); | 4750 DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr); |
4967 }; | 4751 }; |
4968 | 4752 |
4969 | 4753 |
4970 class BoxInt64Instr : public BoxIntegerInstr { | 4754 class BoxInt64Instr : public BoxIntegerInstr { |
4971 public: | 4755 public: |
4972 explicit BoxInt64Instr(Value* value) | 4756 explicit BoxInt64Instr(Value* value) : BoxIntegerInstr(kUnboxedMint, value) {} |
4973 : BoxIntegerInstr(kUnboxedMint, value) { } | |
4974 | 4757 |
4975 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 4758 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
4976 | 4759 |
4977 DECLARE_INSTRUCTION(BoxInt64) | 4760 DECLARE_INSTRUCTION(BoxInt64) |
4978 | 4761 |
4979 private: | 4762 private: |
4980 DISALLOW_COPY_AND_ASSIGN(BoxInt64Instr); | 4763 DISALLOW_COPY_AND_ASSIGN(BoxInt64Instr); |
4981 }; | 4764 }; |
4982 | 4765 |
4983 | 4766 |
4984 class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> { | 4767 class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> { |
4985 public: | 4768 public: |
4986 static UnboxInstr* Create(Representation to, Value* value, intptr_t deopt_id); | 4769 static UnboxInstr* Create(Representation to, Value* value, intptr_t deopt_id); |
4987 | 4770 |
4988 Value* value() const { return inputs_[0]; } | 4771 Value* value() const { return inputs_[0]; } |
4989 | 4772 |
4990 virtual bool CanDeoptimize() const { | 4773 virtual bool CanDeoptimize() const { |
4991 const intptr_t value_cid = value()->Type()->ToCid(); | 4774 const intptr_t value_cid = value()->Type()->ToCid(); |
4992 | 4775 |
4993 if (CanConvertSmi() && | 4776 if (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid)) { |
4994 (value()->Type()->ToCid() == kSmiCid)) { | |
4995 return false; | 4777 return false; |
4996 } | 4778 } |
4997 | 4779 |
4998 return (value_cid != BoxCid()); | 4780 return (value_cid != BoxCid()); |
4999 } | 4781 } |
5000 | 4782 |
5001 virtual Representation representation() const { | 4783 virtual Representation representation() const { return representation_; } |
5002 return representation_; | |
5003 } | |
5004 | 4784 |
5005 DECLARE_INSTRUCTION(Unbox) | 4785 DECLARE_INSTRUCTION(Unbox) |
5006 virtual CompileType ComputeType() const; | 4786 virtual CompileType ComputeType() const; |
5007 | 4787 |
5008 virtual bool AttributesEqual(Instruction* other) const { | 4788 virtual bool AttributesEqual(Instruction* other) const { |
5009 return representation() == other->AsUnbox()->representation(); | 4789 return representation() == other->AsUnbox()->representation(); |
5010 } | 4790 } |
5011 | 4791 |
5012 Definition* Canonicalize(FlowGraph* flow_graph); | 4792 Definition* Canonicalize(FlowGraph* flow_graph); |
5013 | 4793 |
5014 virtual intptr_t DeoptimizationTarget() const { | 4794 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } |
5015 return GetDeoptId(); | |
5016 } | |
5017 | 4795 |
5018 virtual TokenPosition token_pos() const { | 4796 virtual TokenPosition token_pos() const { return TokenPosition::kBox; } |
5019 return TokenPosition::kBox; | |
5020 } | |
5021 | 4797 |
5022 protected: | 4798 protected: |
5023 UnboxInstr(Representation representation, | 4799 UnboxInstr(Representation representation, Value* value, intptr_t deopt_id) |
5024 Value* value, | 4800 : TemplateDefinition(deopt_id), representation_(representation) { |
5025 intptr_t deopt_id) | |
5026 : TemplateDefinition(deopt_id), | |
5027 representation_(representation) { | |
5028 SetInputAt(0, value); | 4801 SetInputAt(0, value); |
5029 } | 4802 } |
5030 | 4803 |
5031 private: | 4804 private: |
5032 bool CanConvertSmi() const; | 4805 bool CanConvertSmi() const; |
5033 void EmitLoadFromBox(FlowGraphCompiler* compiler); | 4806 void EmitLoadFromBox(FlowGraphCompiler* compiler); |
5034 void EmitSmiConversion(FlowGraphCompiler* compiler); | 4807 void EmitSmiConversion(FlowGraphCompiler* compiler); |
5035 | 4808 |
5036 intptr_t BoxCid() const { | 4809 intptr_t BoxCid() const { return Boxing::BoxCid(representation_); } |
5037 return Boxing::BoxCid(representation_); | |
5038 } | |
5039 | 4810 |
5040 intptr_t ValueOffset() const { | 4811 intptr_t ValueOffset() const { return Boxing::ValueOffset(representation_); } |
5041 return Boxing::ValueOffset(representation_); | |
5042 } | |
5043 | 4812 |
5044 const Representation representation_; | 4813 const Representation representation_; |
5045 | 4814 |
5046 DISALLOW_COPY_AND_ASSIGN(UnboxInstr); | 4815 DISALLOW_COPY_AND_ASSIGN(UnboxInstr); |
5047 }; | 4816 }; |
5048 | 4817 |
5049 | 4818 |
5050 class UnboxIntegerInstr : public UnboxInstr { | 4819 class UnboxIntegerInstr : public UnboxInstr { |
5051 public: | 4820 public: |
5052 enum TruncationMode { kTruncate, kNoTruncation }; | 4821 enum TruncationMode { kTruncate, kNoTruncation }; |
5053 | 4822 |
5054 UnboxIntegerInstr(Representation representation, | 4823 UnboxIntegerInstr(Representation representation, |
5055 TruncationMode truncation_mode, | 4824 TruncationMode truncation_mode, |
5056 Value* value, | 4825 Value* value, |
5057 intptr_t deopt_id) | 4826 intptr_t deopt_id) |
5058 : UnboxInstr(representation, value, deopt_id), | 4827 : UnboxInstr(representation, value, deopt_id), |
5059 is_truncating_(truncation_mode == kTruncate) { | 4828 is_truncating_(truncation_mode == kTruncate) {} |
5060 } | |
5061 | 4829 |
5062 bool is_truncating() const { return is_truncating_; } | 4830 bool is_truncating() const { return is_truncating_; } |
5063 | 4831 |
5064 virtual CompileType ComputeType() const; | 4832 virtual CompileType ComputeType() const; |
5065 | 4833 |
5066 virtual bool AttributesEqual(Instruction* other) const { | 4834 virtual bool AttributesEqual(Instruction* other) const { |
5067 UnboxIntegerInstr* other_unbox = other->AsUnboxInteger(); | 4835 UnboxIntegerInstr* other_unbox = other->AsUnboxInteger(); |
5068 return UnboxInstr::AttributesEqual(other) && | 4836 return UnboxInstr::AttributesEqual(other) && |
5069 (other_unbox->is_truncating_ == is_truncating_); | 4837 (other_unbox->is_truncating_ == is_truncating_); |
5070 } | 4838 } |
5071 | 4839 |
5072 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 4840 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
5073 | 4841 |
5074 DEFINE_INSTRUCTION_TYPE_CHECK(UnboxInteger) | 4842 DEFINE_INSTRUCTION_TYPE_CHECK(UnboxInteger) |
5075 | 4843 |
5076 PRINT_OPERANDS_TO_SUPPORT | 4844 PRINT_OPERANDS_TO_SUPPORT |
5077 | 4845 |
5078 private: | 4846 private: |
5079 bool is_truncating_; | 4847 bool is_truncating_; |
5080 | 4848 |
5081 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); | 4849 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); |
5082 }; | 4850 }; |
5083 | 4851 |
5084 | 4852 |
5085 class UnboxInteger32Instr : public UnboxIntegerInstr { | 4853 class UnboxInteger32Instr : public UnboxIntegerInstr { |
5086 public: | 4854 public: |
5087 UnboxInteger32Instr(Representation representation, | 4855 UnboxInteger32Instr(Representation representation, |
5088 TruncationMode truncation_mode, | 4856 TruncationMode truncation_mode, |
5089 Value* value, | 4857 Value* value, |
5090 intptr_t deopt_id) | 4858 intptr_t deopt_id) |
5091 : UnboxIntegerInstr(representation, truncation_mode, value, deopt_id) { } | 4859 : UnboxIntegerInstr(representation, truncation_mode, value, deopt_id) {} |
5092 | 4860 |
5093 DECLARE_INSTRUCTION_BACKEND() | 4861 DECLARE_INSTRUCTION_BACKEND() |
5094 | 4862 |
5095 private: | 4863 private: |
5096 DISALLOW_COPY_AND_ASSIGN(UnboxInteger32Instr); | 4864 DISALLOW_COPY_AND_ASSIGN(UnboxInteger32Instr); |
5097 }; | 4865 }; |
5098 | 4866 |
5099 | 4867 |
5100 class UnboxUint32Instr : public UnboxInteger32Instr { | 4868 class UnboxUint32Instr : public UnboxInteger32Instr { |
5101 public: | 4869 public: |
(...skipping 11 matching lines...) Expand all Loading... |
5113 private: | 4881 private: |
5114 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); | 4882 DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr); |
5115 }; | 4883 }; |
5116 | 4884 |
5117 | 4885 |
5118 class UnboxInt32Instr : public UnboxInteger32Instr { | 4886 class UnboxInt32Instr : public UnboxInteger32Instr { |
5119 public: | 4887 public: |
5120 UnboxInt32Instr(TruncationMode truncation_mode, | 4888 UnboxInt32Instr(TruncationMode truncation_mode, |
5121 Value* value, | 4889 Value* value, |
5122 intptr_t deopt_id) | 4890 intptr_t deopt_id) |
5123 : UnboxInteger32Instr(kUnboxedInt32, truncation_mode, value, deopt_id) { | 4891 : UnboxInteger32Instr(kUnboxedInt32, truncation_mode, value, deopt_id) {} |
5124 } | |
5125 | 4892 |
5126 virtual bool CanDeoptimize() const; | 4893 virtual bool CanDeoptimize() const; |
5127 | 4894 |
5128 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 4895 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
5129 | 4896 |
5130 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 4897 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
5131 | 4898 |
5132 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32) | 4899 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32) |
5133 | 4900 |
5134 private: | 4901 private: |
5135 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); | 4902 DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr); |
5136 }; | 4903 }; |
5137 | 4904 |
5138 | 4905 |
5139 class UnboxInt64Instr : public UnboxIntegerInstr { | 4906 class UnboxInt64Instr : public UnboxIntegerInstr { |
5140 public: | 4907 public: |
5141 UnboxInt64Instr(Value* value, intptr_t deopt_id) | 4908 UnboxInt64Instr(Value* value, intptr_t deopt_id) |
5142 : UnboxIntegerInstr(kUnboxedMint, kNoTruncation, value, deopt_id) { | 4909 : UnboxIntegerInstr(kUnboxedMint, kNoTruncation, value, deopt_id) {} |
5143 } | |
5144 | 4910 |
5145 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 4911 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
5146 | 4912 |
5147 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64) | 4913 DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64) |
5148 | 4914 |
5149 private: | 4915 private: |
5150 DISALLOW_COPY_AND_ASSIGN(UnboxInt64Instr); | 4916 DISALLOW_COPY_AND_ASSIGN(UnboxInt64Instr); |
5151 }; | 4917 }; |
5152 | 4918 |
5153 | 4919 |
5154 bool Definition::IsMintDefinition() { | 4920 bool Definition::IsMintDefinition() { |
5155 return (Type()->ToCid() == kMintCid) || | 4921 return (Type()->ToCid() == kMintCid) || IsBinaryMintOp() || IsUnaryMintOp() || |
5156 IsBinaryMintOp() || | 4922 IsShiftMintOp() || IsBoxInt64() || IsUnboxInt64(); |
5157 IsUnaryMintOp() || | |
5158 IsShiftMintOp() || | |
5159 IsBoxInt64() || | |
5160 IsUnboxInt64(); | |
5161 } | 4923 } |
5162 | 4924 |
5163 | 4925 |
5164 class MathUnaryInstr : public TemplateDefinition<1, NoThrow, Pure> { | 4926 class MathUnaryInstr : public TemplateDefinition<1, NoThrow, Pure> { |
5165 public: | 4927 public: |
5166 enum MathUnaryKind { | 4928 enum MathUnaryKind { |
5167 kIllegal, | 4929 kIllegal, |
5168 kSqrt, | 4930 kSqrt, |
5169 kDoubleSquare, | 4931 kDoubleSquare, |
5170 }; | 4932 }; |
5171 MathUnaryInstr(MathUnaryKind kind, Value* value, intptr_t deopt_id) | 4933 MathUnaryInstr(MathUnaryKind kind, Value* value, intptr_t deopt_id) |
5172 : TemplateDefinition(deopt_id), kind_(kind) { | 4934 : TemplateDefinition(deopt_id), kind_(kind) { |
5173 SetInputAt(0, value); | 4935 SetInputAt(0, value); |
5174 } | 4936 } |
5175 | 4937 |
5176 Value* value() const { return inputs_[0]; } | 4938 Value* value() const { return inputs_[0]; } |
5177 MathUnaryKind kind() const { return kind_; } | 4939 MathUnaryKind kind() const { return kind_; } |
5178 | 4940 |
5179 virtual bool CanDeoptimize() const { return false; } | 4941 virtual bool CanDeoptimize() const { return false; } |
5180 | 4942 |
5181 virtual Representation representation() const { | 4943 virtual Representation representation() const { return kUnboxedDouble; } |
5182 return kUnboxedDouble; | |
5183 } | |
5184 | 4944 |
5185 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 4945 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5186 ASSERT(idx == 0); | 4946 ASSERT(idx == 0); |
5187 return kUnboxedDouble; | 4947 return kUnboxedDouble; |
5188 } | 4948 } |
5189 | 4949 |
5190 virtual intptr_t DeoptimizationTarget() const { | 4950 virtual intptr_t DeoptimizationTarget() const { |
5191 // Direct access since this instruction cannot deoptimize, and the deopt-id | 4951 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5192 // was inherited from another instruction that could deoptimize. | 4952 // was inherited from another instruction that could deoptimize. |
5193 return GetDeoptId(); | 4953 return GetDeoptId(); |
(...skipping 21 matching lines...) Expand all Loading... |
5215 | 4975 |
5216 // Calls into the runtime and performs a case-insensitive comparison of the | 4976 // Calls into the runtime and performs a case-insensitive comparison of the |
5217 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at | 4977 // UTF16 strings (i.e. TwoByteString or ExternalTwoByteString) located at |
5218 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length]. | 4978 // str[lhs_index:lhs_index + length] and str[rhs_index:rhs_index + length]. |
5219 // | 4979 // |
5220 // TODO(zerny): Remove this once (if) functions inherited from unibrow | 4980 // TODO(zerny): Remove this once (if) functions inherited from unibrow |
5221 // are moved to dart code. | 4981 // are moved to dart code. |
5222 class CaseInsensitiveCompareUC16Instr | 4982 class CaseInsensitiveCompareUC16Instr |
5223 : public TemplateDefinition<4, NoThrow, Pure> { | 4983 : public TemplateDefinition<4, NoThrow, Pure> { |
5224 public: | 4984 public: |
5225 CaseInsensitiveCompareUC16Instr( | 4985 CaseInsensitiveCompareUC16Instr(Value* str, |
5226 Value* str, | 4986 Value* lhs_index, |
5227 Value* lhs_index, | 4987 Value* rhs_index, |
5228 Value* rhs_index, | 4988 Value* length, |
5229 Value* length, | 4989 intptr_t cid) |
5230 intptr_t cid) | 4990 : cid_(cid) { |
5231 : cid_(cid) { | |
5232 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid); | 4991 ASSERT(cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid); |
5233 ASSERT(index_scale() == 2); | 4992 ASSERT(index_scale() == 2); |
5234 SetInputAt(0, str); | 4993 SetInputAt(0, str); |
5235 SetInputAt(1, lhs_index); | 4994 SetInputAt(1, lhs_index); |
5236 SetInputAt(2, rhs_index); | 4995 SetInputAt(2, rhs_index); |
5237 SetInputAt(3, length); | 4996 SetInputAt(3, length); |
5238 } | 4997 } |
5239 | 4998 |
5240 Value* str() const { return inputs_[0]; } | 4999 Value* str() const { return inputs_[0]; } |
5241 Value* lhs_index() const { return inputs_[1]; } | 5000 Value* lhs_index() const { return inputs_[1]; } |
5242 Value* rhs_index() const { return inputs_[2]; } | 5001 Value* rhs_index() const { return inputs_[2]; } |
5243 Value* length() const { return inputs_[3]; } | 5002 Value* length() const { return inputs_[3]; } |
5244 | 5003 |
5245 const RuntimeEntry& TargetFunction() const; | 5004 const RuntimeEntry& TargetFunction() const; |
5246 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; } | 5005 bool IsExternal() const { return cid_ == kExternalTwoByteStringCid; } |
5247 intptr_t class_id() const { return cid_; } | 5006 intptr_t class_id() const { return cid_; } |
5248 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); } | 5007 intptr_t index_scale() const { return Instance::ElementSizeFor(cid_); } |
5249 | 5008 |
5250 virtual bool CanDeoptimize() const { return false; } | 5009 virtual bool CanDeoptimize() const { return false; } |
5251 | 5010 |
5252 virtual Representation representation() const { | 5011 virtual Representation representation() const { return kTagged; } |
5253 return kTagged; | |
5254 } | |
5255 | 5012 |
5256 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16) | 5013 DECLARE_INSTRUCTION(CaseInsensitiveCompareUC16) |
5257 virtual CompileType ComputeType() const; | 5014 virtual CompileType ComputeType() const; |
5258 | 5015 |
5259 virtual bool AttributesEqual(Instruction* other) const { | 5016 virtual bool AttributesEqual(Instruction* other) const { |
5260 return other->AsCaseInsensitiveCompareUC16()->cid_ == cid_; | 5017 return other->AsCaseInsensitiveCompareUC16()->cid_ == cid_; |
5261 } | 5018 } |
5262 | 5019 |
5263 private: | 5020 private: |
5264 const intptr_t cid_; | 5021 const intptr_t cid_; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5326 }; | 5083 }; |
5327 | 5084 |
5328 | 5085 |
5329 class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> { | 5086 class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> { |
5330 public: | 5087 public: |
5331 BinaryDoubleOpInstr(Token::Kind op_kind, | 5088 BinaryDoubleOpInstr(Token::Kind op_kind, |
5332 Value* left, | 5089 Value* left, |
5333 Value* right, | 5090 Value* right, |
5334 intptr_t deopt_id, | 5091 intptr_t deopt_id, |
5335 TokenPosition token_pos) | 5092 TokenPosition token_pos) |
5336 : TemplateDefinition(deopt_id), | 5093 : TemplateDefinition(deopt_id), op_kind_(op_kind), token_pos_(token_pos) { |
5337 op_kind_(op_kind), | |
5338 token_pos_(token_pos) { | |
5339 SetInputAt(0, left); | 5094 SetInputAt(0, left); |
5340 SetInputAt(1, right); | 5095 SetInputAt(1, right); |
5341 } | 5096 } |
5342 | 5097 |
5343 Value* left() const { return inputs_[0]; } | 5098 Value* left() const { return inputs_[0]; } |
5344 Value* right() const { return inputs_[1]; } | 5099 Value* right() const { return inputs_[1]; } |
5345 | 5100 |
5346 Token::Kind op_kind() const { return op_kind_; } | 5101 Token::Kind op_kind() const { return op_kind_; } |
5347 | 5102 |
5348 virtual TokenPosition token_pos() const { return token_pos_; } | 5103 virtual TokenPosition token_pos() const { return token_pos_; } |
5349 | 5104 |
5350 virtual bool CanDeoptimize() const { return false; } | 5105 virtual bool CanDeoptimize() const { return false; } |
5351 | 5106 |
5352 virtual Representation representation() const { | 5107 virtual Representation representation() const { return kUnboxedDouble; } |
5353 return kUnboxedDouble; | |
5354 } | |
5355 | 5108 |
5356 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5109 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5357 ASSERT((idx == 0) || (idx == 1)); | 5110 ASSERT((idx == 0) || (idx == 1)); |
5358 return kUnboxedDouble; | 5111 return kUnboxedDouble; |
5359 } | 5112 } |
5360 | 5113 |
5361 virtual intptr_t DeoptimizationTarget() const { | 5114 virtual intptr_t DeoptimizationTarget() const { |
5362 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5115 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5363 // was inherited from another instruction that could deoptimize. | 5116 // was inherited from another instruction that could deoptimize. |
5364 return GetDeoptId(); | 5117 return GetDeoptId(); |
(...skipping 17 matching lines...) Expand all Loading... |
5382 DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr); | 5135 DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr); |
5383 }; | 5136 }; |
5384 | 5137 |
5385 | 5138 |
5386 class DoubleTestOpInstr : public TemplateComparison<1, NoThrow, Pure> { | 5139 class DoubleTestOpInstr : public TemplateComparison<1, NoThrow, Pure> { |
5387 public: | 5140 public: |
5388 DoubleTestOpInstr(MethodRecognizer::Kind op_kind, | 5141 DoubleTestOpInstr(MethodRecognizer::Kind op_kind, |
5389 Value* value, | 5142 Value* value, |
5390 intptr_t deopt_id, | 5143 intptr_t deopt_id, |
5391 TokenPosition token_pos) | 5144 TokenPosition token_pos) |
5392 : TemplateComparison(token_pos, Token::kEQ, deopt_id), | 5145 : TemplateComparison(token_pos, Token::kEQ, deopt_id), op_kind_(op_kind) { |
5393 op_kind_(op_kind) { | |
5394 SetInputAt(0, value); | 5146 SetInputAt(0, value); |
5395 } | 5147 } |
5396 | 5148 |
5397 Value* value() const { return InputAt(0); } | 5149 Value* value() const { return InputAt(0); } |
5398 | 5150 |
5399 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5151 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5400 | 5152 |
5401 virtual bool CanDeoptimize() const { return false; } | 5153 virtual bool CanDeoptimize() const { return false; } |
5402 | 5154 |
5403 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5155 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5404 ASSERT(idx == 0); | 5156 ASSERT(idx == 0); |
5405 return kUnboxedDouble; | 5157 return kUnboxedDouble; |
5406 } | 5158 } |
5407 | 5159 |
5408 PRINT_OPERANDS_TO_SUPPORT | 5160 PRINT_OPERANDS_TO_SUPPORT |
5409 | 5161 |
5410 DECLARE_INSTRUCTION(DoubleTestOp) | 5162 DECLARE_INSTRUCTION(DoubleTestOp) |
5411 virtual CompileType ComputeType() const; | 5163 virtual CompileType ComputeType() const; |
5412 | 5164 |
5413 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 5165 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
5414 | 5166 |
5415 virtual bool AttributesEqual(Instruction* other) const { | 5167 virtual bool AttributesEqual(Instruction* other) const { |
5416 return op_kind_ == other->AsDoubleTestOp()->op_kind() | 5168 return op_kind_ == other->AsDoubleTestOp()->op_kind() && |
5417 && ComparisonInstr::AttributesEqual(other); | 5169 ComparisonInstr::AttributesEqual(other); |
5418 } | 5170 } |
5419 | 5171 |
5420 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); | 5172 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
5421 | 5173 |
5422 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 5174 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
5423 BranchInstr* branch); | |
5424 | 5175 |
5425 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 5176 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
5426 BranchLabels labels); | 5177 BranchLabels labels); |
5427 | 5178 |
5428 private: | 5179 private: |
5429 const MethodRecognizer::Kind op_kind_; | 5180 const MethodRecognizer::Kind op_kind_; |
5430 | 5181 |
5431 DISALLOW_COPY_AND_ASSIGN(DoubleTestOpInstr); | 5182 DISALLOW_COPY_AND_ASSIGN(DoubleTestOpInstr); |
5432 }; | 5183 }; |
5433 | 5184 |
5434 | 5185 |
5435 class BinaryFloat32x4OpInstr : public TemplateDefinition<2, NoThrow, Pure> { | 5186 class BinaryFloat32x4OpInstr : public TemplateDefinition<2, NoThrow, Pure> { |
5436 public: | 5187 public: |
5437 BinaryFloat32x4OpInstr(Token::Kind op_kind, | 5188 BinaryFloat32x4OpInstr(Token::Kind op_kind, |
5438 Value* left, | 5189 Value* left, |
5439 Value* right, | 5190 Value* right, |
5440 intptr_t deopt_id) | 5191 intptr_t deopt_id) |
5441 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 5192 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
5442 SetInputAt(0, left); | 5193 SetInputAt(0, left); |
5443 SetInputAt(1, right); | 5194 SetInputAt(1, right); |
5444 } | 5195 } |
5445 | 5196 |
5446 Value* left() const { return inputs_[0]; } | 5197 Value* left() const { return inputs_[0]; } |
5447 Value* right() const { return inputs_[1]; } | 5198 Value* right() const { return inputs_[1]; } |
5448 | 5199 |
5449 Token::Kind op_kind() const { return op_kind_; } | 5200 Token::Kind op_kind() const { return op_kind_; } |
5450 | 5201 |
5451 virtual bool CanDeoptimize() const { return false; } | 5202 virtual bool CanDeoptimize() const { return false; } |
5452 | 5203 |
5453 virtual Representation representation() const { | 5204 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5454 return kUnboxedFloat32x4; | |
5455 } | |
5456 | 5205 |
5457 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5206 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5458 ASSERT((idx == 0) || (idx == 1)); | 5207 ASSERT((idx == 0) || (idx == 1)); |
5459 return kUnboxedFloat32x4; | 5208 return kUnboxedFloat32x4; |
5460 } | 5209 } |
5461 | 5210 |
5462 virtual intptr_t DeoptimizationTarget() const { | 5211 virtual intptr_t DeoptimizationTarget() const { |
5463 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5212 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5464 // was inherited from another instruction that could deoptimize. | 5213 // was inherited from another instruction that could deoptimize. |
5465 return GetDeoptId(); | 5214 return GetDeoptId(); |
(...skipping 10 matching lines...) Expand all Loading... |
5476 | 5225 |
5477 private: | 5226 private: |
5478 const Token::Kind op_kind_; | 5227 const Token::Kind op_kind_; |
5479 | 5228 |
5480 DISALLOW_COPY_AND_ASSIGN(BinaryFloat32x4OpInstr); | 5229 DISALLOW_COPY_AND_ASSIGN(BinaryFloat32x4OpInstr); |
5481 }; | 5230 }; |
5482 | 5231 |
5483 | 5232 |
5484 class Simd32x4ShuffleInstr : public TemplateDefinition<1, NoThrow, Pure> { | 5233 class Simd32x4ShuffleInstr : public TemplateDefinition<1, NoThrow, Pure> { |
5485 public: | 5234 public: |
5486 Simd32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value, | 5235 Simd32x4ShuffleInstr(MethodRecognizer::Kind op_kind, |
| 5236 Value* value, |
5487 intptr_t mask, | 5237 intptr_t mask, |
5488 intptr_t deopt_id) | 5238 intptr_t deopt_id) |
5489 : TemplateDefinition(deopt_id), op_kind_(op_kind), mask_(mask) { | 5239 : TemplateDefinition(deopt_id), op_kind_(op_kind), mask_(mask) { |
5490 SetInputAt(0, value); | 5240 SetInputAt(0, value); |
5491 } | 5241 } |
5492 | 5242 |
5493 Value* value() const { return inputs_[0]; } | 5243 Value* value() const { return inputs_[0]; } |
5494 | 5244 |
5495 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5245 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5496 | 5246 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5544 private: | 5294 private: |
5545 const MethodRecognizer::Kind op_kind_; | 5295 const MethodRecognizer::Kind op_kind_; |
5546 const intptr_t mask_; | 5296 const intptr_t mask_; |
5547 | 5297 |
5548 DISALLOW_COPY_AND_ASSIGN(Simd32x4ShuffleInstr); | 5298 DISALLOW_COPY_AND_ASSIGN(Simd32x4ShuffleInstr); |
5549 }; | 5299 }; |
5550 | 5300 |
5551 | 5301 |
5552 class Simd32x4ShuffleMixInstr : public TemplateDefinition<2, NoThrow, Pure> { | 5302 class Simd32x4ShuffleMixInstr : public TemplateDefinition<2, NoThrow, Pure> { |
5553 public: | 5303 public: |
5554 Simd32x4ShuffleMixInstr(MethodRecognizer::Kind op_kind, Value* xy, | 5304 Simd32x4ShuffleMixInstr(MethodRecognizer::Kind op_kind, |
5555 Value* zw, intptr_t mask, intptr_t deopt_id) | 5305 Value* xy, |
| 5306 Value* zw, |
| 5307 intptr_t mask, |
| 5308 intptr_t deopt_id) |
5556 : TemplateDefinition(deopt_id), op_kind_(op_kind), mask_(mask) { | 5309 : TemplateDefinition(deopt_id), op_kind_(op_kind), mask_(mask) { |
5557 SetInputAt(0, xy); | 5310 SetInputAt(0, xy); |
5558 SetInputAt(1, zw); | 5311 SetInputAt(1, zw); |
5559 } | 5312 } |
5560 | 5313 |
5561 Value* xy() const { return inputs_[0]; } | 5314 Value* xy() const { return inputs_[0]; } |
5562 Value* zw() const { return inputs_[1]; } | 5315 Value* zw() const { return inputs_[1]; } |
5563 | 5316 |
5564 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5317 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5565 | 5318 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5622 SetInputAt(3, value3); | 5375 SetInputAt(3, value3); |
5623 } | 5376 } |
5624 | 5377 |
5625 Value* value0() const { return inputs_[0]; } | 5378 Value* value0() const { return inputs_[0]; } |
5626 Value* value1() const { return inputs_[1]; } | 5379 Value* value1() const { return inputs_[1]; } |
5627 Value* value2() const { return inputs_[2]; } | 5380 Value* value2() const { return inputs_[2]; } |
5628 Value* value3() const { return inputs_[3]; } | 5381 Value* value3() const { return inputs_[3]; } |
5629 | 5382 |
5630 virtual bool CanDeoptimize() const { return false; } | 5383 virtual bool CanDeoptimize() const { return false; } |
5631 | 5384 |
5632 virtual Representation representation() const { | 5385 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5633 return kUnboxedFloat32x4; | |
5634 } | |
5635 | 5386 |
5636 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5387 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5637 ASSERT(idx >= 0 && idx < 4); | 5388 ASSERT(idx >= 0 && idx < 4); |
5638 return kUnboxedDouble; | 5389 return kUnboxedDouble; |
5639 } | 5390 } |
5640 | 5391 |
5641 virtual intptr_t DeoptimizationTarget() const { | 5392 virtual intptr_t DeoptimizationTarget() const { |
5642 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5393 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5643 // was inherited from another instruction that could deoptimize. | 5394 // was inherited from another instruction that could deoptimize. |
5644 return GetDeoptId(); | 5395 return GetDeoptId(); |
(...skipping 15 matching lines...) Expand all Loading... |
5660 public: | 5411 public: |
5661 Float32x4SplatInstr(Value* value, intptr_t deopt_id) | 5412 Float32x4SplatInstr(Value* value, intptr_t deopt_id) |
5662 : TemplateDefinition(deopt_id) { | 5413 : TemplateDefinition(deopt_id) { |
5663 SetInputAt(0, value); | 5414 SetInputAt(0, value); |
5664 } | 5415 } |
5665 | 5416 |
5666 Value* value() const { return inputs_[0]; } | 5417 Value* value() const { return inputs_[0]; } |
5667 | 5418 |
5668 virtual bool CanDeoptimize() const { return false; } | 5419 virtual bool CanDeoptimize() const { return false; } |
5669 | 5420 |
5670 virtual Representation representation() const { | 5421 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5671 return kUnboxedFloat32x4; | |
5672 } | |
5673 | 5422 |
5674 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5423 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5675 ASSERT(idx == 0); | 5424 ASSERT(idx == 0); |
5676 return kUnboxedDouble; | 5425 return kUnboxedDouble; |
5677 } | 5426 } |
5678 | 5427 |
5679 virtual intptr_t DeoptimizationTarget() const { | 5428 virtual intptr_t DeoptimizationTarget() const { |
5680 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5429 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5681 // was inherited from another instruction that could deoptimize. | 5430 // was inherited from another instruction that could deoptimize. |
5682 return GetDeoptId(); | 5431 return GetDeoptId(); |
5683 } | 5432 } |
5684 | 5433 |
5685 DECLARE_INSTRUCTION(Float32x4Splat) | 5434 DECLARE_INSTRUCTION(Float32x4Splat) |
5686 virtual CompileType ComputeType() const; | 5435 virtual CompileType ComputeType() const; |
5687 | 5436 |
5688 virtual bool AttributesEqual(Instruction* other) const { return true; } | 5437 virtual bool AttributesEqual(Instruction* other) const { return true; } |
5689 | 5438 |
5690 PRINT_OPERANDS_TO_SUPPORT | 5439 PRINT_OPERANDS_TO_SUPPORT |
5691 | 5440 |
5692 private: | 5441 private: |
5693 DISALLOW_COPY_AND_ASSIGN(Float32x4SplatInstr); | 5442 DISALLOW_COPY_AND_ASSIGN(Float32x4SplatInstr); |
5694 }; | 5443 }; |
5695 | 5444 |
5696 | 5445 |
5697 // TODO(vegorov) replace with UnboxedConstantInstr. | 5446 // TODO(vegorov) replace with UnboxedConstantInstr. |
5698 class Float32x4ZeroInstr : public TemplateDefinition<0, NoThrow, Pure> { | 5447 class Float32x4ZeroInstr : public TemplateDefinition<0, NoThrow, Pure> { |
5699 public: | 5448 public: |
5700 Float32x4ZeroInstr() { } | 5449 Float32x4ZeroInstr() {} |
5701 | 5450 |
5702 virtual bool CanDeoptimize() const { return false; } | 5451 virtual bool CanDeoptimize() const { return false; } |
5703 | 5452 |
5704 virtual Representation representation() const { | 5453 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5705 return kUnboxedFloat32x4; | |
5706 } | |
5707 | 5454 |
5708 DECLARE_INSTRUCTION(Float32x4Zero) | 5455 DECLARE_INSTRUCTION(Float32x4Zero) |
5709 virtual CompileType ComputeType() const; | 5456 virtual CompileType ComputeType() const; |
5710 | 5457 |
5711 virtual bool AttributesEqual(Instruction* other) const { return true; } | 5458 virtual bool AttributesEqual(Instruction* other) const { return true; } |
5712 | 5459 |
5713 private: | 5460 private: |
5714 DISALLOW_COPY_AND_ASSIGN(Float32x4ZeroInstr); | 5461 DISALLOW_COPY_AND_ASSIGN(Float32x4ZeroInstr); |
5715 }; | 5462 }; |
5716 | 5463 |
5717 | 5464 |
5718 class Float32x4ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { | 5465 class Float32x4ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { |
5719 public: | 5466 public: |
5720 Float32x4ComparisonInstr(MethodRecognizer::Kind op_kind, | 5467 Float32x4ComparisonInstr(MethodRecognizer::Kind op_kind, |
5721 Value* left, | 5468 Value* left, |
5722 Value* right, | 5469 Value* right, |
5723 intptr_t deopt_id) | 5470 intptr_t deopt_id) |
5724 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 5471 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
5725 SetInputAt(0, left); | 5472 SetInputAt(0, left); |
5726 SetInputAt(1, right); | 5473 SetInputAt(1, right); |
5727 } | 5474 } |
5728 | 5475 |
5729 Value* left() const { return inputs_[0]; } | 5476 Value* left() const { return inputs_[0]; } |
5730 Value* right() const { return inputs_[1]; } | 5477 Value* right() const { return inputs_[1]; } |
5731 | 5478 |
5732 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5479 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5733 | 5480 |
5734 virtual bool CanDeoptimize() const { return false; } | 5481 virtual bool CanDeoptimize() const { return false; } |
5735 | 5482 |
5736 virtual Representation representation() const { | 5483 virtual Representation representation() const { return kUnboxedInt32x4; } |
5737 return kUnboxedInt32x4; | |
5738 } | |
5739 | 5484 |
5740 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5485 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5741 ASSERT((idx == 0) || (idx == 1)); | 5486 ASSERT((idx == 0) || (idx == 1)); |
5742 return kUnboxedFloat32x4; | 5487 return kUnboxedFloat32x4; |
5743 } | 5488 } |
5744 | 5489 |
5745 virtual intptr_t DeoptimizationTarget() const { | 5490 virtual intptr_t DeoptimizationTarget() const { |
5746 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5491 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5747 // was inherited from another instruction that could deoptimize. | 5492 // was inherited from another instruction that could deoptimize. |
5748 return GetDeoptId(); | 5493 return GetDeoptId(); |
(...skipping 26 matching lines...) Expand all Loading... |
5775 SetInputAt(1, right); | 5520 SetInputAt(1, right); |
5776 } | 5521 } |
5777 | 5522 |
5778 Value* left() const { return inputs_[0]; } | 5523 Value* left() const { return inputs_[0]; } |
5779 Value* right() const { return inputs_[1]; } | 5524 Value* right() const { return inputs_[1]; } |
5780 | 5525 |
5781 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5526 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5782 | 5527 |
5783 virtual bool CanDeoptimize() const { return false; } | 5528 virtual bool CanDeoptimize() const { return false; } |
5784 | 5529 |
5785 virtual Representation representation() const { | 5530 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5786 return kUnboxedFloat32x4; | |
5787 } | |
5788 | 5531 |
5789 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5532 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5790 ASSERT((idx == 0) || (idx == 1)); | 5533 ASSERT((idx == 0) || (idx == 1)); |
5791 return kUnboxedFloat32x4; | 5534 return kUnboxedFloat32x4; |
5792 } | 5535 } |
5793 | 5536 |
5794 virtual intptr_t DeoptimizationTarget() const { | 5537 virtual intptr_t DeoptimizationTarget() const { |
5795 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5538 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5796 // was inherited from another instruction that could deoptimize. | 5539 // was inherited from another instruction that could deoptimize. |
5797 return GetDeoptId(); | 5540 return GetDeoptId(); |
(...skipping 26 matching lines...) Expand all Loading... |
5824 SetInputAt(1, right); | 5567 SetInputAt(1, right); |
5825 } | 5568 } |
5826 | 5569 |
5827 Value* left() const { return inputs_[0]; } | 5570 Value* left() const { return inputs_[0]; } |
5828 Value* right() const { return inputs_[1]; } | 5571 Value* right() const { return inputs_[1]; } |
5829 | 5572 |
5830 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5573 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5831 | 5574 |
5832 virtual bool CanDeoptimize() const { return false; } | 5575 virtual bool CanDeoptimize() const { return false; } |
5833 | 5576 |
5834 virtual Representation representation() const { | 5577 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5835 return kUnboxedFloat32x4; | |
5836 } | |
5837 | 5578 |
5838 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5579 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5839 ASSERT((idx == 0) || (idx == 1)); | 5580 ASSERT((idx == 0) || (idx == 1)); |
5840 if (idx == 0) { | 5581 if (idx == 0) { |
5841 return kUnboxedDouble; | 5582 return kUnboxedDouble; |
5842 } | 5583 } |
5843 return kUnboxedFloat32x4; | 5584 return kUnboxedFloat32x4; |
5844 } | 5585 } |
5845 | 5586 |
5846 virtual intptr_t DeoptimizationTarget() const { | 5587 virtual intptr_t DeoptimizationTarget() const { |
(...skipping 26 matching lines...) Expand all Loading... |
5873 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 5614 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
5874 SetInputAt(0, left); | 5615 SetInputAt(0, left); |
5875 } | 5616 } |
5876 | 5617 |
5877 Value* left() const { return inputs_[0]; } | 5618 Value* left() const { return inputs_[0]; } |
5878 | 5619 |
5879 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5620 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5880 | 5621 |
5881 virtual bool CanDeoptimize() const { return false; } | 5622 virtual bool CanDeoptimize() const { return false; } |
5882 | 5623 |
5883 virtual Representation representation() const { | 5624 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5884 return kUnboxedFloat32x4; | |
5885 } | |
5886 | 5625 |
5887 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5626 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5888 ASSERT(idx == 0); | 5627 ASSERT(idx == 0); |
5889 return kUnboxedFloat32x4; | 5628 return kUnboxedFloat32x4; |
5890 } | 5629 } |
5891 | 5630 |
5892 virtual intptr_t DeoptimizationTarget() const { | 5631 virtual intptr_t DeoptimizationTarget() const { |
5893 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5632 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5894 // was inherited from another instruction that could deoptimize. | 5633 // was inherited from another instruction that could deoptimize. |
5895 return GetDeoptId(); | 5634 return GetDeoptId(); |
(...skipping 14 matching lines...) Expand all Loading... |
5910 DISALLOW_COPY_AND_ASSIGN(Float32x4SqrtInstr); | 5649 DISALLOW_COPY_AND_ASSIGN(Float32x4SqrtInstr); |
5911 }; | 5650 }; |
5912 | 5651 |
5913 | 5652 |
5914 // TODO(vegorov) rename to Unary to match naming convention for arithmetic. | 5653 // TODO(vegorov) rename to Unary to match naming convention for arithmetic. |
5915 class Float32x4ZeroArgInstr : public TemplateDefinition<1, NoThrow, Pure> { | 5654 class Float32x4ZeroArgInstr : public TemplateDefinition<1, NoThrow, Pure> { |
5916 public: | 5655 public: |
5917 Float32x4ZeroArgInstr(MethodRecognizer::Kind op_kind, | 5656 Float32x4ZeroArgInstr(MethodRecognizer::Kind op_kind, |
5918 Value* left, | 5657 Value* left, |
5919 intptr_t deopt_id) | 5658 intptr_t deopt_id) |
5920 : TemplateDefinition(deopt_id), | 5659 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
5921 op_kind_(op_kind) { | |
5922 SetInputAt(0, left); | 5660 SetInputAt(0, left); |
5923 } | 5661 } |
5924 | 5662 |
5925 Value* left() const { return inputs_[0]; } | 5663 Value* left() const { return inputs_[0]; } |
5926 | 5664 |
5927 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5665 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
5928 | 5666 |
5929 virtual bool CanDeoptimize() const { return false; } | 5667 virtual bool CanDeoptimize() const { return false; } |
5930 | 5668 |
5931 virtual Representation representation() const { | 5669 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5932 return kUnboxedFloat32x4; | |
5933 } | |
5934 | 5670 |
5935 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5671 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5936 ASSERT(idx == 0); | 5672 ASSERT(idx == 0); |
5937 return kUnboxedFloat32x4; | 5673 return kUnboxedFloat32x4; |
5938 } | 5674 } |
5939 | 5675 |
5940 virtual intptr_t DeoptimizationTarget() const { | 5676 virtual intptr_t DeoptimizationTarget() const { |
5941 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5677 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5942 // was inherited from another instruction that could deoptimize. | 5678 // was inherited from another instruction that could deoptimize. |
5943 return GetDeoptId(); | 5679 return GetDeoptId(); |
(...skipping 26 matching lines...) Expand all Loading... |
5970 SetInputAt(1, lower); | 5706 SetInputAt(1, lower); |
5971 SetInputAt(2, upper); | 5707 SetInputAt(2, upper); |
5972 } | 5708 } |
5973 | 5709 |
5974 Value* left() const { return inputs_[0]; } | 5710 Value* left() const { return inputs_[0]; } |
5975 Value* lower() const { return inputs_[1]; } | 5711 Value* lower() const { return inputs_[1]; } |
5976 Value* upper() const { return inputs_[2]; } | 5712 Value* upper() const { return inputs_[2]; } |
5977 | 5713 |
5978 virtual bool CanDeoptimize() const { return false; } | 5714 virtual bool CanDeoptimize() const { return false; } |
5979 | 5715 |
5980 virtual Representation representation() const { | 5716 virtual Representation representation() const { return kUnboxedFloat32x4; } |
5981 return kUnboxedFloat32x4; | |
5982 } | |
5983 | 5717 |
5984 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5718 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
5985 ASSERT((idx == 0) || (idx == 1) || (idx == 2)); | 5719 ASSERT((idx == 0) || (idx == 1) || (idx == 2)); |
5986 return kUnboxedFloat32x4; | 5720 return kUnboxedFloat32x4; |
5987 } | 5721 } |
5988 | 5722 |
5989 virtual intptr_t DeoptimizationTarget() const { | 5723 virtual intptr_t DeoptimizationTarget() const { |
5990 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5724 // Direct access since this instruction cannot deoptimize, and the deopt-id |
5991 // was inherited from another instruction that could deoptimize. | 5725 // was inherited from another instruction that could deoptimize. |
5992 return GetDeoptId(); | 5726 return GetDeoptId(); |
(...skipping 10 matching lines...) Expand all Loading... |
6003 DISALLOW_COPY_AND_ASSIGN(Float32x4ClampInstr); | 5737 DISALLOW_COPY_AND_ASSIGN(Float32x4ClampInstr); |
6004 }; | 5738 }; |
6005 | 5739 |
6006 | 5740 |
6007 class Float32x4WithInstr : public TemplateDefinition<2, NoThrow, Pure> { | 5741 class Float32x4WithInstr : public TemplateDefinition<2, NoThrow, Pure> { |
6008 public: | 5742 public: |
6009 Float32x4WithInstr(MethodRecognizer::Kind op_kind, | 5743 Float32x4WithInstr(MethodRecognizer::Kind op_kind, |
6010 Value* left, | 5744 Value* left, |
6011 Value* replacement, | 5745 Value* replacement, |
6012 intptr_t deopt_id) | 5746 intptr_t deopt_id) |
6013 : TemplateDefinition(deopt_id), | 5747 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
6014 op_kind_(op_kind) { | |
6015 SetInputAt(0, replacement); | 5748 SetInputAt(0, replacement); |
6016 SetInputAt(1, left); | 5749 SetInputAt(1, left); |
6017 } | 5750 } |
6018 | 5751 |
6019 Value* left() const { return inputs_[1]; } | 5752 Value* left() const { return inputs_[1]; } |
6020 Value* replacement() const { return inputs_[0]; } | 5753 Value* replacement() const { return inputs_[0]; } |
6021 | 5754 |
6022 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 5755 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
6023 | 5756 |
6024 virtual bool CanDeoptimize() const { return false; } | 5757 virtual bool CanDeoptimize() const { return false; } |
6025 | 5758 |
6026 virtual Representation representation() const { | 5759 virtual Representation representation() const { return kUnboxedFloat32x4; } |
6027 return kUnboxedFloat32x4; | |
6028 } | |
6029 | 5760 |
6030 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5761 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6031 ASSERT((idx == 0) || (idx == 1)); | 5762 ASSERT((idx == 0) || (idx == 1)); |
6032 if (idx == 0) { | 5763 if (idx == 0) { |
6033 return kUnboxedDouble; | 5764 return kUnboxedDouble; |
6034 } | 5765 } |
6035 return kUnboxedFloat32x4; | 5766 return kUnboxedFloat32x4; |
6036 } | 5767 } |
6037 | 5768 |
6038 virtual intptr_t DeoptimizationTarget() const { | 5769 virtual intptr_t DeoptimizationTarget() const { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6122 public: | 5853 public: |
6123 Float32x4ToInt32x4Instr(Value* left, intptr_t deopt_id) | 5854 Float32x4ToInt32x4Instr(Value* left, intptr_t deopt_id) |
6124 : TemplateDefinition(deopt_id) { | 5855 : TemplateDefinition(deopt_id) { |
6125 SetInputAt(0, left); | 5856 SetInputAt(0, left); |
6126 } | 5857 } |
6127 | 5858 |
6128 Value* left() const { return inputs_[0]; } | 5859 Value* left() const { return inputs_[0]; } |
6129 | 5860 |
6130 virtual bool CanDeoptimize() const { return false; } | 5861 virtual bool CanDeoptimize() const { return false; } |
6131 | 5862 |
6132 virtual Representation representation() const { | 5863 virtual Representation representation() const { return kUnboxedInt32x4; } |
6133 return kUnboxedInt32x4; | |
6134 } | |
6135 | 5864 |
6136 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5865 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6137 ASSERT(idx == 0); | 5866 ASSERT(idx == 0); |
6138 return kUnboxedFloat32x4; | 5867 return kUnboxedFloat32x4; |
6139 } | 5868 } |
6140 | 5869 |
6141 virtual intptr_t DeoptimizationTarget() const { | 5870 virtual intptr_t DeoptimizationTarget() const { |
6142 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5871 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6143 // was inherited from another instruction that could deoptimize. | 5872 // was inherited from another instruction that could deoptimize. |
6144 return GetDeoptId(); | 5873 return GetDeoptId(); |
(...skipping 15 matching lines...) Expand all Loading... |
6160 public: | 5889 public: |
6161 Float32x4ToFloat64x2Instr(Value* left, intptr_t deopt_id) | 5890 Float32x4ToFloat64x2Instr(Value* left, intptr_t deopt_id) |
6162 : TemplateDefinition(deopt_id) { | 5891 : TemplateDefinition(deopt_id) { |
6163 SetInputAt(0, left); | 5892 SetInputAt(0, left); |
6164 } | 5893 } |
6165 | 5894 |
6166 Value* left() const { return inputs_[0]; } | 5895 Value* left() const { return inputs_[0]; } |
6167 | 5896 |
6168 virtual bool CanDeoptimize() const { return false; } | 5897 virtual bool CanDeoptimize() const { return false; } |
6169 | 5898 |
6170 virtual Representation representation() const { | 5899 virtual Representation representation() const { return kUnboxedFloat64x2; } |
6171 return kUnboxedFloat64x2; | |
6172 } | |
6173 | 5900 |
6174 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5901 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6175 ASSERT(idx == 0); | 5902 ASSERT(idx == 0); |
6176 return kUnboxedFloat32x4; | 5903 return kUnboxedFloat32x4; |
6177 } | 5904 } |
6178 | 5905 |
6179 virtual intptr_t DeoptimizationTarget() const { | 5906 virtual intptr_t DeoptimizationTarget() const { |
6180 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5907 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6181 // was inherited from another instruction that could deoptimize. | 5908 // was inherited from another instruction that could deoptimize. |
6182 return GetDeoptId(); | 5909 return GetDeoptId(); |
(...skipping 15 matching lines...) Expand all Loading... |
6198 public: | 5925 public: |
6199 Float64x2ToFloat32x4Instr(Value* left, intptr_t deopt_id) | 5926 Float64x2ToFloat32x4Instr(Value* left, intptr_t deopt_id) |
6200 : TemplateDefinition(deopt_id) { | 5927 : TemplateDefinition(deopt_id) { |
6201 SetInputAt(0, left); | 5928 SetInputAt(0, left); |
6202 } | 5929 } |
6203 | 5930 |
6204 Value* left() const { return inputs_[0]; } | 5931 Value* left() const { return inputs_[0]; } |
6205 | 5932 |
6206 virtual bool CanDeoptimize() const { return false; } | 5933 virtual bool CanDeoptimize() const { return false; } |
6207 | 5934 |
6208 virtual Representation representation() const { | 5935 virtual Representation representation() const { return kUnboxedFloat32x4; } |
6209 return kUnboxedFloat32x4; | |
6210 } | |
6211 | 5936 |
6212 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5937 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6213 ASSERT(idx == 0); | 5938 ASSERT(idx == 0); |
6214 return kUnboxedFloat64x2; | 5939 return kUnboxedFloat64x2; |
6215 } | 5940 } |
6216 | 5941 |
6217 virtual intptr_t DeoptimizationTarget() const { | 5942 virtual intptr_t DeoptimizationTarget() const { |
6218 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5943 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6219 // was inherited from another instruction that could deoptimize. | 5944 // was inherited from another instruction that could deoptimize. |
6220 return GetDeoptId(); | 5945 return GetDeoptId(); |
(...skipping 17 matching lines...) Expand all Loading... |
6238 : TemplateDefinition(deopt_id) { | 5963 : TemplateDefinition(deopt_id) { |
6239 SetInputAt(0, value0); | 5964 SetInputAt(0, value0); |
6240 SetInputAt(1, value1); | 5965 SetInputAt(1, value1); |
6241 } | 5966 } |
6242 | 5967 |
6243 Value* value0() const { return inputs_[0]; } | 5968 Value* value0() const { return inputs_[0]; } |
6244 Value* value1() const { return inputs_[1]; } | 5969 Value* value1() const { return inputs_[1]; } |
6245 | 5970 |
6246 virtual bool CanDeoptimize() const { return false; } | 5971 virtual bool CanDeoptimize() const { return false; } |
6247 | 5972 |
6248 virtual Representation representation() const { | 5973 virtual Representation representation() const { return kUnboxedFloat64x2; } |
6249 return kUnboxedFloat64x2; | |
6250 } | |
6251 | 5974 |
6252 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 5975 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6253 ASSERT(idx >= 0 && idx < 2); | 5976 ASSERT(idx >= 0 && idx < 2); |
6254 return kUnboxedDouble; | 5977 return kUnboxedDouble; |
6255 } | 5978 } |
6256 | 5979 |
6257 virtual intptr_t DeoptimizationTarget() const { | 5980 virtual intptr_t DeoptimizationTarget() const { |
6258 // Direct access since this instruction cannot deoptimize, and the deopt-id | 5981 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6259 // was inherited from another instruction that could deoptimize. | 5982 // was inherited from another instruction that could deoptimize. |
6260 return GetDeoptId(); | 5983 return GetDeoptId(); |
(...skipping 15 matching lines...) Expand all Loading... |
6276 public: | 5999 public: |
6277 Float64x2SplatInstr(Value* value, intptr_t deopt_id) | 6000 Float64x2SplatInstr(Value* value, intptr_t deopt_id) |
6278 : TemplateDefinition(deopt_id) { | 6001 : TemplateDefinition(deopt_id) { |
6279 SetInputAt(0, value); | 6002 SetInputAt(0, value); |
6280 } | 6003 } |
6281 | 6004 |
6282 Value* value() const { return inputs_[0]; } | 6005 Value* value() const { return inputs_[0]; } |
6283 | 6006 |
6284 virtual bool CanDeoptimize() const { return false; } | 6007 virtual bool CanDeoptimize() const { return false; } |
6285 | 6008 |
6286 virtual Representation representation() const { | 6009 virtual Representation representation() const { return kUnboxedFloat64x2; } |
6287 return kUnboxedFloat64x2; | |
6288 } | |
6289 | 6010 |
6290 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6011 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6291 ASSERT(idx == 0); | 6012 ASSERT(idx == 0); |
6292 return kUnboxedDouble; | 6013 return kUnboxedDouble; |
6293 } | 6014 } |
6294 | 6015 |
6295 virtual intptr_t DeoptimizationTarget() const { | 6016 virtual intptr_t DeoptimizationTarget() const { |
6296 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6017 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6297 // was inherited from another instruction that could deoptimize. | 6018 // was inherited from another instruction that could deoptimize. |
6298 return GetDeoptId(); | 6019 return GetDeoptId(); |
6299 } | 6020 } |
6300 | 6021 |
6301 DECLARE_INSTRUCTION(Float64x2Splat) | 6022 DECLARE_INSTRUCTION(Float64x2Splat) |
6302 virtual CompileType ComputeType() const; | 6023 virtual CompileType ComputeType() const; |
6303 | 6024 |
6304 virtual bool AttributesEqual(Instruction* other) const { return true; } | 6025 virtual bool AttributesEqual(Instruction* other) const { return true; } |
6305 | 6026 |
6306 PRINT_OPERANDS_TO_SUPPORT | 6027 PRINT_OPERANDS_TO_SUPPORT |
6307 | 6028 |
6308 private: | 6029 private: |
6309 DISALLOW_COPY_AND_ASSIGN(Float64x2SplatInstr); | 6030 DISALLOW_COPY_AND_ASSIGN(Float64x2SplatInstr); |
6310 }; | 6031 }; |
6311 | 6032 |
6312 | 6033 |
6313 class Float64x2ZeroInstr : public TemplateDefinition<0, NoThrow, Pure> { | 6034 class Float64x2ZeroInstr : public TemplateDefinition<0, NoThrow, Pure> { |
6314 public: | 6035 public: |
6315 Float64x2ZeroInstr() { } | 6036 Float64x2ZeroInstr() {} |
6316 | 6037 |
6317 virtual bool CanDeoptimize() const { return false; } | 6038 virtual bool CanDeoptimize() const { return false; } |
6318 | 6039 |
6319 virtual Representation representation() const { | 6040 virtual Representation representation() const { return kUnboxedFloat64x2; } |
6320 return kUnboxedFloat64x2; | |
6321 } | |
6322 | 6041 |
6323 DECLARE_INSTRUCTION(Float64x2Zero) | 6042 DECLARE_INSTRUCTION(Float64x2Zero) |
6324 virtual CompileType ComputeType() const; | 6043 virtual CompileType ComputeType() const; |
6325 | 6044 |
6326 virtual bool AttributesEqual(Instruction* other) const { return true; } | 6045 virtual bool AttributesEqual(Instruction* other) const { return true; } |
6327 | 6046 |
6328 private: | 6047 private: |
6329 DISALLOW_COPY_AND_ASSIGN(Float64x2ZeroInstr); | 6048 DISALLOW_COPY_AND_ASSIGN(Float64x2ZeroInstr); |
6330 }; | 6049 }; |
6331 | 6050 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6392 SetInputAt(1, right); | 6111 SetInputAt(1, right); |
6393 } | 6112 } |
6394 | 6113 |
6395 Value* left() const { return inputs_[0]; } | 6114 Value* left() const { return inputs_[0]; } |
6396 Value* right() const { return inputs_[1]; } | 6115 Value* right() const { return inputs_[1]; } |
6397 | 6116 |
6398 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 6117 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
6399 | 6118 |
6400 virtual bool CanDeoptimize() const { return false; } | 6119 virtual bool CanDeoptimize() const { return false; } |
6401 | 6120 |
6402 virtual Representation representation() const { | 6121 virtual Representation representation() const { return kUnboxedFloat64x2; } |
6403 return kUnboxedFloat64x2; | |
6404 } | |
6405 | 6122 |
6406 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6123 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6407 if (idx == 0) { | 6124 if (idx == 0) { |
6408 return kUnboxedFloat64x2; | 6125 return kUnboxedFloat64x2; |
6409 } | 6126 } |
6410 ASSERT(idx == 1); | 6127 ASSERT(idx == 1); |
6411 if ((op_kind() == MethodRecognizer::kFloat64x2WithX) || | 6128 if ((op_kind() == MethodRecognizer::kFloat64x2WithX) || |
6412 (op_kind() == MethodRecognizer::kFloat64x2WithY) || | 6129 (op_kind() == MethodRecognizer::kFloat64x2WithY) || |
6413 (op_kind() == MethodRecognizer::kFloat64x2Scale)) { | 6130 (op_kind() == MethodRecognizer::kFloat64x2Scale)) { |
6414 return kUnboxedDouble; | 6131 return kUnboxedDouble; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6452 SetInputAt(3, value3); | 6169 SetInputAt(3, value3); |
6453 } | 6170 } |
6454 | 6171 |
6455 Value* value0() const { return inputs_[0]; } | 6172 Value* value0() const { return inputs_[0]; } |
6456 Value* value1() const { return inputs_[1]; } | 6173 Value* value1() const { return inputs_[1]; } |
6457 Value* value2() const { return inputs_[2]; } | 6174 Value* value2() const { return inputs_[2]; } |
6458 Value* value3() const { return inputs_[3]; } | 6175 Value* value3() const { return inputs_[3]; } |
6459 | 6176 |
6460 virtual bool CanDeoptimize() const { return false; } | 6177 virtual bool CanDeoptimize() const { return false; } |
6461 | 6178 |
6462 virtual Representation representation() const { | 6179 virtual Representation representation() const { return kUnboxedInt32x4; } |
6463 return kUnboxedInt32x4; | |
6464 } | |
6465 | 6180 |
6466 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6181 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6467 ASSERT((idx >= 0) && (idx < 4)); | 6182 ASSERT((idx >= 0) && (idx < 4)); |
6468 return kUnboxedInt32; | 6183 return kUnboxedInt32; |
6469 } | 6184 } |
6470 | 6185 |
6471 virtual intptr_t DeoptimizationTarget() const { | 6186 virtual intptr_t DeoptimizationTarget() const { |
6472 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6187 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6473 // was inherited from another instruction that could deoptimize. | 6188 // was inherited from another instruction that could deoptimize. |
6474 return GetDeoptId(); | 6189 return GetDeoptId(); |
(...skipping 26 matching lines...) Expand all Loading... |
6501 SetInputAt(3, value3); | 6216 SetInputAt(3, value3); |
6502 } | 6217 } |
6503 | 6218 |
6504 Value* value0() const { return inputs_[0]; } | 6219 Value* value0() const { return inputs_[0]; } |
6505 Value* value1() const { return inputs_[1]; } | 6220 Value* value1() const { return inputs_[1]; } |
6506 Value* value2() const { return inputs_[2]; } | 6221 Value* value2() const { return inputs_[2]; } |
6507 Value* value3() const { return inputs_[3]; } | 6222 Value* value3() const { return inputs_[3]; } |
6508 | 6223 |
6509 virtual bool CanDeoptimize() const { return false; } | 6224 virtual bool CanDeoptimize() const { return false; } |
6510 | 6225 |
6511 virtual Representation representation() const { | 6226 virtual Representation representation() const { return kUnboxedInt32x4; } |
6512 return kUnboxedInt32x4; | |
6513 } | |
6514 | 6227 |
6515 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6228 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6516 ASSERT((idx >= 0) && (idx < 4)); | 6229 ASSERT((idx >= 0) && (idx < 4)); |
6517 return kTagged; | 6230 return kTagged; |
6518 } | 6231 } |
6519 | 6232 |
6520 virtual intptr_t DeoptimizationTarget() const { | 6233 virtual intptr_t DeoptimizationTarget() const { |
6521 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6234 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6522 // was inherited from another instruction that could deoptimize. | 6235 // was inherited from another instruction that could deoptimize. |
6523 return GetDeoptId(); | 6236 return GetDeoptId(); |
(...skipping 19 matching lines...) Expand all Loading... |
6543 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 6256 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
6544 SetInputAt(0, value); | 6257 SetInputAt(0, value); |
6545 } | 6258 } |
6546 | 6259 |
6547 Value* value() const { return inputs_[0]; } | 6260 Value* value() const { return inputs_[0]; } |
6548 | 6261 |
6549 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 6262 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
6550 | 6263 |
6551 virtual bool CanDeoptimize() const { return false; } | 6264 virtual bool CanDeoptimize() const { return false; } |
6552 | 6265 |
6553 virtual Representation representation() const { | 6266 virtual Representation representation() const { return kTagged; } |
6554 return kTagged; | |
6555 } | |
6556 | 6267 |
6557 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6268 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6558 ASSERT(idx == 0); | 6269 ASSERT(idx == 0); |
6559 return kUnboxedInt32x4; | 6270 return kUnboxedInt32x4; |
6560 } | 6271 } |
6561 | 6272 |
6562 virtual intptr_t DeoptimizationTarget() const { | 6273 virtual intptr_t DeoptimizationTarget() const { |
6563 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6274 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6564 // was inherited from another instruction that could deoptimize. | 6275 // was inherited from another instruction that could deoptimize. |
6565 return GetDeoptId(); | 6276 return GetDeoptId(); |
(...skipping 23 matching lines...) Expand all Loading... |
6589 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 6300 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
6590 SetInputAt(0, value); | 6301 SetInputAt(0, value); |
6591 } | 6302 } |
6592 | 6303 |
6593 Value* value() const { return inputs_[0]; } | 6304 Value* value() const { return inputs_[0]; } |
6594 | 6305 |
6595 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 6306 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
6596 | 6307 |
6597 virtual bool CanDeoptimize() const { return false; } | 6308 virtual bool CanDeoptimize() const { return false; } |
6598 | 6309 |
6599 virtual Representation representation() const { | 6310 virtual Representation representation() const { return kTagged; } |
6600 return kTagged; | |
6601 } | |
6602 | 6311 |
6603 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6312 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6604 ASSERT(idx == 0); | 6313 ASSERT(idx == 0); |
6605 if (op_kind_ == MethodRecognizer::kFloat32x4GetSignMask) { | 6314 if (op_kind_ == MethodRecognizer::kFloat32x4GetSignMask) { |
6606 return kUnboxedFloat32x4; | 6315 return kUnboxedFloat32x4; |
6607 } | 6316 } |
6608 ASSERT(op_kind_ == MethodRecognizer::kInt32x4GetSignMask); | 6317 ASSERT(op_kind_ == MethodRecognizer::kInt32x4GetSignMask); |
6609 return kUnboxedInt32x4; | 6318 return kUnboxedInt32x4; |
6610 } | 6319 } |
6611 | 6320 |
(...skipping 30 matching lines...) Expand all Loading... |
6642 SetInputAt(1, trueValue); | 6351 SetInputAt(1, trueValue); |
6643 SetInputAt(2, falseValue); | 6352 SetInputAt(2, falseValue); |
6644 } | 6353 } |
6645 | 6354 |
6646 Value* mask() const { return inputs_[0]; } | 6355 Value* mask() const { return inputs_[0]; } |
6647 Value* trueValue() const { return inputs_[1]; } | 6356 Value* trueValue() const { return inputs_[1]; } |
6648 Value* falseValue() const { return inputs_[2]; } | 6357 Value* falseValue() const { return inputs_[2]; } |
6649 | 6358 |
6650 virtual bool CanDeoptimize() const { return false; } | 6359 virtual bool CanDeoptimize() const { return false; } |
6651 | 6360 |
6652 virtual Representation representation() const { | 6361 virtual Representation representation() const { return kUnboxedFloat32x4; } |
6653 return kUnboxedFloat32x4; | |
6654 } | |
6655 | 6362 |
6656 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6363 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6657 ASSERT((idx == 0) || (idx == 1) || (idx == 2)); | 6364 ASSERT((idx == 0) || (idx == 1) || (idx == 2)); |
6658 if (idx == 0) { | 6365 if (idx == 0) { |
6659 return kUnboxedInt32x4; | 6366 return kUnboxedInt32x4; |
6660 } | 6367 } |
6661 return kUnboxedFloat32x4; | 6368 return kUnboxedFloat32x4; |
6662 } | 6369 } |
6663 | 6370 |
6664 virtual intptr_t DeoptimizationTarget() const { | 6371 virtual intptr_t DeoptimizationTarget() const { |
(...skipping 25 matching lines...) Expand all Loading... |
6690 SetInputAt(1, flagValue); | 6397 SetInputAt(1, flagValue); |
6691 } | 6398 } |
6692 | 6399 |
6693 Value* value() const { return inputs_[0]; } | 6400 Value* value() const { return inputs_[0]; } |
6694 Value* flagValue() const { return inputs_[1]; } | 6401 Value* flagValue() const { return inputs_[1]; } |
6695 | 6402 |
6696 MethodRecognizer::Kind op_kind() const { return op_kind_; } | 6403 MethodRecognizer::Kind op_kind() const { return op_kind_; } |
6697 | 6404 |
6698 virtual bool CanDeoptimize() const { return false; } | 6405 virtual bool CanDeoptimize() const { return false; } |
6699 | 6406 |
6700 virtual Representation representation() const { | 6407 virtual Representation representation() const { return kUnboxedInt32x4; } |
6701 return kUnboxedInt32x4; | |
6702 } | |
6703 | 6408 |
6704 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6409 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6705 ASSERT((idx == 0) || (idx == 1)); | 6410 ASSERT((idx == 0) || (idx == 1)); |
6706 if (idx == 1) { | 6411 if (idx == 1) { |
6707 return kTagged; | 6412 return kTagged; |
6708 } | 6413 } |
6709 return kUnboxedInt32x4; | 6414 return kUnboxedInt32x4; |
6710 } | 6415 } |
6711 | 6416 |
6712 virtual intptr_t DeoptimizationTarget() const { | 6417 virtual intptr_t DeoptimizationTarget() const { |
(...skipping 22 matching lines...) Expand all Loading... |
6735 public: | 6440 public: |
6736 Int32x4ToFloat32x4Instr(Value* left, intptr_t deopt_id) | 6441 Int32x4ToFloat32x4Instr(Value* left, intptr_t deopt_id) |
6737 : TemplateDefinition(deopt_id) { | 6442 : TemplateDefinition(deopt_id) { |
6738 SetInputAt(0, left); | 6443 SetInputAt(0, left); |
6739 } | 6444 } |
6740 | 6445 |
6741 Value* left() const { return inputs_[0]; } | 6446 Value* left() const { return inputs_[0]; } |
6742 | 6447 |
6743 virtual bool CanDeoptimize() const { return false; } | 6448 virtual bool CanDeoptimize() const { return false; } |
6744 | 6449 |
6745 virtual Representation representation() const { | 6450 virtual Representation representation() const { return kUnboxedFloat32x4; } |
6746 return kUnboxedFloat32x4; | |
6747 } | |
6748 | 6451 |
6749 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6452 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6750 ASSERT(idx == 0); | 6453 ASSERT(idx == 0); |
6751 return kUnboxedInt32x4; | 6454 return kUnboxedInt32x4; |
6752 } | 6455 } |
6753 | 6456 |
6754 virtual intptr_t DeoptimizationTarget() const { | 6457 virtual intptr_t DeoptimizationTarget() const { |
6755 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6458 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6756 // was inherited from another instruction that could deoptimize. | 6459 // was inherited from another instruction that could deoptimize. |
6757 return GetDeoptId(); | 6460 return GetDeoptId(); |
6758 } | 6461 } |
6759 | 6462 |
6760 DECLARE_INSTRUCTION(Int32x4ToFloat32x4) | 6463 DECLARE_INSTRUCTION(Int32x4ToFloat32x4) |
6761 virtual CompileType ComputeType() const; | 6464 virtual CompileType ComputeType() const; |
6762 | 6465 |
6763 virtual bool AttributesEqual(Instruction* other) const { return true; } | 6466 virtual bool AttributesEqual(Instruction* other) const { return true; } |
6764 | 6467 |
6765 PRINT_OPERANDS_TO_SUPPORT | 6468 PRINT_OPERANDS_TO_SUPPORT |
6766 | 6469 |
6767 private: | 6470 private: |
6768 DISALLOW_COPY_AND_ASSIGN(Int32x4ToFloat32x4Instr); | 6471 DISALLOW_COPY_AND_ASSIGN(Int32x4ToFloat32x4Instr); |
6769 }; | 6472 }; |
6770 | 6473 |
6771 | 6474 |
6772 class BinaryInt32x4OpInstr : public TemplateDefinition<2, NoThrow, Pure> { | 6475 class BinaryInt32x4OpInstr : public TemplateDefinition<2, NoThrow, Pure> { |
6773 public: | 6476 public: |
6774 BinaryInt32x4OpInstr(Token::Kind op_kind, | 6477 BinaryInt32x4OpInstr(Token::Kind op_kind, |
6775 Value* left, | 6478 Value* left, |
6776 Value* right, | 6479 Value* right, |
6777 intptr_t deopt_id) | 6480 intptr_t deopt_id) |
6778 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 6481 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
6779 SetInputAt(0, left); | 6482 SetInputAt(0, left); |
6780 SetInputAt(1, right); | 6483 SetInputAt(1, right); |
6781 } | 6484 } |
6782 | 6485 |
6783 Value* left() const { return inputs_[0]; } | 6486 Value* left() const { return inputs_[0]; } |
6784 Value* right() const { return inputs_[1]; } | 6487 Value* right() const { return inputs_[1]; } |
6785 | 6488 |
6786 Token::Kind op_kind() const { return op_kind_; } | 6489 Token::Kind op_kind() const { return op_kind_; } |
6787 | 6490 |
6788 virtual bool CanDeoptimize() const { return false; } | 6491 virtual bool CanDeoptimize() const { return false; } |
6789 | 6492 |
6790 virtual Representation representation() const { | 6493 virtual Representation representation() const { return kUnboxedInt32x4; } |
6791 return kUnboxedInt32x4; | |
6792 } | |
6793 | 6494 |
6794 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6495 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6795 ASSERT((idx == 0) || (idx == 1)); | 6496 ASSERT((idx == 0) || (idx == 1)); |
6796 return kUnboxedInt32x4; | 6497 return kUnboxedInt32x4; |
6797 } | 6498 } |
6798 | 6499 |
6799 virtual intptr_t DeoptimizationTarget() const { | 6500 virtual intptr_t DeoptimizationTarget() const { |
6800 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6501 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6801 // was inherited from another instruction that could deoptimize. | 6502 // was inherited from another instruction that could deoptimize. |
6802 return GetDeoptId(); | 6503 return GetDeoptId(); |
(...skipping 26 matching lines...) Expand all Loading... |
6829 SetInputAt(1, right); | 6530 SetInputAt(1, right); |
6830 } | 6531 } |
6831 | 6532 |
6832 Value* left() const { return inputs_[0]; } | 6533 Value* left() const { return inputs_[0]; } |
6833 Value* right() const { return inputs_[1]; } | 6534 Value* right() const { return inputs_[1]; } |
6834 | 6535 |
6835 Token::Kind op_kind() const { return op_kind_; } | 6536 Token::Kind op_kind() const { return op_kind_; } |
6836 | 6537 |
6837 virtual bool CanDeoptimize() const { return false; } | 6538 virtual bool CanDeoptimize() const { return false; } |
6838 | 6539 |
6839 virtual Representation representation() const { | 6540 virtual Representation representation() const { return kUnboxedFloat64x2; } |
6840 return kUnboxedFloat64x2; | |
6841 } | |
6842 | 6541 |
6843 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6542 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6844 ASSERT((idx == 0) || (idx == 1)); | 6543 ASSERT((idx == 0) || (idx == 1)); |
6845 return kUnboxedFloat64x2; | 6544 return kUnboxedFloat64x2; |
6846 } | 6545 } |
6847 | 6546 |
6848 virtual intptr_t DeoptimizationTarget() const { | 6547 virtual intptr_t DeoptimizationTarget() const { |
6849 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6548 // Direct access since this instruction cannot deoptimize, and the deopt-id |
6850 // was inherited from another instruction that could deoptimize. | 6549 // was inherited from another instruction that could deoptimize. |
6851 return GetDeoptId(); | 6550 return GetDeoptId(); |
(...skipping 10 matching lines...) Expand all Loading... |
6862 | 6561 |
6863 private: | 6562 private: |
6864 const Token::Kind op_kind_; | 6563 const Token::Kind op_kind_; |
6865 | 6564 |
6866 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); | 6565 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); |
6867 }; | 6566 }; |
6868 | 6567 |
6869 | 6568 |
6870 class UnaryIntegerOpInstr : public TemplateDefinition<1, NoThrow, Pure> { | 6569 class UnaryIntegerOpInstr : public TemplateDefinition<1, NoThrow, Pure> { |
6871 public: | 6570 public: |
6872 UnaryIntegerOpInstr(Token::Kind op_kind, | 6571 UnaryIntegerOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) |
6873 Value* value, | |
6874 intptr_t deopt_id) | |
6875 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 6572 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
6876 ASSERT((op_kind == Token::kNEGATE) || | 6573 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); |
6877 (op_kind == Token::kBIT_NOT)); | |
6878 SetInputAt(0, value); | 6574 SetInputAt(0, value); |
6879 } | 6575 } |
6880 | 6576 |
6881 static UnaryIntegerOpInstr* Make(Representation representation, | 6577 static UnaryIntegerOpInstr* Make(Representation representation, |
6882 Token::Kind op_kind, | 6578 Token::Kind op_kind, |
6883 Value* value, | 6579 Value* value, |
6884 intptr_t deopt_id, | 6580 intptr_t deopt_id, |
6885 Range* range); | 6581 Range* range); |
6886 | 6582 |
6887 Value* value() const { return inputs_[0]; } | 6583 Value* value() const { return inputs_[0]; } |
(...skipping 16 matching lines...) Expand all Loading... |
6904 DEFINE_INSTRUCTION_TYPE_CHECK(UnaryIntegerOp) | 6600 DEFINE_INSTRUCTION_TYPE_CHECK(UnaryIntegerOp) |
6905 | 6601 |
6906 private: | 6602 private: |
6907 const Token::Kind op_kind_; | 6603 const Token::Kind op_kind_; |
6908 }; | 6604 }; |
6909 | 6605 |
6910 | 6606 |
6911 // Handles both Smi operations: BIT_OR and NEGATE. | 6607 // Handles both Smi operations: BIT_OR and NEGATE. |
6912 class UnarySmiOpInstr : public UnaryIntegerOpInstr { | 6608 class UnarySmiOpInstr : public UnaryIntegerOpInstr { |
6913 public: | 6609 public: |
6914 UnarySmiOpInstr(Token::Kind op_kind, | 6610 UnarySmiOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) |
6915 Value* value, | |
6916 intptr_t deopt_id) | |
6917 : UnaryIntegerOpInstr(op_kind, value, deopt_id) {} | 6611 : UnaryIntegerOpInstr(op_kind, value, deopt_id) {} |
6918 | 6612 |
6919 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } | 6613 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } |
6920 | 6614 |
6921 virtual CompileType ComputeType() const; | 6615 virtual CompileType ComputeType() const; |
6922 | 6616 |
6923 DECLARE_INSTRUCTION(UnarySmiOp) | 6617 DECLARE_INSTRUCTION(UnarySmiOp) |
6924 | 6618 |
6925 private: | 6619 private: |
6926 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); | 6620 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); |
6927 }; | 6621 }; |
6928 | 6622 |
6929 | 6623 |
6930 class UnaryUint32OpInstr : public UnaryIntegerOpInstr { | 6624 class UnaryUint32OpInstr : public UnaryIntegerOpInstr { |
6931 public: | 6625 public: |
6932 UnaryUint32OpInstr(Token::Kind op_kind, | 6626 UnaryUint32OpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) |
6933 Value* value, | |
6934 intptr_t deopt_id) | |
6935 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { | 6627 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { |
6936 ASSERT(op_kind == Token::kBIT_NOT); | 6628 ASSERT(op_kind == Token::kBIT_NOT); |
6937 } | 6629 } |
6938 | 6630 |
6939 virtual bool CanDeoptimize() const { return false; } | 6631 virtual bool CanDeoptimize() const { return false; } |
6940 | 6632 |
6941 virtual CompileType ComputeType() const; | 6633 virtual CompileType ComputeType() const; |
6942 | 6634 |
6943 virtual Representation representation() const { | 6635 virtual Representation representation() const { return kUnboxedUint32; } |
6944 return kUnboxedUint32; | |
6945 } | |
6946 | 6636 |
6947 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6637 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6948 ASSERT(idx == 0); | 6638 ASSERT(idx == 0); |
6949 return kUnboxedUint32; | 6639 return kUnboxedUint32; |
6950 } | 6640 } |
6951 | 6641 |
6952 DECLARE_INSTRUCTION(UnaryUint32Op) | 6642 DECLARE_INSTRUCTION(UnaryUint32Op) |
6953 | 6643 |
6954 private: | 6644 private: |
6955 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | 6645 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); |
6956 }; | 6646 }; |
6957 | 6647 |
6958 | 6648 |
6959 class UnaryMintOpInstr : public UnaryIntegerOpInstr { | 6649 class UnaryMintOpInstr : public UnaryIntegerOpInstr { |
6960 public: | 6650 public: |
6961 UnaryMintOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) | 6651 UnaryMintOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) |
6962 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { | 6652 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { |
6963 ASSERT(op_kind == Token::kBIT_NOT); | 6653 ASSERT(op_kind == Token::kBIT_NOT); |
6964 } | 6654 } |
6965 | 6655 |
6966 virtual bool CanDeoptimize() const { | 6656 virtual bool CanDeoptimize() const { return false; } |
6967 return false; | |
6968 } | |
6969 | 6657 |
6970 virtual CompileType ComputeType() const; | 6658 virtual CompileType ComputeType() const; |
6971 | 6659 |
6972 virtual Representation representation() const { | 6660 virtual Representation representation() const { return kUnboxedMint; } |
6973 return kUnboxedMint; | |
6974 } | |
6975 | 6661 |
6976 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6662 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
6977 ASSERT(idx == 0); | 6663 ASSERT(idx == 0); |
6978 return kUnboxedMint; | 6664 return kUnboxedMint; |
6979 } | 6665 } |
6980 | 6666 |
6981 DECLARE_INSTRUCTION(UnaryMintOp) | 6667 DECLARE_INSTRUCTION(UnaryMintOp) |
6982 | 6668 |
6983 private: | 6669 private: |
6984 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); | 6670 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); |
6985 }; | 6671 }; |
6986 | 6672 |
6987 | 6673 |
6988 class CheckedSmiOpInstr : public TemplateDefinition<2, Throws> { | 6674 class CheckedSmiOpInstr : public TemplateDefinition<2, Throws> { |
6989 public: | 6675 public: |
6990 CheckedSmiOpInstr(Token::Kind op_kind, | 6676 CheckedSmiOpInstr(Token::Kind op_kind, |
6991 Value* left, | 6677 Value* left, |
6992 Value* right, | 6678 Value* right, |
6993 InstanceCallInstr* call) | 6679 InstanceCallInstr* call) |
6994 : TemplateDefinition(call->deopt_id()), | 6680 : TemplateDefinition(call->deopt_id()), call_(call), op_kind_(op_kind) { |
6995 call_(call), | |
6996 op_kind_(op_kind) { | |
6997 SetInputAt(0, left); | 6681 SetInputAt(0, left); |
6998 SetInputAt(1, right); | 6682 SetInputAt(1, right); |
6999 } | 6683 } |
7000 | 6684 |
7001 InstanceCallInstr* call() const { return call_; } | 6685 InstanceCallInstr* call() const { return call_; } |
7002 Token::Kind op_kind() const { return op_kind_; } | 6686 Token::Kind op_kind() const { return op_kind_; } |
7003 Value* left() const { return inputs_[0]; } | 6687 Value* left() const { return inputs_[0]; } |
7004 Value* right() const { return inputs_[1]; } | 6688 Value* right() const { return inputs_[1]; } |
7005 | 6689 |
7006 virtual bool CanDeoptimize() const { return false; } | 6690 virtual bool CanDeoptimize() const { return false; } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7045 } | 6729 } |
7046 | 6730 |
7047 bool is_negated() const { return is_negated_; } | 6731 bool is_negated() const { return is_negated_; } |
7048 | 6732 |
7049 virtual EffectSet Effects() const { return EffectSet::All(); } | 6733 virtual EffectSet Effects() const { return EffectSet::All(); } |
7050 | 6734 |
7051 PRINT_OPERANDS_TO_SUPPORT | 6735 PRINT_OPERANDS_TO_SUPPORT |
7052 | 6736 |
7053 DECLARE_INSTRUCTION(CheckedSmiComparison) | 6737 DECLARE_INSTRUCTION(CheckedSmiComparison) |
7054 | 6738 |
7055 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 6739 virtual void EmitBranchCode(FlowGraphCompiler* compiler, BranchInstr* branch); |
7056 BranchInstr* branch); | |
7057 | 6740 |
7058 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, | 6741 virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
7059 BranchLabels labels); | 6742 BranchLabels labels); |
7060 | 6743 |
7061 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); | 6744 virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
7062 | 6745 |
7063 private: | 6746 private: |
7064 InstanceCallInstr* call_; | 6747 InstanceCallInstr* call_; |
7065 bool is_negated_; | 6748 bool is_negated_; |
7066 DISALLOW_COPY_AND_ASSIGN(CheckedSmiComparisonInstr); | 6749 DISALLOW_COPY_AND_ASSIGN(CheckedSmiComparisonInstr); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7157 bool is_truncating_; | 6840 bool is_truncating_; |
7158 }; | 6841 }; |
7159 | 6842 |
7160 | 6843 |
7161 class BinarySmiOpInstr : public BinaryIntegerOpInstr { | 6844 class BinarySmiOpInstr : public BinaryIntegerOpInstr { |
7162 public: | 6845 public: |
7163 BinarySmiOpInstr(Token::Kind op_kind, | 6846 BinarySmiOpInstr(Token::Kind op_kind, |
7164 Value* left, | 6847 Value* left, |
7165 Value* right, | 6848 Value* right, |
7166 intptr_t deopt_id) | 6849 intptr_t deopt_id) |
7167 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | 6850 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) {} |
7168 } | |
7169 | 6851 |
7170 virtual bool CanDeoptimize() const; | 6852 virtual bool CanDeoptimize() const; |
7171 | 6853 |
7172 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 6854 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
7173 virtual CompileType ComputeType() const; | 6855 virtual CompileType ComputeType() const; |
7174 | 6856 |
7175 DECLARE_INSTRUCTION(BinarySmiOp) | 6857 DECLARE_INSTRUCTION(BinarySmiOp) |
7176 | 6858 |
7177 private: | 6859 private: |
7178 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); | 6860 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); |
(...skipping 29 matching lines...) Expand all Loading... |
7208 default: | 6890 default: |
7209 return false; | 6891 return false; |
7210 } | 6892 } |
7211 #else | 6893 #else |
7212 return false; | 6894 return false; |
7213 #endif | 6895 #endif |
7214 } | 6896 } |
7215 | 6897 |
7216 virtual bool CanDeoptimize() const; | 6898 virtual bool CanDeoptimize() const; |
7217 | 6899 |
7218 virtual Representation representation() const { | 6900 virtual Representation representation() const { return kUnboxedInt32; } |
7219 return kUnboxedInt32; | |
7220 } | |
7221 | 6901 |
7222 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6902 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7223 ASSERT((idx == 0) || (idx == 1)); | 6903 ASSERT((idx == 0) || (idx == 1)); |
7224 return kUnboxedInt32; | 6904 return kUnboxedInt32; |
7225 } | 6905 } |
7226 | 6906 |
7227 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 6907 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
7228 virtual CompileType ComputeType() const; | 6908 virtual CompileType ComputeType() const; |
7229 | 6909 |
7230 DECLARE_INSTRUCTION(BinaryInt32Op) | 6910 DECLARE_INSTRUCTION(BinaryInt32Op) |
7231 | 6911 |
7232 private: | 6912 private: |
7233 DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr); | 6913 DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr); |
7234 }; | 6914 }; |
7235 | 6915 |
7236 | 6916 |
7237 class BinaryUint32OpInstr : public BinaryIntegerOpInstr { | 6917 class BinaryUint32OpInstr : public BinaryIntegerOpInstr { |
7238 public: | 6918 public: |
7239 BinaryUint32OpInstr(Token::Kind op_kind, | 6919 BinaryUint32OpInstr(Token::Kind op_kind, |
7240 Value* left, | 6920 Value* left, |
7241 Value* right, | 6921 Value* right, |
7242 intptr_t deopt_id) | 6922 intptr_t deopt_id) |
7243 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | 6923 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { |
7244 mark_truncating(); | 6924 mark_truncating(); |
7245 } | 6925 } |
7246 | 6926 |
7247 virtual bool CanDeoptimize() const { | 6927 virtual bool CanDeoptimize() const { return false; } |
7248 return false; | |
7249 } | |
7250 | 6928 |
7251 virtual Representation representation() const { | 6929 virtual Representation representation() const { return kUnboxedUint32; } |
7252 return kUnboxedUint32; | |
7253 } | |
7254 | 6930 |
7255 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6931 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7256 ASSERT((idx == 0) || (idx == 1)); | 6932 ASSERT((idx == 0) || (idx == 1)); |
7257 return kUnboxedUint32; | 6933 return kUnboxedUint32; |
7258 } | 6934 } |
7259 | 6935 |
7260 virtual CompileType ComputeType() const; | 6936 virtual CompileType ComputeType() const; |
7261 | 6937 |
7262 DECLARE_INSTRUCTION(BinaryUint32Op) | 6938 DECLARE_INSTRUCTION(BinaryUint32Op) |
7263 | 6939 |
7264 private: | 6940 private: |
7265 DISALLOW_COPY_AND_ASSIGN(BinaryUint32OpInstr); | 6941 DISALLOW_COPY_AND_ASSIGN(BinaryUint32OpInstr); |
7266 }; | 6942 }; |
7267 | 6943 |
7268 | 6944 |
7269 class ShiftUint32OpInstr : public BinaryIntegerOpInstr { | 6945 class ShiftUint32OpInstr : public BinaryIntegerOpInstr { |
7270 public: | 6946 public: |
7271 ShiftUint32OpInstr(Token::Kind op_kind, | 6947 ShiftUint32OpInstr(Token::Kind op_kind, |
7272 Value* left, | 6948 Value* left, |
7273 Value* right, | 6949 Value* right, |
7274 intptr_t deopt_id) | 6950 intptr_t deopt_id) |
7275 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | 6951 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { |
7276 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); | 6952 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); |
7277 } | 6953 } |
7278 | 6954 |
7279 virtual bool CanDeoptimize() const { return true; } | 6955 virtual bool CanDeoptimize() const { return true; } |
7280 | 6956 |
7281 virtual Representation representation() const { | 6957 virtual Representation representation() const { return kUnboxedUint32; } |
7282 return kUnboxedUint32; | |
7283 } | |
7284 | 6958 |
7285 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6959 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7286 ASSERT((idx == 0) || (idx == 1)); | 6960 ASSERT((idx == 0) || (idx == 1)); |
7287 return (idx == 0) ? kUnboxedUint32 : kTagged; | 6961 return (idx == 0) ? kUnboxedUint32 : kTagged; |
7288 } | 6962 } |
7289 | 6963 |
7290 virtual CompileType ComputeType() const; | 6964 virtual CompileType ComputeType() const; |
7291 | 6965 |
7292 DECLARE_INSTRUCTION(ShiftUint32Op) | 6966 DECLARE_INSTRUCTION(ShiftUint32Op) |
7293 | 6967 |
7294 private: | 6968 private: |
7295 DISALLOW_COPY_AND_ASSIGN(ShiftUint32OpInstr); | 6969 DISALLOW_COPY_AND_ASSIGN(ShiftUint32OpInstr); |
7296 }; | 6970 }; |
7297 | 6971 |
7298 | 6972 |
7299 class BinaryMintOpInstr : public BinaryIntegerOpInstr { | 6973 class BinaryMintOpInstr : public BinaryIntegerOpInstr { |
7300 public: | 6974 public: |
7301 BinaryMintOpInstr(Token::Kind op_kind, | 6975 BinaryMintOpInstr(Token::Kind op_kind, |
7302 Value* left, | 6976 Value* left, |
7303 Value* right, | 6977 Value* right, |
7304 intptr_t deopt_id) | 6978 intptr_t deopt_id) |
7305 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | 6979 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) {} |
| 6980 |
| 6981 virtual bool CanDeoptimize() const { |
| 6982 return (can_overflow() && |
| 6983 ((op_kind() == Token::kADD) || (op_kind() == Token::kSUB))) || |
| 6984 (op_kind() == Token::kMUL); // Deopt if inputs are not int32. |
7306 } | 6985 } |
7307 | 6986 |
7308 virtual bool CanDeoptimize() const { | 6987 virtual Representation representation() const { return kUnboxedMint; } |
7309 return (can_overflow() && ((op_kind() == Token::kADD) || | |
7310 (op_kind() == Token::kSUB))) | |
7311 || (op_kind() == Token::kMUL); // Deopt if inputs are not int32. | |
7312 } | |
7313 | |
7314 virtual Representation representation() const { | |
7315 return kUnboxedMint; | |
7316 } | |
7317 | 6988 |
7318 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6989 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7319 ASSERT((idx == 0) || (idx == 1)); | 6990 ASSERT((idx == 0) || (idx == 1)); |
7320 return kUnboxedMint; | 6991 return kUnboxedMint; |
7321 } | 6992 } |
7322 | 6993 |
7323 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 6994 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
7324 virtual CompileType ComputeType() const; | 6995 virtual CompileType ComputeType() const; |
7325 | 6996 |
7326 DECLARE_INSTRUCTION(BinaryMintOp) | 6997 DECLARE_INSTRUCTION(BinaryMintOp) |
7327 | 6998 |
7328 private: | 6999 private: |
7329 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); | 7000 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); |
7330 }; | 7001 }; |
7331 | 7002 |
7332 | 7003 |
7333 class ShiftMintOpInstr : public BinaryIntegerOpInstr { | 7004 class ShiftMintOpInstr : public BinaryIntegerOpInstr { |
7334 public: | 7005 public: |
7335 ShiftMintOpInstr(Token::Kind op_kind, | 7006 ShiftMintOpInstr(Token::Kind op_kind, |
7336 Value* left, | 7007 Value* left, |
7337 Value* right, | 7008 Value* right, |
7338 intptr_t deopt_id) | 7009 intptr_t deopt_id) |
7339 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | 7010 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { |
7340 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); | 7011 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); |
7341 } | 7012 } |
7342 | 7013 |
7343 virtual bool CanDeoptimize() const { | 7014 virtual bool CanDeoptimize() const { |
7344 return has_shift_count_check() | 7015 return has_shift_count_check() || |
7345 || (can_overflow() && (op_kind() == Token::kSHL)); | 7016 (can_overflow() && (op_kind() == Token::kSHL)); |
7346 } | 7017 } |
7347 | 7018 |
7348 virtual Representation representation() const { | 7019 virtual Representation representation() const { return kUnboxedMint; } |
7349 return kUnboxedMint; | |
7350 } | |
7351 | 7020 |
7352 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7021 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7353 ASSERT((idx == 0) || (idx == 1)); | 7022 ASSERT((idx == 0) || (idx == 1)); |
7354 return (idx == 0) ? kUnboxedMint : kTagged; | 7023 return (idx == 0) ? kUnboxedMint : kTagged; |
7355 } | 7024 } |
7356 | 7025 |
7357 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 7026 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
7358 virtual CompileType ComputeType() const; | 7027 virtual CompileType ComputeType() const; |
7359 | 7028 |
7360 DECLARE_INSTRUCTION(ShiftMintOp) | 7029 DECLARE_INSTRUCTION(ShiftMintOp) |
7361 | 7030 |
7362 private: | 7031 private: |
7363 bool has_shift_count_check() const; | 7032 bool has_shift_count_check() const; |
7364 | 7033 |
7365 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); | 7034 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); |
7366 }; | 7035 }; |
7367 | 7036 |
7368 | 7037 |
7369 // Handles only NEGATE. | 7038 // Handles only NEGATE. |
7370 class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> { | 7039 class UnaryDoubleOpInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7371 public: | 7040 public: |
7372 UnaryDoubleOpInstr(Token::Kind op_kind, | 7041 UnaryDoubleOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) |
7373 Value* value, | |
7374 intptr_t deopt_id) | |
7375 : TemplateDefinition(deopt_id), op_kind_(op_kind) { | 7042 : TemplateDefinition(deopt_id), op_kind_(op_kind) { |
7376 ASSERT(op_kind == Token::kNEGATE); | 7043 ASSERT(op_kind == Token::kNEGATE); |
7377 SetInputAt(0, value); | 7044 SetInputAt(0, value); |
7378 } | 7045 } |
7379 | 7046 |
7380 Value* value() const { return inputs_[0]; } | 7047 Value* value() const { return inputs_[0]; } |
7381 Token::Kind op_kind() const { return op_kind_; } | 7048 Token::Kind op_kind() const { return op_kind_; } |
7382 | 7049 |
7383 DECLARE_INSTRUCTION(UnaryDoubleOp) | 7050 DECLARE_INSTRUCTION(UnaryDoubleOp) |
7384 virtual CompileType ComputeType() const; | 7051 virtual CompileType ComputeType() const; |
7385 | 7052 |
7386 virtual bool CanDeoptimize() const { return false; } | 7053 virtual bool CanDeoptimize() const { return false; } |
7387 | 7054 |
7388 virtual intptr_t DeoptimizationTarget() const { | 7055 virtual intptr_t DeoptimizationTarget() const { |
7389 // Direct access since this instruction cannot deoptimize, and the deopt-id | 7056 // Direct access since this instruction cannot deoptimize, and the deopt-id |
7390 // was inherited from another instruction that could deoptimize. | 7057 // was inherited from another instruction that could deoptimize. |
7391 return GetDeoptId(); | 7058 return GetDeoptId(); |
7392 } | 7059 } |
7393 | 7060 |
7394 virtual Representation representation() const { | 7061 virtual Representation representation() const { return kUnboxedDouble; } |
7395 return kUnboxedDouble; | |
7396 } | |
7397 | 7062 |
7398 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7063 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7399 ASSERT(idx == 0); | 7064 ASSERT(idx == 0); |
7400 return kUnboxedDouble; | 7065 return kUnboxedDouble; |
7401 } | 7066 } |
7402 | 7067 |
7403 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7068 virtual bool AttributesEqual(Instruction* other) const { return true; } |
7404 | 7069 |
7405 PRINT_OPERANDS_TO_SUPPORT | 7070 PRINT_OPERANDS_TO_SUPPORT |
7406 | 7071 |
7407 private: | 7072 private: |
7408 const Token::Kind op_kind_; | 7073 const Token::Kind op_kind_; |
7409 | 7074 |
7410 DISALLOW_COPY_AND_ASSIGN(UnaryDoubleOpInstr); | 7075 DISALLOW_COPY_AND_ASSIGN(UnaryDoubleOpInstr); |
7411 }; | 7076 }; |
7412 | 7077 |
7413 | 7078 |
7414 class CheckStackOverflowInstr : public TemplateInstruction<0, NoThrow> { | 7079 class CheckStackOverflowInstr : public TemplateInstruction<0, NoThrow> { |
7415 public: | 7080 public: |
7416 CheckStackOverflowInstr(TokenPosition token_pos, intptr_t loop_depth) | 7081 CheckStackOverflowInstr(TokenPosition token_pos, intptr_t loop_depth) |
7417 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), | 7082 : TemplateInstruction(Thread::Current()->GetNextDeoptId()), |
7418 token_pos_(token_pos), | 7083 token_pos_(token_pos), |
7419 loop_depth_(loop_depth) { | 7084 loop_depth_(loop_depth) {} |
7420 } | |
7421 | 7085 |
7422 virtual TokenPosition token_pos() const { return token_pos_; } | 7086 virtual TokenPosition token_pos() const { return token_pos_; } |
7423 bool in_loop() const { return loop_depth_ > 0; } | 7087 bool in_loop() const { return loop_depth_ > 0; } |
7424 intptr_t loop_depth() const { return loop_depth_; } | 7088 intptr_t loop_depth() const { return loop_depth_; } |
7425 | 7089 |
7426 DECLARE_INSTRUCTION(CheckStackOverflow) | 7090 DECLARE_INSTRUCTION(CheckStackOverflow) |
7427 | 7091 |
7428 virtual bool CanDeoptimize() const { return true; } | 7092 virtual bool CanDeoptimize() const { return true; } |
7429 | 7093 |
7430 virtual EffectSet Effects() const { return EffectSet::None(); } | 7094 virtual EffectSet Effects() const { return EffectSet::None(); } |
(...skipping 15 matching lines...) Expand all Loading... |
7446 : token_pos_(token_pos) { | 7110 : token_pos_(token_pos) { |
7447 SetInputAt(0, value); | 7111 SetInputAt(0, value); |
7448 } | 7112 } |
7449 | 7113 |
7450 Value* value() const { return inputs_[0]; } | 7114 Value* value() const { return inputs_[0]; } |
7451 virtual TokenPosition token_pos() const { return token_pos_; } | 7115 virtual TokenPosition token_pos() const { return token_pos_; } |
7452 | 7116 |
7453 DECLARE_INSTRUCTION(SmiToDouble) | 7117 DECLARE_INSTRUCTION(SmiToDouble) |
7454 virtual CompileType ComputeType() const; | 7118 virtual CompileType ComputeType() const; |
7455 | 7119 |
7456 virtual Representation representation() const { | 7120 virtual Representation representation() const { return kUnboxedDouble; } |
7457 return kUnboxedDouble; | |
7458 } | |
7459 | 7121 |
7460 virtual bool CanDeoptimize() const { return false; } | 7122 virtual bool CanDeoptimize() const { return false; } |
7461 | 7123 |
7462 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7124 virtual bool AttributesEqual(Instruction* other) const { return true; } |
7463 | 7125 |
7464 private: | 7126 private: |
7465 const TokenPosition token_pos_; | 7127 const TokenPosition token_pos_; |
7466 | 7128 |
7467 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); | 7129 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); |
7468 }; | 7130 }; |
7469 | 7131 |
7470 | 7132 |
7471 class Int32ToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { | 7133 class Int32ToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7472 public: | 7134 public: |
7473 explicit Int32ToDoubleInstr(Value* value) { | 7135 explicit Int32ToDoubleInstr(Value* value) { SetInputAt(0, value); } |
7474 SetInputAt(0, value); | |
7475 } | |
7476 | 7136 |
7477 Value* value() const { return inputs_[0]; } | 7137 Value* value() const { return inputs_[0]; } |
7478 | 7138 |
7479 DECLARE_INSTRUCTION(Int32ToDouble) | 7139 DECLARE_INSTRUCTION(Int32ToDouble) |
7480 virtual CompileType ComputeType() const; | 7140 virtual CompileType ComputeType() const; |
7481 | 7141 |
7482 virtual Representation RequiredInputRepresentation(intptr_t index) const { | 7142 virtual Representation RequiredInputRepresentation(intptr_t index) const { |
7483 ASSERT(index == 0); | 7143 ASSERT(index == 0); |
7484 return kUnboxedInt32; | 7144 return kUnboxedInt32; |
7485 } | 7145 } |
7486 | 7146 |
7487 virtual Representation representation() const { | 7147 virtual Representation representation() const { return kUnboxedDouble; } |
7488 return kUnboxedDouble; | |
7489 } | |
7490 | 7148 |
7491 virtual bool CanDeoptimize() const { return false; } | 7149 virtual bool CanDeoptimize() const { return false; } |
7492 | 7150 |
7493 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7151 virtual bool AttributesEqual(Instruction* other) const { return true; } |
7494 | 7152 |
7495 private: | 7153 private: |
7496 DISALLOW_COPY_AND_ASSIGN(Int32ToDoubleInstr); | 7154 DISALLOW_COPY_AND_ASSIGN(Int32ToDoubleInstr); |
7497 }; | 7155 }; |
7498 | 7156 |
7499 | 7157 |
7500 class MintToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { | 7158 class MintToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7501 public: | 7159 public: |
7502 MintToDoubleInstr(Value* value, intptr_t deopt_id) | 7160 MintToDoubleInstr(Value* value, intptr_t deopt_id) |
7503 : TemplateDefinition(deopt_id) { | 7161 : TemplateDefinition(deopt_id) { |
7504 SetInputAt(0, value); | 7162 SetInputAt(0, value); |
7505 } | 7163 } |
7506 | 7164 |
7507 Value* value() const { return inputs_[0]; } | 7165 Value* value() const { return inputs_[0]; } |
7508 | 7166 |
7509 DECLARE_INSTRUCTION(MintToDouble) | 7167 DECLARE_INSTRUCTION(MintToDouble) |
7510 virtual CompileType ComputeType() const; | 7168 virtual CompileType ComputeType() const; |
7511 | 7169 |
7512 virtual Representation RequiredInputRepresentation(intptr_t index) const { | 7170 virtual Representation RequiredInputRepresentation(intptr_t index) const { |
7513 ASSERT(index == 0); | 7171 ASSERT(index == 0); |
7514 return kUnboxedMint; | 7172 return kUnboxedMint; |
7515 } | 7173 } |
7516 | 7174 |
7517 virtual Representation representation() const { | 7175 virtual Representation representation() const { return kUnboxedDouble; } |
7518 return kUnboxedDouble; | |
7519 } | |
7520 | 7176 |
7521 virtual intptr_t DeoptimizationTarget() const { | 7177 virtual intptr_t DeoptimizationTarget() const { |
7522 // Direct access since this instruction cannot deoptimize, and the deopt-id | 7178 // Direct access since this instruction cannot deoptimize, and the deopt-id |
7523 // was inherited from another instruction that could deoptimize. | 7179 // was inherited from another instruction that could deoptimize. |
7524 return GetDeoptId(); | 7180 return GetDeoptId(); |
7525 } | 7181 } |
7526 | 7182 |
7527 virtual bool CanDeoptimize() const { return false; } | 7183 virtual bool CanDeoptimize() const { return false; } |
7528 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7184 virtual bool AttributesEqual(Instruction* other) const { return true; } |
7529 | 7185 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7587 private: | 7243 private: |
7588 DISALLOW_COPY_AND_ASSIGN(DoubleToSmiInstr); | 7244 DISALLOW_COPY_AND_ASSIGN(DoubleToSmiInstr); |
7589 }; | 7245 }; |
7590 | 7246 |
7591 | 7247 |
7592 class DoubleToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { | 7248 class DoubleToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7593 public: | 7249 public: |
7594 DoubleToDoubleInstr(Value* value, | 7250 DoubleToDoubleInstr(Value* value, |
7595 MethodRecognizer::Kind recognized_kind, | 7251 MethodRecognizer::Kind recognized_kind, |
7596 intptr_t deopt_id) | 7252 intptr_t deopt_id) |
7597 : TemplateDefinition(deopt_id), | 7253 : TemplateDefinition(deopt_id), recognized_kind_(recognized_kind) { |
7598 recognized_kind_(recognized_kind) { | |
7599 SetInputAt(0, value); | 7254 SetInputAt(0, value); |
7600 } | 7255 } |
7601 | 7256 |
7602 Value* value() const { return inputs_[0]; } | 7257 Value* value() const { return inputs_[0]; } |
7603 | 7258 |
7604 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } | 7259 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } |
7605 | 7260 |
7606 DECLARE_INSTRUCTION(DoubleToDouble) | 7261 DECLARE_INSTRUCTION(DoubleToDouble) |
7607 virtual CompileType ComputeType() const; | 7262 virtual CompileType ComputeType() const; |
7608 | 7263 |
7609 virtual bool CanDeoptimize() const { return false; } | 7264 virtual bool CanDeoptimize() const { return false; } |
7610 | 7265 |
7611 virtual Representation representation() const { | 7266 virtual Representation representation() const { return kUnboxedDouble; } |
7612 return kUnboxedDouble; | |
7613 } | |
7614 | 7267 |
7615 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7268 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7616 ASSERT(idx == 0); | 7269 ASSERT(idx == 0); |
7617 return kUnboxedDouble; | 7270 return kUnboxedDouble; |
7618 } | 7271 } |
7619 | 7272 |
7620 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } | 7273 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } |
7621 | 7274 |
7622 virtual bool AttributesEqual(Instruction* other) const { | 7275 virtual bool AttributesEqual(Instruction* other) const { |
7623 return other->AsDoubleToDouble()->recognized_kind() == recognized_kind(); | 7276 return other->AsDoubleToDouble()->recognized_kind() == recognized_kind(); |
7624 } | 7277 } |
7625 | 7278 |
7626 private: | 7279 private: |
7627 const MethodRecognizer::Kind recognized_kind_; | 7280 const MethodRecognizer::Kind recognized_kind_; |
7628 | 7281 |
7629 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr); | 7282 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr); |
7630 }; | 7283 }; |
7631 | 7284 |
7632 | 7285 |
7633 class DoubleToFloatInstr: public TemplateDefinition<1, NoThrow, Pure> { | 7286 class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7634 public: | 7287 public: |
7635 DoubleToFloatInstr(Value* value, intptr_t deopt_id) | 7288 DoubleToFloatInstr(Value* value, intptr_t deopt_id) |
7636 : TemplateDefinition(deopt_id) { | 7289 : TemplateDefinition(deopt_id) { |
7637 SetInputAt(0, value); | 7290 SetInputAt(0, value); |
7638 } | 7291 } |
7639 | 7292 |
7640 Value* value() const { return inputs_[0]; } | 7293 Value* value() const { return inputs_[0]; } |
7641 | 7294 |
7642 DECLARE_INSTRUCTION(DoubleToFloat) | 7295 DECLARE_INSTRUCTION(DoubleToFloat) |
7643 | 7296 |
(...skipping 18 matching lines...) Expand all Loading... |
7662 | 7315 |
7663 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7316 virtual bool AttributesEqual(Instruction* other) const { return true; } |
7664 | 7317 |
7665 virtual Definition* Canonicalize(FlowGraph* flow_graph); | 7318 virtual Definition* Canonicalize(FlowGraph* flow_graph); |
7666 | 7319 |
7667 private: | 7320 private: |
7668 DISALLOW_COPY_AND_ASSIGN(DoubleToFloatInstr); | 7321 DISALLOW_COPY_AND_ASSIGN(DoubleToFloatInstr); |
7669 }; | 7322 }; |
7670 | 7323 |
7671 | 7324 |
7672 class FloatToDoubleInstr: public TemplateDefinition<1, NoThrow, Pure> { | 7325 class FloatToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> { |
7673 public: | 7326 public: |
7674 FloatToDoubleInstr(Value* value, intptr_t deopt_id) | 7327 FloatToDoubleInstr(Value* value, intptr_t deopt_id) |
7675 : TemplateDefinition(deopt_id) { | 7328 : TemplateDefinition(deopt_id) { |
7676 SetInputAt(0, value); | 7329 SetInputAt(0, value); |
7677 } | 7330 } |
7678 | 7331 |
7679 Value* value() const { return inputs_[0]; } | 7332 Value* value() const { return inputs_[0]; } |
7680 | 7333 |
7681 DECLARE_INSTRUCTION(FloatToDouble) | 7334 DECLARE_INSTRUCTION(FloatToDouble) |
7682 | 7335 |
7683 virtual CompileType ComputeType() const; | 7336 virtual CompileType ComputeType() const; |
7684 | 7337 |
7685 virtual bool CanDeoptimize() const { return false; } | 7338 virtual bool CanDeoptimize() const { return false; } |
7686 | 7339 |
7687 virtual Representation representation() const { | 7340 virtual Representation representation() const { return kUnboxedDouble; } |
7688 return kUnboxedDouble; | |
7689 } | |
7690 | 7341 |
7691 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7342 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7692 ASSERT(idx == 0); | 7343 ASSERT(idx == 0); |
7693 return kUnboxedDouble; | 7344 return kUnboxedDouble; |
7694 } | 7345 } |
7695 | 7346 |
7696 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } | 7347 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } |
7697 | 7348 |
7698 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7349 virtual bool AttributesEqual(Instruction* other) const { return true; } |
7699 | 7350 |
(...skipping 17 matching lines...) Expand all Loading... |
7717 | 7368 |
7718 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } | 7369 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } |
7719 | 7370 |
7720 virtual TokenPosition token_pos() const { return token_pos_; } | 7371 virtual TokenPosition token_pos() const { return token_pos_; } |
7721 | 7372 |
7722 DECLARE_INSTRUCTION(InvokeMathCFunction) | 7373 DECLARE_INSTRUCTION(InvokeMathCFunction) |
7723 virtual CompileType ComputeType() const; | 7374 virtual CompileType ComputeType() const; |
7724 | 7375 |
7725 virtual bool CanDeoptimize() const { return false; } | 7376 virtual bool CanDeoptimize() const { return false; } |
7726 | 7377 |
7727 virtual Representation representation() const { | 7378 virtual Representation representation() const { return kUnboxedDouble; } |
7728 return kUnboxedDouble; | |
7729 } | |
7730 | 7379 |
7731 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7380 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7732 ASSERT((0 <= idx) && (idx < InputCount())); | 7381 ASSERT((0 <= idx) && (idx < InputCount())); |
7733 return kUnboxedDouble; | 7382 return kUnboxedDouble; |
7734 } | 7383 } |
7735 | 7384 |
7736 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } | 7385 virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); } |
7737 | 7386 |
7738 virtual intptr_t InputCount() const { | 7387 virtual intptr_t InputCount() const { return inputs_->length(); } |
7739 return inputs_->length(); | |
7740 } | |
7741 | 7388 |
7742 virtual Value* InputAt(intptr_t i) const { | 7389 virtual Value* InputAt(intptr_t i) const { return (*inputs_)[i]; } |
7743 return (*inputs_)[i]; | |
7744 } | |
7745 | 7390 |
7746 virtual bool AttributesEqual(Instruction* other) const { | 7391 virtual bool AttributesEqual(Instruction* other) const { |
7747 InvokeMathCFunctionInstr* other_invoke = other->AsInvokeMathCFunction(); | 7392 InvokeMathCFunctionInstr* other_invoke = other->AsInvokeMathCFunction(); |
7748 return other_invoke->recognized_kind() == recognized_kind(); | 7393 return other_invoke->recognized_kind() == recognized_kind(); |
7749 } | 7394 } |
7750 | 7395 |
7751 virtual bool MayThrow() const { return false; } | 7396 virtual bool MayThrow() const { return false; } |
7752 | 7397 |
7753 static const intptr_t kSavedSpTempIndex = 0; | 7398 static const intptr_t kSavedSpTempIndex = 0; |
7754 static const intptr_t kObjectTempIndex = 1; | 7399 static const intptr_t kObjectTempIndex = 1; |
(...skipping 29 matching lines...) Expand all Loading... |
7784 | 7429 |
7785 Value* value() const { return inputs_[0]; } | 7430 Value* value() const { return inputs_[0]; } |
7786 | 7431 |
7787 DECLARE_INSTRUCTION(ExtractNthOutput) | 7432 DECLARE_INSTRUCTION(ExtractNthOutput) |
7788 | 7433 |
7789 virtual CompileType ComputeType() const; | 7434 virtual CompileType ComputeType() const; |
7790 virtual bool CanDeoptimize() const { return false; } | 7435 virtual bool CanDeoptimize() const { return false; } |
7791 | 7436 |
7792 intptr_t index() const { return index_; } | 7437 intptr_t index() const { return index_; } |
7793 | 7438 |
7794 virtual Representation representation() const { | 7439 virtual Representation representation() const { return definition_rep_; } |
7795 return definition_rep_; | |
7796 } | |
7797 | 7440 |
7798 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7441 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
7799 ASSERT(idx == 0); | 7442 ASSERT(idx == 0); |
7800 if (representation() == kTagged) { | 7443 if (representation() == kTagged) { |
7801 return kPairOfTagged; | 7444 return kPairOfTagged; |
7802 } else if (representation() == kUnboxedDouble) { | 7445 } else if (representation() == kUnboxedDouble) { |
7803 return kPairOfUnboxedDouble; | 7446 return kPairOfUnboxedDouble; |
7804 } | 7447 } |
7805 UNREACHABLE(); | 7448 UNREACHABLE(); |
7806 return definition_rep_; | 7449 return definition_rep_; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7841 } else { | 7484 } else { |
7842 UNIMPLEMENTED(); | 7485 UNIMPLEMENTED(); |
7843 return -1; | 7486 return -1; |
7844 } | 7487 } |
7845 } | 7488 } |
7846 | 7489 |
7847 MergedMathInstr::Kind kind() const { return kind_; } | 7490 MergedMathInstr::Kind kind() const { return kind_; } |
7848 | 7491 |
7849 virtual intptr_t InputCount() const { return inputs_->length(); } | 7492 virtual intptr_t InputCount() const { return inputs_->length(); } |
7850 | 7493 |
7851 virtual Value* InputAt(intptr_t i) const { | 7494 virtual Value* InputAt(intptr_t i) const { return (*inputs_)[i]; } |
7852 return (*inputs_)[i]; | |
7853 } | |
7854 | 7495 |
7855 static intptr_t OutputIndexOf(MethodRecognizer::Kind kind); | 7496 static intptr_t OutputIndexOf(MethodRecognizer::Kind kind); |
7856 static intptr_t OutputIndexOf(Token::Kind token); | 7497 static intptr_t OutputIndexOf(Token::Kind token); |
7857 | 7498 |
7858 virtual CompileType ComputeType() const; | 7499 virtual CompileType ComputeType() const; |
7859 | 7500 |
7860 virtual bool CanDeoptimize() const { | 7501 virtual bool CanDeoptimize() const { |
7861 if (kind_ == kTruncDivMod) { | 7502 if (kind_ == kTruncDivMod) { |
7862 return true; | 7503 return true; |
7863 } else if (kind_ == kSinCos) { | 7504 } else if (kind_ == kSinCos) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7935 virtual TokenPosition token_pos() const { return token_pos_; } | 7576 virtual TokenPosition token_pos() const { return token_pos_; } |
7936 | 7577 |
7937 Value* value() const { return inputs_[0]; } | 7578 Value* value() const { return inputs_[0]; } |
7938 | 7579 |
7939 const ICData& unary_checks() const { return unary_checks_; } | 7580 const ICData& unary_checks() const { return unary_checks_; } |
7940 | 7581 |
7941 const GrowableArray<intptr_t>& cids() const { return cids_; } | 7582 const GrowableArray<intptr_t>& cids() const { return cids_; } |
7942 | 7583 |
7943 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 7584 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
7944 | 7585 |
7945 bool IsNullCheck() const { | 7586 bool IsNullCheck() const { return DeoptIfNull() || DeoptIfNotNull(); } |
7946 return DeoptIfNull() || DeoptIfNotNull(); | |
7947 } | |
7948 | 7587 |
7949 bool DeoptIfNull() const; | 7588 bool DeoptIfNull() const; |
7950 bool DeoptIfNotNull() const; | 7589 bool DeoptIfNotNull() const; |
7951 | 7590 |
7952 bool IsDenseSwitch() const; | 7591 bool IsDenseSwitch() const; |
7953 static bool IsDenseCidRange(const ICData& unary_checks); | 7592 static bool IsDenseCidRange(const ICData& unary_checks); |
7954 intptr_t ComputeCidMask() const; | 7593 intptr_t ComputeCidMask() const; |
7955 static bool IsDenseMask(intptr_t mask); | 7594 static bool IsDenseMask(intptr_t mask); |
7956 | 7595 |
7957 virtual bool AllowsCSE() const { return true; } | 7596 virtual bool AllowsCSE() const { return true; } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8048 | 7687 |
8049 Value* length() const { return inputs_[kLengthPos]; } | 7688 Value* length() const { return inputs_[kLengthPos]; } |
8050 Value* index() const { return inputs_[kIndexPos]; } | 7689 Value* index() const { return inputs_[kIndexPos]; } |
8051 | 7690 |
8052 DECLARE_INSTRUCTION(CheckArrayBound) | 7691 DECLARE_INSTRUCTION(CheckArrayBound) |
8053 | 7692 |
8054 virtual bool CanDeoptimize() const { return true; } | 7693 virtual bool CanDeoptimize() const { return true; } |
8055 | 7694 |
8056 bool IsRedundant(const RangeBoundary& length); | 7695 bool IsRedundant(const RangeBoundary& length); |
8057 | 7696 |
8058 void mark_generalized() { | 7697 void mark_generalized() { generalized_ = true; } |
8059 generalized_ = true; | |
8060 } | |
8061 | 7698 |
8062 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 7699 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
8063 | 7700 |
8064 // Returns the length offset for array and string types. | 7701 // Returns the length offset for array and string types. |
8065 static intptr_t LengthOffsetFor(intptr_t class_id); | 7702 static intptr_t LengthOffsetFor(intptr_t class_id); |
8066 | 7703 |
8067 static bool IsFixedLengthArrayType(intptr_t class_id); | 7704 static bool IsFixedLengthArrayType(intptr_t class_id); |
8068 | 7705 |
8069 virtual bool AttributesEqual(Instruction* other) const { return true; } | 7706 virtual bool AttributesEqual(Instruction* other) const { return true; } |
8070 | 7707 |
8071 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } | 7708 void set_licm_hoisted(bool value) { licm_hoisted_ = value; } |
8072 | 7709 |
8073 // Give a name to the location/input indices. | 7710 // Give a name to the location/input indices. |
8074 enum { | 7711 enum { kLengthPos = 0, kIndexPos = 1 }; |
8075 kLengthPos = 0, | |
8076 kIndexPos = 1 | |
8077 }; | |
8078 | 7712 |
8079 private: | 7713 private: |
8080 bool generalized_; | 7714 bool generalized_; |
8081 bool licm_hoisted_; | 7715 bool licm_hoisted_; |
8082 | 7716 |
8083 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); | 7717 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); |
8084 }; | 7718 }; |
8085 | 7719 |
8086 | 7720 |
8087 class GenericCheckBoundInstr : public TemplateInstruction<2, Throws, NoCSE> { | 7721 class GenericCheckBoundInstr : public TemplateInstruction<2, Throws, NoCSE> { |
8088 public: | 7722 public: |
8089 GenericCheckBoundInstr(Value* length, Value* index, intptr_t deopt_id) | 7723 GenericCheckBoundInstr(Value* length, Value* index, intptr_t deopt_id) |
8090 : TemplateInstruction(deopt_id) { | 7724 : TemplateInstruction(deopt_id) { |
8091 SetInputAt(kLengthPos, length); | 7725 SetInputAt(kLengthPos, length); |
8092 SetInputAt(kIndexPos, index); | 7726 SetInputAt(kIndexPos, index); |
8093 } | 7727 } |
8094 | 7728 |
8095 Value* length() const { return inputs_[kLengthPos]; } | 7729 Value* length() const { return inputs_[kLengthPos]; } |
8096 Value* index() const { return inputs_[kIndexPos]; } | 7730 Value* index() const { return inputs_[kIndexPos]; } |
8097 | 7731 |
8098 virtual EffectSet Effects() const { return EffectSet::None(); } | 7732 virtual EffectSet Effects() const { return EffectSet::None(); } |
8099 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7733 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
8100 | 7734 |
8101 DECLARE_INSTRUCTION(GenericCheckBound) | 7735 DECLARE_INSTRUCTION(GenericCheckBound) |
8102 | 7736 |
8103 virtual bool CanDeoptimize() const { return true; } | 7737 virtual bool CanDeoptimize() const { return true; } |
8104 | 7738 |
8105 // Give a name to the location/input indices. | 7739 // Give a name to the location/input indices. |
8106 enum { | 7740 enum { kLengthPos = 0, kIndexPos = 1 }; |
8107 kLengthPos = 0, | |
8108 kIndexPos = 1 | |
8109 }; | |
8110 | 7741 |
8111 private: | 7742 private: |
8112 DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr); | 7743 DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr); |
8113 }; | 7744 }; |
8114 | 7745 |
8115 | 7746 |
8116 class UnboxedIntConverterInstr : public TemplateDefinition<1, NoThrow> { | 7747 class UnboxedIntConverterInstr : public TemplateDefinition<1, NoThrow> { |
8117 public: | 7748 public: |
8118 UnboxedIntConverterInstr(Representation from, | 7749 UnboxedIntConverterInstr(Representation from, |
8119 Representation to, | 7750 Representation to, |
8120 Value* value, | 7751 Value* value, |
8121 intptr_t deopt_id) | 7752 intptr_t deopt_id) |
8122 : TemplateDefinition(deopt_id), | 7753 : TemplateDefinition(deopt_id), |
8123 from_representation_(from), | 7754 from_representation_(from), |
8124 to_representation_(to), | 7755 to_representation_(to), |
8125 is_truncating_(to == kUnboxedUint32) { | 7756 is_truncating_(to == kUnboxedUint32) { |
8126 ASSERT(from != to); | 7757 ASSERT(from != to); |
8127 ASSERT((from == kUnboxedMint) || | 7758 ASSERT((from == kUnboxedMint) || (from == kUnboxedUint32) || |
8128 (from == kUnboxedUint32) || | |
8129 (from == kUnboxedInt32)); | 7759 (from == kUnboxedInt32)); |
8130 ASSERT((to == kUnboxedMint) || | 7760 ASSERT((to == kUnboxedMint) || (to == kUnboxedUint32) || |
8131 (to == kUnboxedUint32) || | |
8132 (to == kUnboxedInt32)); | 7761 (to == kUnboxedInt32)); |
8133 SetInputAt(0, value); | 7762 SetInputAt(0, value); |
8134 } | 7763 } |
8135 | 7764 |
8136 Value* value() const { return inputs_[0]; } | 7765 Value* value() const { return inputs_[0]; } |
8137 | 7766 |
8138 Representation from() const { return from_representation_; } | 7767 Representation from() const { return from_representation_; } |
8139 Representation to() const { return to_representation_; } | 7768 Representation to() const { return to_representation_; } |
8140 bool is_truncating() const { return is_truncating_; } | 7769 bool is_truncating() const { return is_truncating_; } |
8141 | 7770 |
8142 void mark_truncating() { is_truncating_ = true; } | 7771 void mark_truncating() { is_truncating_ = true; } |
8143 | 7772 |
8144 Definition* Canonicalize(FlowGraph* flow_graph); | 7773 Definition* Canonicalize(FlowGraph* flow_graph); |
8145 | 7774 |
8146 virtual bool CanDeoptimize() const; | 7775 virtual bool CanDeoptimize() const; |
8147 | 7776 |
8148 virtual Representation representation() const { | 7777 virtual Representation representation() const { return to(); } |
8149 return to(); | |
8150 } | |
8151 | 7778 |
8152 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 7779 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
8153 ASSERT(idx == 0); | 7780 ASSERT(idx == 0); |
8154 return from(); | 7781 return from(); |
8155 } | 7782 } |
8156 | 7783 |
8157 virtual EffectSet Effects() const { return EffectSet::None(); } | 7784 virtual EffectSet Effects() const { return EffectSet::None(); } |
8158 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 7785 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
8159 virtual bool AttributesEqual(Instruction* other) const { | 7786 virtual bool AttributesEqual(Instruction* other) const { |
8160 ASSERT(other->IsUnboxedIntConverter()); | 7787 ASSERT(other->IsUnboxedIntConverter()); |
8161 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); | 7788 UnboxedIntConverterInstr* converter = other->AsUnboxedIntConverter(); |
8162 return (converter->from() == from()) && | 7789 return (converter->from() == from()) && (converter->to() == to()) && |
8163 (converter->to() == to()) && | 7790 (converter->is_truncating() == is_truncating()); |
8164 (converter->is_truncating() == is_truncating()); | |
8165 } | 7791 } |
8166 | 7792 |
8167 virtual void InferRange(RangeAnalysis* analysis, Range* range); | 7793 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
8168 | 7794 |
8169 virtual CompileType ComputeType() const { | 7795 virtual CompileType ComputeType() const { |
8170 // TODO(vegorov) use range information to improve type. | 7796 // TODO(vegorov) use range information to improve type. |
8171 return CompileType::Int(); | 7797 return CompileType::Int(); |
8172 } | 7798 } |
8173 | 7799 |
8174 DECLARE_INSTRUCTION(UnboxedIntConverter); | 7800 DECLARE_INSTRUCTION(UnboxedIntConverter); |
(...skipping 28 matching lines...) Expand all Loading... |
8203 | 7829 |
8204 | 7830 |
8205 #undef DECLARE_INSTRUCTION | 7831 #undef DECLARE_INSTRUCTION |
8206 | 7832 |
8207 class Environment : public ZoneAllocated { | 7833 class Environment : public ZoneAllocated { |
8208 public: | 7834 public: |
8209 // Iterate the non-NULL values in the innermost level of an environment. | 7835 // Iterate the non-NULL values in the innermost level of an environment. |
8210 class ShallowIterator : public ValueObject { | 7836 class ShallowIterator : public ValueObject { |
8211 public: | 7837 public: |
8212 explicit ShallowIterator(Environment* environment) | 7838 explicit ShallowIterator(Environment* environment) |
8213 : environment_(environment), index_(0) { } | 7839 : environment_(environment), index_(0) {} |
8214 | 7840 |
8215 ShallowIterator(const ShallowIterator& other) | 7841 ShallowIterator(const ShallowIterator& other) |
8216 : ValueObject(), | 7842 : ValueObject(), |
8217 environment_(other.environment_), | 7843 environment_(other.environment_), |
8218 index_(other.index_) { } | 7844 index_(other.index_) {} |
8219 | 7845 |
8220 ShallowIterator& operator=(const ShallowIterator& other) { | 7846 ShallowIterator& operator=(const ShallowIterator& other) { |
8221 environment_ = other.environment_; | 7847 environment_ = other.environment_; |
8222 index_ = other.index_; | 7848 index_ = other.index_; |
8223 return *this; | 7849 return *this; |
8224 } | 7850 } |
8225 | 7851 |
8226 Environment* environment() const { return environment_; } | 7852 Environment* environment() const { return environment_; } |
8227 | 7853 |
8228 void Advance() { | 7854 void Advance() { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8318 locations_ = locations; | 7944 locations_ = locations; |
8319 } | 7945 } |
8320 | 7946 |
8321 void set_deopt_id(intptr_t deopt_id) { deopt_id_ = deopt_id; } | 7947 void set_deopt_id(intptr_t deopt_id) { deopt_id_ = deopt_id; } |
8322 intptr_t deopt_id() const { return deopt_id_; } | 7948 intptr_t deopt_id() const { return deopt_id_; } |
8323 | 7949 |
8324 Environment* outer() const { return outer_; } | 7950 Environment* outer() const { return outer_; } |
8325 | 7951 |
8326 Environment* Outermost() { | 7952 Environment* Outermost() { |
8327 Environment* result = this; | 7953 Environment* result = this; |
8328 while (result->outer() != NULL) result = result->outer(); | 7954 while (result->outer() != NULL) |
| 7955 result = result->outer(); |
8329 return result; | 7956 return result; |
8330 } | 7957 } |
8331 | 7958 |
8332 Value* ValueAt(intptr_t ix) const { | 7959 Value* ValueAt(intptr_t ix) const { return values_[ix]; } |
8333 return values_[ix]; | |
8334 } | |
8335 | 7960 |
8336 intptr_t Length() const { | 7961 intptr_t Length() const { return values_.length(); } |
8337 return values_.length(); | |
8338 } | |
8339 | 7962 |
8340 Location LocationAt(intptr_t index) const { | 7963 Location LocationAt(intptr_t index) const { |
8341 ASSERT((index >= 0) && (index < values_.length())); | 7964 ASSERT((index >= 0) && (index < values_.length())); |
8342 return locations_[index]; | 7965 return locations_[index]; |
8343 } | 7966 } |
8344 | 7967 |
8345 // The use index is the index in the flattened environment. | 7968 // The use index is the index in the flattened environment. |
8346 Value* ValueAtUseIndex(intptr_t index) const { | 7969 Value* ValueAtUseIndex(intptr_t index) const { |
8347 const Environment* env = this; | 7970 const Environment* env = this; |
8348 while (index >= env->Length()) { | 7971 while (index >= env->Length()) { |
8349 ASSERT(env->outer_ != NULL); | 7972 ASSERT(env->outer_ != NULL); |
8350 index -= env->Length(); | 7973 index -= env->Length(); |
8351 env = env->outer_; | 7974 env = env->outer_; |
8352 } | 7975 } |
8353 return env->ValueAt(index); | 7976 return env->ValueAt(index); |
8354 } | 7977 } |
8355 | 7978 |
8356 intptr_t fixed_parameter_count() const { | 7979 intptr_t fixed_parameter_count() const { return fixed_parameter_count_; } |
8357 return fixed_parameter_count_; | |
8358 } | |
8359 | 7980 |
8360 intptr_t CountArgsPushed() { | 7981 intptr_t CountArgsPushed() { |
8361 intptr_t count = 0; | 7982 intptr_t count = 0; |
8362 for (Environment::DeepIterator it(this); !it.Done(); it.Advance()) { | 7983 for (Environment::DeepIterator it(this); !it.Done(); it.Advance()) { |
8363 if (it.CurrentValue()->definition()->IsPushArgument()) { | 7984 if (it.CurrentValue()->definition()->IsPushArgument()) { |
8364 count++; | 7985 count++; |
8365 } | 7986 } |
8366 } | 7987 } |
8367 return count; | 7988 return count; |
8368 } | 7989 } |
8369 | 7990 |
8370 const Function& function() const { return parsed_function_.function(); } | 7991 const Function& function() const { return parsed_function_.function(); } |
8371 | 7992 |
8372 Environment* DeepCopy(Zone* zone) const { | 7993 Environment* DeepCopy(Zone* zone) const { return DeepCopy(zone, Length()); } |
8373 return DeepCopy(zone, Length()); | |
8374 } | |
8375 | 7994 |
8376 void DeepCopyTo(Zone* zone, Instruction* instr) const; | 7995 void DeepCopyTo(Zone* zone, Instruction* instr) const; |
8377 void DeepCopyToOuter(Zone* zone, Instruction* instr) const; | 7996 void DeepCopyToOuter(Zone* zone, Instruction* instr) const; |
8378 | 7997 |
8379 void DeepCopyAfterTo(Zone* zone, | 7998 void DeepCopyAfterTo(Zone* zone, |
8380 Instruction* instr, | 7999 Instruction* instr, |
8381 intptr_t argc, | 8000 intptr_t argc, |
8382 Definition* dead, | 8001 Definition* dead, |
8383 Definition* result) const; | 8002 Definition* result) const; |
8384 | 8003 |
(...skipping 22 matching lines...) Expand all Loading... |
8407 Environment(intptr_t length, | 8026 Environment(intptr_t length, |
8408 intptr_t fixed_parameter_count, | 8027 intptr_t fixed_parameter_count, |
8409 intptr_t deopt_id, | 8028 intptr_t deopt_id, |
8410 const ParsedFunction& parsed_function, | 8029 const ParsedFunction& parsed_function, |
8411 Environment* outer) | 8030 Environment* outer) |
8412 : values_(length), | 8031 : values_(length), |
8413 locations_(NULL), | 8032 locations_(NULL), |
8414 fixed_parameter_count_(fixed_parameter_count), | 8033 fixed_parameter_count_(fixed_parameter_count), |
8415 deopt_id_(deopt_id), | 8034 deopt_id_(deopt_id), |
8416 parsed_function_(parsed_function), | 8035 parsed_function_(parsed_function), |
8417 outer_(outer) { | 8036 outer_(outer) {} |
8418 } | |
8419 | 8037 |
8420 | 8038 |
8421 GrowableArray<Value*> values_; | 8039 GrowableArray<Value*> values_; |
8422 Location* locations_; | 8040 Location* locations_; |
8423 const intptr_t fixed_parameter_count_; | 8041 const intptr_t fixed_parameter_count_; |
8424 intptr_t deopt_id_; | 8042 intptr_t deopt_id_; |
8425 const ParsedFunction& parsed_function_; | 8043 const ParsedFunction& parsed_function_; |
8426 Environment* outer_; | 8044 Environment* outer_; |
8427 | 8045 |
8428 DISALLOW_COPY_AND_ASSIGN(Environment); | 8046 DISALLOW_COPY_AND_ASSIGN(Environment); |
8429 }; | 8047 }; |
8430 | 8048 |
8431 | 8049 |
8432 // Visitor base class to visit each instruction and computation in a flow | 8050 // Visitor base class to visit each instruction and computation in a flow |
8433 // graph as defined by a reversed list of basic blocks. | 8051 // graph as defined by a reversed list of basic blocks. |
8434 class FlowGraphVisitor : public ValueObject { | 8052 class FlowGraphVisitor : public ValueObject { |
8435 public: | 8053 public: |
8436 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) | 8054 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) |
8437 : current_iterator_(NULL), block_order_(block_order) { } | 8055 : current_iterator_(NULL), block_order_(block_order) {} |
8438 virtual ~FlowGraphVisitor() { } | 8056 virtual ~FlowGraphVisitor() {} |
8439 | 8057 |
8440 ForwardInstructionIterator* current_iterator() const { | 8058 ForwardInstructionIterator* current_iterator() const { |
8441 return current_iterator_; | 8059 return current_iterator_; |
8442 } | 8060 } |
8443 | 8061 |
8444 // Visit each block in the block order, and for each block its | 8062 // Visit each block in the block order, and for each block its |
8445 // instructions in order from the block entry to exit. | 8063 // instructions in order from the block entry to exit. |
8446 virtual void VisitBlocks(); | 8064 virtual void VisitBlocks(); |
8447 | 8065 |
8448 // Visit functions for instruction classes, with an empty default | 8066 // Visit functions for instruction classes, with an empty default |
8449 // implementation. | 8067 // implementation. |
8450 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ | 8068 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ |
8451 virtual void Visit##ShortName(ShortName##Instr* instr) { } | 8069 virtual void Visit##ShortName(ShortName##Instr* instr) {} |
8452 | 8070 |
8453 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) | 8071 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) |
8454 | 8072 |
8455 #undef DECLARE_VISIT_INSTRUCTION | 8073 #undef DECLARE_VISIT_INSTRUCTION |
8456 | 8074 |
8457 protected: | 8075 protected: |
8458 ForwardInstructionIterator* current_iterator_; | 8076 ForwardInstructionIterator* current_iterator_; |
8459 | 8077 |
8460 private: | 8078 private: |
8461 const GrowableArray<BlockEntryInstr*>& block_order_; | 8079 const GrowableArray<BlockEntryInstr*>& block_order_; |
8462 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 8080 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
8463 }; | 8081 }; |
8464 | 8082 |
8465 | 8083 |
8466 // Helper macros for platform ports. | 8084 // Helper macros for platform ports. |
8467 #define DEFINE_UNIMPLEMENTED_INSTRUCTION(Name) \ | 8085 #define DEFINE_UNIMPLEMENTED_INSTRUCTION(Name) \ |
8468 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ | 8086 LocationSummary* Name::MakeLocationSummary(Zone* zone, bool opt) const { \ |
8469 UNIMPLEMENTED(); \ | 8087 UNIMPLEMENTED(); \ |
8470 return NULL; \ | 8088 return NULL; \ |
8471 } \ | 8089 } \ |
8472 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8090 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
8473 | 8091 |
8474 | 8092 |
8475 } // namespace dart | 8093 } // namespace dart |
8476 | 8094 |
8477 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ | 8095 #endif // RUNTIME_VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |