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