| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define 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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 Instruction* instruction_; | 125 Instruction* instruction_; |
| 126 intptr_t use_index_; | 126 intptr_t use_index_; |
| 127 | 127 |
| 128 intptr_t reaching_cid_; | 128 intptr_t reaching_cid_; |
| 129 | 129 |
| 130 DISALLOW_COPY_AND_ASSIGN(Value); | 130 DISALLOW_COPY_AND_ASSIGN(Value); |
| 131 }; | 131 }; |
| 132 | 132 |
| 133 | 133 |
| 134 enum Representation { | 134 enum Representation { |
| 135 kTagged, kUnboxedDouble | 135 kTagged, |
| 136 kUnboxedDouble, |
| 137 kUnboxedInteger |
| 136 }; | 138 }; |
| 137 | 139 |
| 138 | 140 |
| 139 // An embedded container with N elements of type T. Used (with partial | 141 // An embedded container with N elements of type T. Used (with partial |
| 140 // specialization for N=0) because embedded arrays cannot have size 0. | 142 // specialization for N=0) because embedded arrays cannot have size 0. |
| 141 template<typename T, intptr_t N> | 143 template<typename T, intptr_t N> |
| 142 class EmbeddedArray { | 144 class EmbeddedArray { |
| 143 public: | 145 public: |
| 144 EmbeddedArray() { | 146 EmbeddedArray() { |
| 145 for (intptr_t i = 0; i < N; i++) elements_[i] = NULL; | 147 for (intptr_t i = 0; i < N; i++) elements_[i] = NULL; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 M(DoubleToDouble) \ | 249 M(DoubleToDouble) \ |
| 248 M(SmiToDouble) \ | 250 M(SmiToDouble) \ |
| 249 M(CheckClass) \ | 251 M(CheckClass) \ |
| 250 M(CheckSmi) \ | 252 M(CheckSmi) \ |
| 251 M(Constant) \ | 253 M(Constant) \ |
| 252 M(CheckEitherNonSmi) \ | 254 M(CheckEitherNonSmi) \ |
| 253 M(UnboxedDoubleBinaryOp) \ | 255 M(UnboxedDoubleBinaryOp) \ |
| 254 M(MathSqrt) \ | 256 M(MathSqrt) \ |
| 255 M(UnboxDouble) \ | 257 M(UnboxDouble) \ |
| 256 M(BoxDouble) \ | 258 M(BoxDouble) \ |
| 259 M(UnboxInteger) \ |
| 260 M(BoxInteger) \ |
| 261 M(UnboxedMintBinaryOp) \ |
| 257 M(CheckArrayBound) \ | 262 M(CheckArrayBound) \ |
| 258 M(Constraint) \ | 263 M(Constraint) \ |
| 259 | 264 |
| 260 | 265 |
| 261 #define FORWARD_DECLARATION(type) class type##Instr; | 266 #define FORWARD_DECLARATION(type) class type##Instr; |
| 262 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 267 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 263 #undef FORWARD_DECLARATION | 268 #undef FORWARD_DECLARATION |
| 264 | 269 |
| 265 | 270 |
| 266 // Functions required in all concrete instruction classes. | 271 // Functions required in all concrete instruction classes. |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 protected: | 497 protected: |
| 493 // Fetch deopt id without checking if this computation can deoptimize. | 498 // Fetch deopt id without checking if this computation can deoptimize. |
| 494 intptr_t GetDeoptId() const { | 499 intptr_t GetDeoptId() const { |
| 495 return deopt_id_; | 500 return deopt_id_; |
| 496 } | 501 } |
| 497 | 502 |
| 498 private: | 503 private: |
| 499 friend class Definition; // Needed for InsertBefore, InsertAfter. | 504 friend class Definition; // Needed for InsertBefore, InsertAfter. |
| 500 | 505 |
| 501 // Classes that set deopt_id_. | 506 // Classes that set deopt_id_. |
| 507 friend class UnboxIntegerInstr; |
| 502 friend class UnboxDoubleInstr; | 508 friend class UnboxDoubleInstr; |
| 503 friend class UnboxedDoubleBinaryOpInstr; | 509 friend class UnboxedDoubleBinaryOpInstr; |
| 510 friend class UnboxedMintBinaryOpInstr; |
| 504 friend class MathSqrtInstr; | 511 friend class MathSqrtInstr; |
| 505 friend class CheckClassInstr; | 512 friend class CheckClassInstr; |
| 506 friend class CheckSmiInstr; | 513 friend class CheckSmiInstr; |
| 507 friend class CheckArrayBoundInstr; | 514 friend class CheckArrayBoundInstr; |
| 508 friend class CheckEitherNonSmiInstr; | 515 friend class CheckEitherNonSmiInstr; |
| 509 friend class LICM; | 516 friend class LICM; |
| 510 | 517 |
| 511 intptr_t deopt_id_; | 518 intptr_t deopt_id_; |
| 512 intptr_t lifetime_position_; // Position used by register allocator. | 519 intptr_t lifetime_position_; // Position used by register allocator. |
| 513 Instruction* previous_; | 520 Instruction* previous_; |
| (...skipping 1785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2299 | 2306 |
| 2300 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2307 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2301 BranchInstr* branch); | 2308 BranchInstr* branch); |
| 2302 | 2309 |
| 2303 virtual intptr_t DeoptimizationTarget() const { | 2310 virtual intptr_t DeoptimizationTarget() const { |
| 2304 return GetDeoptId(); | 2311 return GetDeoptId(); |
| 2305 } | 2312 } |
| 2306 | 2313 |
| 2307 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2314 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 2308 ASSERT((idx == 0) || (idx == 1)); | 2315 ASSERT((idx == 0) || (idx == 1)); |
| 2309 return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged; | 2316 if (receiver_class_id() == kDoubleCid) return kUnboxedDouble; |
| 2317 if (receiver_class_id() == kMintCid) return kUnboxedInteger; |
| 2318 return kTagged; |
| 2310 } | 2319 } |
| 2311 | 2320 |
| 2312 private: | 2321 private: |
| 2313 const ICData* ic_data_; | 2322 const ICData* ic_data_; |
| 2314 const intptr_t token_pos_; | 2323 const intptr_t token_pos_; |
| 2315 intptr_t receiver_class_id_; // Set by optimizer. | 2324 intptr_t receiver_class_id_; // Set by optimizer. |
| 2316 | 2325 |
| 2317 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); | 2326 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); |
| 2318 }; | 2327 }; |
| 2319 | 2328 |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3295 DECLARE_INSTRUCTION(BoxDouble) | 3304 DECLARE_INSTRUCTION(BoxDouble) |
| 3296 virtual RawAbstractType* CompileType() const; | 3305 virtual RawAbstractType* CompileType() const; |
| 3297 | 3306 |
| 3298 private: | 3307 private: |
| 3299 const intptr_t token_pos_; | 3308 const intptr_t token_pos_; |
| 3300 | 3309 |
| 3301 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr); | 3310 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr); |
| 3302 }; | 3311 }; |
| 3303 | 3312 |
| 3304 | 3313 |
| 3314 class BoxIntegerInstr : public TemplateDefinition<1> { |
| 3315 public: |
| 3316 explicit BoxIntegerInstr(Value* value) { |
| 3317 ASSERT(value != NULL); |
| 3318 inputs_[0] = value; |
| 3319 } |
| 3320 |
| 3321 Value* value() const { return inputs_[0]; } |
| 3322 |
| 3323 virtual bool CanDeoptimize() const { return false; } |
| 3324 |
| 3325 virtual bool HasSideEffect() const { return false; } |
| 3326 |
| 3327 virtual bool AffectedBySideEffect() const { return false; } |
| 3328 virtual bool AttributesEqual(Instruction* other) const { return true; } |
| 3329 |
| 3330 virtual intptr_t ResultCid() const; |
| 3331 |
| 3332 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 3333 ASSERT(idx == 0); |
| 3334 return kUnboxedInteger; |
| 3335 } |
| 3336 |
| 3337 DECLARE_INSTRUCTION(BoxInteger) |
| 3338 virtual RawAbstractType* CompileType() const; |
| 3339 |
| 3340 private: |
| 3341 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); |
| 3342 }; |
| 3343 |
| 3344 |
| 3305 class UnboxDoubleInstr : public TemplateDefinition<1> { | 3345 class UnboxDoubleInstr : public TemplateDefinition<1> { |
| 3306 public: | 3346 public: |
| 3307 UnboxDoubleInstr(Value* value, intptr_t deopt_id) { | 3347 UnboxDoubleInstr(Value* value, intptr_t deopt_id) { |
| 3308 ASSERT(value != NULL); | 3348 ASSERT(value != NULL); |
| 3309 inputs_[0] = value; | 3349 inputs_[0] = value; |
| 3310 deopt_id_ = deopt_id; | 3350 deopt_id_ = deopt_id; |
| 3311 } | 3351 } |
| 3312 | 3352 |
| 3313 Value* value() const { return inputs_[0]; } | 3353 Value* value() const { return inputs_[0]; } |
| 3314 | 3354 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3330 virtual bool AttributesEqual(Instruction* other) const { return true; } | 3370 virtual bool AttributesEqual(Instruction* other) const { return true; } |
| 3331 | 3371 |
| 3332 DECLARE_INSTRUCTION(UnboxDouble) | 3372 DECLARE_INSTRUCTION(UnboxDouble) |
| 3333 virtual RawAbstractType* CompileType() const; | 3373 virtual RawAbstractType* CompileType() const; |
| 3334 | 3374 |
| 3335 private: | 3375 private: |
| 3336 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr); | 3376 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr); |
| 3337 }; | 3377 }; |
| 3338 | 3378 |
| 3339 | 3379 |
| 3380 class UnboxIntegerInstr : public TemplateDefinition<1> { |
| 3381 public: |
| 3382 UnboxIntegerInstr(Value* value, intptr_t deopt_id) { |
| 3383 ASSERT(value != NULL); |
| 3384 inputs_[0] = value; |
| 3385 deopt_id_ = deopt_id; |
| 3386 } |
| 3387 |
| 3388 Value* value() const { return inputs_[0]; } |
| 3389 |
| 3390 virtual bool CanDeoptimize() const { |
| 3391 return (value()->ResultCid() != kMintCid) |
| 3392 && (value()->ResultCid() != kSmiCid); |
| 3393 } |
| 3394 |
| 3395 virtual bool HasSideEffect() const { return false; } |
| 3396 |
| 3397 virtual intptr_t ResultCid() const; |
| 3398 |
| 3399 virtual RawAbstractType* CompileType() const; |
| 3400 |
| 3401 virtual Representation representation() const { |
| 3402 return kUnboxedInteger; |
| 3403 } |
| 3404 |
| 3405 virtual bool AffectedBySideEffect() const { return false; } |
| 3406 virtual bool AttributesEqual(Instruction* other) const { return true; } |
| 3407 |
| 3408 DECLARE_INSTRUCTION(UnboxInteger) |
| 3409 |
| 3410 private: |
| 3411 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); |
| 3412 }; |
| 3413 |
| 3414 |
| 3340 class MathSqrtInstr : public TemplateDefinition<1> { | 3415 class MathSqrtInstr : public TemplateDefinition<1> { |
| 3341 public: | 3416 public: |
| 3342 MathSqrtInstr(Value* value, StaticCallInstr* instance_call) { | 3417 MathSqrtInstr(Value* value, StaticCallInstr* instance_call) { |
| 3343 ASSERT(value != NULL); | 3418 ASSERT(value != NULL); |
| 3344 inputs_[0] = value; | 3419 inputs_[0] = value; |
| 3345 deopt_id_ = instance_call->deopt_id(); | 3420 deopt_id_ = instance_call->deopt_id(); |
| 3346 } | 3421 } |
| 3347 | 3422 |
| 3348 Value* value() const { return inputs_[0]; } | 3423 Value* value() const { return inputs_[0]; } |
| 3349 | 3424 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3433 DECLARE_INSTRUCTION(UnboxedDoubleBinaryOp) | 3508 DECLARE_INSTRUCTION(UnboxedDoubleBinaryOp) |
| 3434 virtual RawAbstractType* CompileType() const; | 3509 virtual RawAbstractType* CompileType() const; |
| 3435 | 3510 |
| 3436 private: | 3511 private: |
| 3437 const Token::Kind op_kind_; | 3512 const Token::Kind op_kind_; |
| 3438 | 3513 |
| 3439 DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpInstr); | 3514 DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpInstr); |
| 3440 }; | 3515 }; |
| 3441 | 3516 |
| 3442 | 3517 |
| 3518 class UnboxedMintBinaryOpInstr : public TemplateDefinition<2> { |
| 3519 public: |
| 3520 UnboxedMintBinaryOpInstr(Token::Kind op_kind, |
| 3521 Value* left, |
| 3522 Value* right, |
| 3523 InstanceCallInstr* instance_call) |
| 3524 : op_kind_(op_kind) { |
| 3525 ASSERT(left != NULL); |
| 3526 ASSERT(right != NULL); |
| 3527 inputs_[0] = left; |
| 3528 inputs_[1] = right; |
| 3529 deopt_id_ = instance_call->deopt_id(); |
| 3530 } |
| 3531 |
| 3532 Value* left() const { return inputs_[0]; } |
| 3533 Value* right() const { return inputs_[1]; } |
| 3534 |
| 3535 Token::Kind op_kind() const { return op_kind_; } |
| 3536 |
| 3537 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3538 |
| 3539 virtual bool CanDeoptimize() const { return false; } |
| 3540 |
| 3541 virtual bool HasSideEffect() const { return false; } |
| 3542 |
| 3543 virtual bool AffectedBySideEffect() const { return false; } |
| 3544 |
| 3545 virtual bool AttributesEqual(Instruction* other) const { |
| 3546 return op_kind() == other->AsUnboxedMintBinaryOp()->op_kind(); |
| 3547 } |
| 3548 |
| 3549 virtual intptr_t ResultCid() const; |
| 3550 virtual RawAbstractType* CompileType() const; |
| 3551 |
| 3552 virtual Representation representation() const { |
| 3553 return kUnboxedInteger; |
| 3554 } |
| 3555 |
| 3556 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 3557 ASSERT((idx == 0) || (idx == 1)); |
| 3558 return kUnboxedInteger; |
| 3559 } |
| 3560 |
| 3561 virtual intptr_t DeoptimizationTarget() const { |
| 3562 // Direct access since this instuction cannot deoptimize, and the deopt-id |
| 3563 // was inherited from another instuction that could deoptimize. |
| 3564 return deopt_id_; |
| 3565 } |
| 3566 |
| 3567 DECLARE_INSTRUCTION(UnboxedMintBinaryOp) |
| 3568 |
| 3569 private: |
| 3570 const Token::Kind op_kind_; |
| 3571 |
| 3572 DISALLOW_COPY_AND_ASSIGN(UnboxedMintBinaryOpInstr); |
| 3573 }; |
| 3574 |
| 3575 |
| 3443 class BinarySmiOpInstr : public TemplateDefinition<2> { | 3576 class BinarySmiOpInstr : public TemplateDefinition<2> { |
| 3444 public: | 3577 public: |
| 3445 BinarySmiOpInstr(Token::Kind op_kind, | 3578 BinarySmiOpInstr(Token::Kind op_kind, |
| 3446 InstanceCallInstr* instance_call, | 3579 InstanceCallInstr* instance_call, |
| 3447 Value* left, | 3580 Value* left, |
| 3448 Value* right) | 3581 Value* right) |
| 3449 : op_kind_(op_kind), | 3582 : op_kind_(op_kind), |
| 3450 instance_call_(instance_call), | 3583 instance_call_(instance_call), |
| 3451 overflow_(true) { | 3584 overflow_(true) { |
| 3452 ASSERT(left != NULL); | 3585 ASSERT(left != NULL); |
| 3453 ASSERT(right != NULL); | 3586 ASSERT(right != NULL); |
| 3454 inputs_[0] = left; | 3587 inputs_[0] = left; |
| 3455 inputs_[1] = right; | 3588 inputs_[1] = right; |
| 3456 } | 3589 } |
| 3457 | 3590 |
| 3458 Value* left() const { return inputs_[0]; } | 3591 Value* left() const { return inputs_[0]; } |
| 3459 Value* right() const { return inputs_[1]; } | 3592 Value* right() const { return inputs_[1]; } |
| 3460 | 3593 |
| 3461 Token::Kind op_kind() const { return op_kind_; } | 3594 Token::Kind op_kind() const { return op_kind_; } |
| 3462 | 3595 |
| 3463 InstanceCallInstr* instance_call() const { return instance_call_; } | 3596 InstanceCallInstr* instance_call() const { return instance_call_; } |
| 3464 | 3597 |
| 3465 const ICData* ic_data() const { return instance_call()->ic_data(); } | 3598 const ICData* ic_data() const { return instance_call()->ic_data(); } |
| 3466 | 3599 |
| 3467 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3600 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3468 | 3601 |
| 3469 DECLARE_INSTRUCTION(BinarySmiOp) | 3602 DECLARE_INSTRUCTION(BinarySmiOp) |
| 3603 |
| 3470 virtual RawAbstractType* CompileType() const; | 3604 virtual RawAbstractType* CompileType() const; |
| 3471 | 3605 |
| 3472 virtual bool CanDeoptimize() const; | 3606 virtual bool CanDeoptimize() const; |
| 3473 | 3607 |
| 3474 virtual bool HasSideEffect() const { return false; } | 3608 virtual bool HasSideEffect() const { return false; } |
| 3475 | 3609 |
| 3476 virtual bool AffectedBySideEffect() const { return false; } | 3610 virtual bool AffectedBySideEffect() const { return false; } |
| 3477 virtual bool AttributesEqual(Instruction* other) const; | 3611 virtual bool AttributesEqual(Instruction* other) const; |
| 3478 | 3612 |
| 3479 virtual intptr_t ResultCid() const; | 3613 virtual intptr_t ResultCid() const; |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3965 ForwardInstructionIterator* current_iterator_; | 4099 ForwardInstructionIterator* current_iterator_; |
| 3966 | 4100 |
| 3967 private: | 4101 private: |
| 3968 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 4102 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3969 }; | 4103 }; |
| 3970 | 4104 |
| 3971 | 4105 |
| 3972 } // namespace dart | 4106 } // namespace dart |
| 3973 | 4107 |
| 3974 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 4108 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |