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