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

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/instructions_x64.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « runtime/vm/instructions_x64.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698