Chromium Code Reviews| 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 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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 M(Float64x2OneArg) \ | 549 M(Float64x2OneArg) \ |
| 550 M(ExtractNthOutput) \ | 550 M(ExtractNthOutput) \ |
| 551 M(BinaryUint32Op) \ | 551 M(BinaryUint32Op) \ |
| 552 M(ShiftUint32Op) \ | 552 M(ShiftUint32Op) \ |
| 553 M(UnaryUint32Op) \ | 553 M(UnaryUint32Op) \ |
| 554 M(BoxUint32) \ | 554 M(BoxUint32) \ |
| 555 M(UnboxUint32) \ | 555 M(UnboxUint32) \ |
| 556 M(BoxInt32) \ | 556 M(BoxInt32) \ |
| 557 M(UnboxInt32) \ | 557 M(UnboxInt32) \ |
| 558 M(UnboxedIntConverter) \ | 558 M(UnboxedIntConverter) \ |
| 559 | 559 M(Deoptimize) |
| 560 | 560 |
| 561 #define FORWARD_DECLARATION(type) class type##Instr; | 561 #define FORWARD_DECLARATION(type) class type##Instr; |
| 562 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 562 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 563 #undef FORWARD_DECLARATION | 563 #undef FORWARD_DECLARATION |
| 564 | 564 |
| 565 | 565 |
| 566 // Functions required in all concrete instruction classes. | 566 // Functions required in all concrete instruction classes. |
| 567 #define DECLARE_INSTRUCTION_NO_BACKEND(type) \ | 567 #define DECLARE_INSTRUCTION_NO_BACKEND(type) \ |
| 568 virtual Tag tag() const { return k##type; } \ | 568 virtual Tag tag() const { return k##type; } \ |
| 569 virtual void Accept(FlowGraphVisitor* visitor); \ | 569 virtual void Accept(FlowGraphVisitor* visitor); \ |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 friend class Float64x2SplatInstr; | 866 friend class Float64x2SplatInstr; |
| 867 friend class Float64x2ConstructorInstr; | 867 friend class Float64x2ConstructorInstr; |
| 868 friend class Int32x4ConstructorInstr; | 868 friend class Int32x4ConstructorInstr; |
| 869 friend class Int32x4BoolConstructorInstr; | 869 friend class Int32x4BoolConstructorInstr; |
| 870 friend class Int32x4GetFlagInstr; | 870 friend class Int32x4GetFlagInstr; |
| 871 friend class Int32x4SetFlagInstr; | 871 friend class Int32x4SetFlagInstr; |
| 872 friend class Int32x4SelectInstr; | 872 friend class Int32x4SelectInstr; |
| 873 friend class Int32x4ToFloat32x4Instr; | 873 friend class Int32x4ToFloat32x4Instr; |
| 874 friend class BinaryInt32x4OpInstr; | 874 friend class BinaryInt32x4OpInstr; |
| 875 friend class BinaryFloat64x2OpInstr; | 875 friend class BinaryFloat64x2OpInstr; |
| 876 friend class BinaryMintOpInstr; | |
| 877 friend class BinarySmiOpInstr; | |
| 878 friend class UnarySmiOpInstr; | |
| 879 friend class UnaryDoubleOpInstr; | 876 friend class UnaryDoubleOpInstr; |
| 880 friend class ShiftMintOpInstr; | |
| 881 friend class UnaryMintOpInstr; | |
| 882 friend class MathUnaryInstr; | 877 friend class MathUnaryInstr; |
| 883 friend class MathMinMaxInstr; | 878 friend class MathMinMaxInstr; |
| 884 friend class CheckClassInstr; | 879 friend class CheckClassInstr; |
| 885 friend class CheckClassIdInstr; | 880 friend class CheckClassIdInstr; |
| 886 friend class GuardFieldInstr; | 881 friend class GuardFieldInstr; |
| 887 friend class CheckSmiInstr; | 882 friend class CheckSmiInstr; |
| 888 friend class CheckArrayBoundInstr; | 883 friend class CheckArrayBoundInstr; |
| 889 friend class CheckEitherNonSmiInstr; | 884 friend class CheckEitherNonSmiInstr; |
| 890 friend class LICM; | 885 friend class LICM; |
| 891 friend class DoubleToSmiInstr; | 886 friend class DoubleToSmiInstr; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 903 friend class JoinEntryInstr; | 898 friend class JoinEntryInstr; |
| 904 friend class InstanceOfInstr; | 899 friend class InstanceOfInstr; |
| 905 friend class PolymorphicInstanceCallInstr; | 900 friend class PolymorphicInstanceCallInstr; |
| 906 friend class SmiToDoubleInstr; | 901 friend class SmiToDoubleInstr; |
| 907 friend class DoubleToIntegerInstr; | 902 friend class DoubleToIntegerInstr; |
| 908 friend class BranchSimplifier; | 903 friend class BranchSimplifier; |
| 909 friend class BlockEntryInstr; | 904 friend class BlockEntryInstr; |
| 910 friend class RelationalOpInstr; | 905 friend class RelationalOpInstr; |
| 911 friend class EqualityCompareInstr; | 906 friend class EqualityCompareInstr; |
| 912 friend class TestCidsInstr; | 907 friend class TestCidsInstr; |
| 913 friend class BinaryUint32OpInstr; | |
| 914 friend class UnaryUint32OpInstr; | |
| 915 friend class ShiftUint32OpInstr; | |
| 916 friend class UnboxIntNInstr; | 908 friend class UnboxIntNInstr; |
| 917 friend class UnboxInt32Instr; | 909 friend class UnboxInt32Instr; |
| 918 friend class UnboxUint32Instr; | 910 friend class UnboxUint32Instr; |
| 919 friend class BinaryInt32OpInstr; | |
| 920 friend class UnboxedIntConverterInstr; | 911 friend class UnboxedIntConverterInstr; |
| 912 friend class UnaryIntegerOpInstr; | |
| 913 friend class BinaryIntegerOpInstr; | |
| 914 friend class DeoptimizeInstr; | |
| 921 | 915 |
| 922 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; | 916 virtual void RawSetInputAt(intptr_t i, Value* value) = 0; |
| 923 | 917 |
| 924 enum { | 918 enum { |
| 925 kNoPlaceId = -1 | 919 kNoPlaceId = -1 |
| 926 }; | 920 }; |
| 927 | 921 |
| 928 intptr_t deopt_id_; | 922 intptr_t deopt_id_; |
| 929 intptr_t lifetime_position_; // Position used by register allocator. | 923 intptr_t lifetime_position_; // Position used by register allocator. |
| 930 Instruction* previous_; | 924 Instruction* previous_; |
| (...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2318 | 2312 |
| 2319 virtual EffectSet Effects() const { return EffectSet::None(); } | 2313 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 2320 | 2314 |
| 2321 virtual bool MayThrow() const { return false; } | 2315 virtual bool MayThrow() const { return false; } |
| 2322 | 2316 |
| 2323 private: | 2317 private: |
| 2324 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); | 2318 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); |
| 2325 }; | 2319 }; |
| 2326 | 2320 |
| 2327 | 2321 |
| 2322 class DeoptimizeInstr : public TemplateInstruction<0> { | |
| 2323 public: | |
| 2324 DeoptimizeInstr(ICData::DeoptReasonId deopt_reason, intptr_t deopt_id) | |
| 2325 : deopt_reason_(deopt_reason) { | |
| 2326 deopt_id_ = deopt_id; | |
| 2327 } | |
| 2328 | |
| 2329 virtual intptr_t ArgumentCount() const { return 0; } | |
| 2330 | |
| 2331 virtual bool CanDeoptimize() const { return true; } | |
| 2332 | |
| 2333 virtual bool AllowsCSE() const { return true; } | |
| 2334 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 2335 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 2336 virtual bool AttributesEqual(Instruction* other) const { | |
| 2337 return true; | |
| 2338 } | |
| 2339 | |
| 2340 virtual bool MayThrow() const { return false; } | |
| 2341 | |
| 2342 DECLARE_INSTRUCTION(Deoptimize) | |
| 2343 | |
| 2344 private: | |
| 2345 const ICData::DeoptReasonId deopt_reason_; | |
| 2346 | |
| 2347 DISALLOW_COPY_AND_ASSIGN(DeoptimizeInstr); | |
| 2348 }; | |
| 2349 | |
| 2350 | |
| 2328 class RedefinitionInstr : public TemplateDefinition<1> { | 2351 class RedefinitionInstr : public TemplateDefinition<1> { |
| 2329 public: | 2352 public: |
| 2330 explicit RedefinitionInstr(Value* value) { | 2353 explicit RedefinitionInstr(Value* value) { |
| 2331 SetInputAt(0, value); | 2354 SetInputAt(0, value); |
| 2332 } | 2355 } |
| 2333 | 2356 |
| 2334 DECLARE_INSTRUCTION(Redefinition) | 2357 DECLARE_INSTRUCTION(Redefinition) |
| 2335 | 2358 |
| 2336 Value* value() const { return inputs_[0]; } | 2359 Value* value() const { return inputs_[0]; } |
| 2337 | 2360 |
| (...skipping 4323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6661 | 6684 |
| 6662 virtual bool MayThrow() const { return false; } | 6685 virtual bool MayThrow() const { return false; } |
| 6663 | 6686 |
| 6664 private: | 6687 private: |
| 6665 const Token::Kind op_kind_; | 6688 const Token::Kind op_kind_; |
| 6666 | 6689 |
| 6667 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); | 6690 DISALLOW_COPY_AND_ASSIGN(BinaryFloat64x2OpInstr); |
| 6668 }; | 6691 }; |
| 6669 | 6692 |
| 6670 | 6693 |
| 6671 class BinaryMintOpInstr : public TemplateDefinition<2> { | 6694 class UnaryIntegerOpInstr : public TemplateDefinition<1> { |
| 6672 public: | 6695 public: |
| 6673 BinaryMintOpInstr(Token::Kind op_kind, | 6696 UnaryIntegerOpInstr(Token::Kind op_kind, |
| 6674 Value* left, | 6697 Value* value, |
| 6675 Value* right, | 6698 intptr_t deopt_id) |
| 6676 intptr_t deopt_id) | 6699 : op_kind_(op_kind) { |
| 6677 : op_kind_(op_kind), can_overflow_(true) { | 6700 ASSERT((op_kind == Token::kNEGATE) || |
| 6678 SetInputAt(0, left); | 6701 (op_kind == Token::kBIT_NOT)); |
| 6679 SetInputAt(1, right); | 6702 SetInputAt(0, value); |
| 6680 // Override generated deopt-id. | 6703 // Override generated deopt-id. |
| 6681 deopt_id_ = deopt_id; | 6704 deopt_id_ = deopt_id; |
| 6682 } | 6705 } |
| 6683 | 6706 |
| 6684 Value* left() const { return inputs_[0]; } | 6707 static UnaryIntegerOpInstr* Make(Representation representation, |
| 6685 Value* right() const { return inputs_[1]; } | 6708 Token::Kind op_kind, |
| 6709 Value* value, | |
| 6710 intptr_t deopt_id, | |
| 6711 Range* range); | |
| 6686 | 6712 |
| 6713 Value* value() const { return inputs_[0]; } | |
| 6687 Token::Kind op_kind() const { return op_kind_; } | 6714 Token::Kind op_kind() const { return op_kind_; } |
| 6688 | 6715 |
| 6689 bool can_overflow() const { return can_overflow_; } | 6716 virtual bool AllowsCSE() const { return true; } |
| 6690 void set_can_overflow(bool value) { can_overflow_ = value; } | 6717 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 6691 | 6718 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 6692 virtual void PrintOperandsTo(BufferFormatter* f) const; | 6719 virtual bool AttributesEqual(Instruction* other) const { |
| 6693 | 6720 return static_cast<UnaryIntegerOpInstr*>(other)->op_kind() == op_kind(); |
|
srdjan
2014/09/11 17:38:12
Why static_cast instead of other->AsUnary... ?
Vyacheslav Egorov (Google)
2014/09/11 19:50:47
That would require manually introducing AsUnary...
| |
| 6694 virtual bool CanDeoptimize() const { | |
| 6695 return FLAG_throw_on_javascript_int_overflow | |
| 6696 || (can_overflow() && ((op_kind() == Token::kADD) || | |
| 6697 (op_kind() == Token::kSUB))) | |
| 6698 || (op_kind() == Token::kMUL); // Deopt if inputs are not int32. | |
| 6699 } | |
| 6700 | |
| 6701 virtual Representation representation() const { | |
| 6702 return kUnboxedMint; | |
| 6703 } | |
| 6704 | |
| 6705 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 6706 ASSERT((idx == 0) || (idx == 1)); | |
| 6707 return kUnboxedMint; | |
| 6708 } | 6721 } |
| 6709 | 6722 |
| 6710 virtual intptr_t DeoptimizationTarget() const { | 6723 virtual intptr_t DeoptimizationTarget() const { |
| 6711 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6724 // Direct access since this instruction cannot deoptimize, and the deopt-id |
| 6712 // was inherited from another instruction that could deoptimize. | 6725 // was inherited from another instruction that could deoptimize. |
| 6713 return deopt_id_; | 6726 return deopt_id_; |
| 6714 } | 6727 } |
| 6715 | 6728 |
| 6716 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 6717 | |
| 6718 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
| 6719 | |
| 6720 DECLARE_INSTRUCTION(BinaryMintOp) | |
| 6721 virtual CompileType ComputeType() const; | |
| 6722 | |
| 6723 virtual bool AllowsCSE() const { return true; } | |
| 6724 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 6725 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 6726 virtual bool AttributesEqual(Instruction* other) const { | |
| 6727 ASSERT(other->IsBinaryMintOp()); | |
| 6728 return op_kind() == other->AsBinaryMintOp()->op_kind(); | |
| 6729 } | |
| 6730 | |
| 6731 virtual bool MayThrow() const { return false; } | 6729 virtual bool MayThrow() const { return false; } |
| 6732 | 6730 |
| 6731 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 6732 | |
| 6733 private: | 6733 private: |
| 6734 const Token::Kind op_kind_; | 6734 const Token::Kind op_kind_; |
| 6735 bool can_overflow_; | |
| 6736 | |
| 6737 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); | |
| 6738 }; | 6735 }; |
| 6739 | 6736 |
| 6740 | 6737 |
| 6741 class ShiftMintOpInstr : public TemplateDefinition<2> { | 6738 // Handles both Smi operations: BIT_OR and NEGATE. |
| 6739 class UnarySmiOpInstr : public UnaryIntegerOpInstr { | |
| 6742 public: | 6740 public: |
| 6743 ShiftMintOpInstr(Token::Kind op_kind, | 6741 UnarySmiOpInstr(Token::Kind op_kind, |
| 6744 Value* left, | 6742 Value* value, |
| 6745 Value* right, | 6743 intptr_t deopt_id) |
| 6746 intptr_t deopt_id) | 6744 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { |
| 6747 : op_kind_(op_kind), can_overflow_(true) { | |
| 6748 ASSERT(op_kind == Token::kSHR || op_kind == Token::kSHL); | |
| 6749 SetInputAt(0, left); | |
| 6750 SetInputAt(1, right); | |
| 6751 // Override generated deopt-id. | |
| 6752 deopt_id_ = deopt_id; | |
| 6753 } | 6745 } |
| 6754 | 6746 |
| 6755 Value* left() const { return inputs_[0]; } | 6747 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } |
| 6756 Value* right() const { return inputs_[1]; } | |
| 6757 | 6748 |
| 6758 Token::Kind op_kind() const { return op_kind_; } | 6749 virtual CompileType ComputeType() const; |
| 6759 | 6750 |
| 6760 bool can_overflow() const { return can_overflow_; } | 6751 DECLARE_INSTRUCTION(UnarySmiOp) |
| 6761 void set_can_overflow(bool value) { can_overflow_ = value; } | |
| 6762 | 6752 |
| 6763 virtual void PrintOperandsTo(BufferFormatter* f) const; | 6753 private: |
| 6754 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); | |
| 6755 }; | |
| 6764 | 6756 |
| 6765 bool has_shift_count_check() const; | 6757 |
| 6758 class UnaryUint32OpInstr : public UnaryIntegerOpInstr { | |
| 6759 public: | |
| 6760 UnaryUint32OpInstr(Token::Kind op_kind, | |
| 6761 Value* value, | |
| 6762 intptr_t deopt_id) | |
| 6763 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { | |
| 6764 ASSERT(op_kind == Token::kBIT_NOT); | |
| 6765 } | |
| 6766 | |
| 6767 virtual bool CanDeoptimize() const { return false; } | |
| 6768 | |
| 6769 virtual CompileType ComputeType() const; | |
| 6770 | |
| 6771 virtual Representation representation() const { | |
| 6772 return kUnboxedUint32; | |
| 6773 } | |
| 6774 | |
| 6775 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 6776 ASSERT(idx == 0); | |
| 6777 return kUnboxedUint32; | |
| 6778 } | |
| 6779 | |
| 6780 DECLARE_INSTRUCTION(UnaryUint32Op) | |
| 6781 | |
| 6782 private: | |
| 6783 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | |
| 6784 }; | |
| 6785 | |
| 6786 | |
| 6787 class UnaryMintOpInstr : public UnaryIntegerOpInstr { | |
| 6788 public: | |
| 6789 UnaryMintOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) | |
| 6790 : UnaryIntegerOpInstr(op_kind, value, deopt_id) { | |
| 6791 ASSERT(op_kind == Token::kBIT_NOT); | |
| 6792 } | |
| 6766 | 6793 |
| 6767 virtual bool CanDeoptimize() const { | 6794 virtual bool CanDeoptimize() const { |
| 6768 return FLAG_throw_on_javascript_int_overflow | 6795 return FLAG_throw_on_javascript_int_overflow; |
| 6769 || has_shift_count_check() | |
| 6770 || (can_overflow() && (op_kind() == Token::kSHL)); | |
| 6771 } | 6796 } |
| 6772 | 6797 |
| 6773 virtual CompileType ComputeType() const; | 6798 virtual CompileType ComputeType() const; |
| 6774 | 6799 |
| 6775 virtual Representation representation() const { | 6800 virtual Representation representation() const { |
| 6776 return kUnboxedMint; | 6801 return kUnboxedMint; |
| 6777 } | 6802 } |
| 6778 | |
| 6779 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 6780 ASSERT((idx == 0) || (idx == 1)); | |
| 6781 return (idx == 0) ? kUnboxedMint : kTagged; | |
| 6782 } | |
| 6783 | |
| 6784 virtual intptr_t DeoptimizationTarget() const { | |
| 6785 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
| 6786 // was inherited from another instruction that could deoptimize. | |
| 6787 return deopt_id_; | |
| 6788 } | |
| 6789 | |
| 6790 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 6791 | |
| 6792 DECLARE_INSTRUCTION(ShiftMintOp) | |
| 6793 | |
| 6794 virtual bool AllowsCSE() const { return true; } | |
| 6795 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 6796 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 6797 virtual bool AttributesEqual(Instruction* other) const { | |
| 6798 return op_kind() == other->AsShiftMintOp()->op_kind(); | |
| 6799 } | |
| 6800 | |
| 6801 virtual bool MayThrow() const { return false; } | |
| 6802 | |
| 6803 private: | |
| 6804 const Token::Kind op_kind_; | |
| 6805 bool can_overflow_; | |
| 6806 | |
| 6807 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); | |
| 6808 }; | |
| 6809 | |
| 6810 | |
| 6811 class UnaryMintOpInstr : public TemplateDefinition<1> { | |
| 6812 public: | |
| 6813 UnaryMintOpInstr(Token::Kind op_kind, Value* value, intptr_t deopt_id) | |
| 6814 : op_kind_(op_kind) { | |
| 6815 ASSERT(op_kind == Token::kBIT_NOT); | |
| 6816 SetInputAt(0, value); | |
| 6817 // Override generated deopt-id. | |
| 6818 deopt_id_ = deopt_id; | |
| 6819 } | |
| 6820 | |
| 6821 Value* value() const { return inputs_[0]; } | |
| 6822 | |
| 6823 Token::Kind op_kind() const { return op_kind_; } | |
| 6824 | |
| 6825 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 6826 | |
| 6827 virtual bool CanDeoptimize() const { | |
| 6828 return FLAG_throw_on_javascript_int_overflow; | |
| 6829 } | |
| 6830 | |
| 6831 virtual Representation representation() const { | |
| 6832 return kUnboxedMint; | |
| 6833 } | |
| 6834 | 6803 |
| 6835 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6804 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 6836 ASSERT(idx == 0); | 6805 ASSERT(idx == 0); |
| 6837 return kUnboxedMint; | 6806 return kUnboxedMint; |
| 6838 } | 6807 } |
| 6839 | 6808 |
| 6840 virtual intptr_t DeoptimizationTarget() const { | |
| 6841 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
| 6842 // was inherited from another instruction that could deoptimize. | |
| 6843 return deopt_id_; | |
| 6844 } | |
| 6845 | |
| 6846 DECLARE_INSTRUCTION(UnaryMintOp) | 6809 DECLARE_INSTRUCTION(UnaryMintOp) |
| 6847 virtual CompileType ComputeType() const; | |
| 6848 | |
| 6849 virtual bool AllowsCSE() const { return true; } | |
| 6850 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 6851 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 6852 virtual bool AttributesEqual(Instruction* other) const { | |
| 6853 return op_kind() == other->AsUnaryMintOp()->op_kind(); | |
| 6854 } | |
| 6855 | |
| 6856 virtual bool MayThrow() const { return false; } | |
| 6857 | 6810 |
| 6858 private: | 6811 private: |
| 6859 const Token::Kind op_kind_; | |
| 6860 | |
| 6861 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); | 6812 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); |
| 6862 }; | 6813 }; |
| 6863 | 6814 |
| 6864 | 6815 |
| 6865 class BinarySmiOpInstr : public TemplateDefinition<2> { | 6816 class BinaryIntegerOpInstr : public TemplateDefinition<2> { |
| 6866 public: | 6817 public: |
| 6867 BinarySmiOpInstr(Token::Kind op_kind, | 6818 BinaryIntegerOpInstr(Token::Kind op_kind, |
| 6868 Value* left, | 6819 Value* left, |
| 6869 Value* right, | 6820 Value* right, |
| 6870 intptr_t deopt_id, | 6821 intptr_t deopt_id) |
| 6871 intptr_t token_pos) | |
| 6872 : op_kind_(op_kind), | 6822 : op_kind_(op_kind), |
| 6873 overflow_(true), | 6823 can_overflow_(true), |
| 6874 is_truncating_(false), | |
| 6875 token_pos_(token_pos) { | |
| 6876 SetInputAt(0, left); | |
| 6877 SetInputAt(1, right); | |
| 6878 // Override generated deopt-id. | |
| 6879 deopt_id_ = deopt_id; | |
| 6880 } | |
| 6881 | |
| 6882 Value* left() const { return inputs_[0]; } | |
| 6883 Value* right() const { return inputs_[1]; } | |
| 6884 | |
| 6885 virtual intptr_t token_pos() const { return token_pos_; } | |
| 6886 Token::Kind op_kind() const { return op_kind_; } | |
| 6887 | |
| 6888 void set_overflow(bool overflow) { overflow_ = overflow; } | |
| 6889 | |
| 6890 void set_is_truncating(bool value) { is_truncating_ = value; } | |
| 6891 bool IsTruncating() const { return is_truncating_ || !overflow_; } | |
| 6892 | |
| 6893 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 6894 | |
| 6895 DECLARE_INSTRUCTION(BinarySmiOp) | |
| 6896 virtual CompileType ComputeType() const; | |
| 6897 | |
| 6898 virtual bool CanDeoptimize() const; | |
| 6899 | |
| 6900 virtual bool AllowsCSE() const { return true; } | |
| 6901 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 6902 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 6903 virtual bool AttributesEqual(Instruction* other) const; | |
| 6904 | |
| 6905 void PrintTo(BufferFormatter* f) const; | |
| 6906 | |
| 6907 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 6908 | |
| 6909 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
| 6910 | |
| 6911 // Returns true if right is a non-zero Smi constant which absolute value is | |
| 6912 // a power of two. | |
| 6913 bool RightIsPowerOfTwoConstant() const; | |
| 6914 | |
| 6915 virtual bool MayThrow() const { return false; } | |
| 6916 | |
| 6917 virtual intptr_t DeoptimizationTarget() const { | |
| 6918 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
| 6919 // was inherited from another instruction that could deoptimize. | |
| 6920 return deopt_id_; | |
| 6921 } | |
| 6922 | |
| 6923 private: | |
| 6924 const Token::Kind op_kind_; | |
| 6925 bool overflow_; | |
| 6926 bool is_truncating_; | |
| 6927 const intptr_t token_pos_; | |
| 6928 | |
| 6929 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); | |
| 6930 }; | |
| 6931 | |
| 6932 | |
| 6933 class BinaryInt32OpInstr : public TemplateDefinition<2> { | |
| 6934 public: | |
| 6935 BinaryInt32OpInstr(Token::Kind op_kind, | |
| 6936 Value* left, | |
| 6937 Value* right, | |
| 6938 intptr_t deopt_id) | |
| 6939 : op_kind_(op_kind), | |
| 6940 overflow_(true), | |
| 6941 is_truncating_(false) { | 6824 is_truncating_(false) { |
| 6942 SetInputAt(0, left); | 6825 SetInputAt(0, left); |
| 6943 SetInputAt(1, right); | 6826 SetInputAt(1, right); |
| 6944 // Override generated deopt-id. | 6827 // Override generated deopt-id. |
| 6945 deopt_id_ = deopt_id; | 6828 deopt_id_ = deopt_id; |
| 6946 } | 6829 } |
| 6947 | 6830 |
| 6831 static BinaryIntegerOpInstr* Make(Representation representation, | |
| 6832 Token::Kind op_kind, | |
| 6833 Value* left, | |
| 6834 Value* right, | |
| 6835 intptr_t deopt_id, | |
| 6836 bool can_overflow, | |
| 6837 bool is_truncating, | |
| 6838 Range* range); | |
| 6839 | |
| 6840 Token::Kind op_kind() const { return op_kind_; } | |
| 6841 Value* left() const { return inputs_[0]; } | |
| 6842 Value* right() const { return inputs_[1]; } | |
| 6843 | |
| 6844 bool can_overflow() const { return can_overflow_; } | |
| 6845 void set_can_overflow(bool overflow) { | |
| 6846 ASSERT(!is_truncating_ || !overflow); | |
| 6847 can_overflow_ = overflow; | |
| 6848 } | |
| 6849 | |
| 6850 bool is_truncating() const { return is_truncating_; } | |
| 6851 void mark_truncating() { | |
| 6852 is_truncating_ = true; | |
| 6853 set_can_overflow(false); | |
| 6854 } | |
| 6855 | |
| 6856 // Returns true if right is a non-zero Smi constant which absolute value is | |
| 6857 // a power of two. | |
| 6858 bool RightIsPowerOfTwoConstant() const; | |
| 6859 | |
| 6860 RawInteger* Evaluate(const Integer& left, const Integer& right) const; | |
| 6861 | |
| 6862 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
| 6863 | |
| 6864 virtual bool AllowsCSE() const { return true; } | |
| 6865 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 6866 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 6867 virtual bool AttributesEqual(Instruction* other) const; | |
| 6868 | |
| 6869 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } | |
| 6870 | |
| 6871 virtual bool MayThrow() const { return false; } | |
| 6872 | |
| 6873 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 6874 | |
| 6875 protected: | |
| 6876 void InferRangeHelper(const Range* left_range, | |
| 6877 const Range* right_range, | |
| 6878 Range* range); | |
| 6879 | |
| 6880 private: | |
| 6881 const Token::Kind op_kind_; | |
| 6882 | |
| 6883 bool can_overflow_; | |
| 6884 bool is_truncating_; | |
| 6885 }; | |
| 6886 | |
| 6887 | |
| 6888 class BinarySmiOpInstr : public BinaryIntegerOpInstr { | |
| 6889 public: | |
| 6890 BinarySmiOpInstr(Token::Kind op_kind, | |
| 6891 Value* left, | |
| 6892 Value* right, | |
| 6893 intptr_t deopt_id) | |
| 6894 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | |
| 6895 } | |
| 6896 | |
| 6897 virtual bool CanDeoptimize() const; | |
| 6898 | |
| 6899 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 6900 virtual CompileType ComputeType() const; | |
| 6901 | |
| 6902 DECLARE_INSTRUCTION(BinarySmiOp) | |
| 6903 | |
| 6904 private: | |
| 6905 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); | |
| 6906 }; | |
| 6907 | |
| 6908 | |
| 6909 class BinaryInt32OpInstr : public BinaryIntegerOpInstr { | |
| 6910 public: | |
| 6911 BinaryInt32OpInstr(Token::Kind op_kind, | |
| 6912 Value* left, | |
| 6913 Value* right, | |
| 6914 intptr_t deopt_id) | |
| 6915 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | |
| 6916 SetInputAt(0, left); | |
| 6917 SetInputAt(1, right); | |
| 6918 } | |
| 6919 | |
| 6948 static bool IsSupported(Token::Kind op, Value* left, Value* right) { | 6920 static bool IsSupported(Token::Kind op, Value* left, Value* right) { |
| 6949 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) | 6921 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) |
| 6950 switch (op) { | 6922 switch (op) { |
| 6951 case Token::kADD: | 6923 case Token::kADD: |
| 6952 case Token::kSUB: | 6924 case Token::kSUB: |
| 6953 case Token::kMUL: | 6925 case Token::kMUL: |
| 6954 case Token::kBIT_AND: | 6926 case Token::kBIT_AND: |
| 6955 case Token::kBIT_OR: | 6927 case Token::kBIT_OR: |
| 6956 case Token::kBIT_XOR: | 6928 case Token::kBIT_XOR: |
| 6957 return true; | 6929 return true; |
| 6958 | 6930 |
| 6959 case Token::kSHL: | 6931 case Token::kSHL: |
| 6960 case Token::kSHR: | 6932 case Token::kSHR: |
| 6961 return right->BindsToConstant(); | 6933 return right->BindsToConstant(); |
| 6962 | 6934 |
| 6963 default: | 6935 default: |
| 6964 return false; | 6936 return false; |
| 6965 } | 6937 } |
| 6966 #else | 6938 #else |
| 6967 return false; | 6939 return false; |
| 6968 #endif | 6940 #endif |
| 6969 } | 6941 } |
| 6970 | 6942 |
| 6971 Value* left() const { return inputs_[0]; } | |
| 6972 Value* right() const { return inputs_[1]; } | |
| 6973 | |
| 6974 Token::Kind op_kind() const { return op_kind_; } | |
| 6975 | |
| 6976 void set_overflow(bool overflow) { overflow_ = overflow; } | |
| 6977 | |
| 6978 void set_is_truncating(bool value) { is_truncating_ = value; } | |
| 6979 bool IsTruncating() const { return is_truncating_ || !overflow_; } | |
| 6980 | |
| 6981 void PrintTo(BufferFormatter* f) const; | |
| 6982 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 6983 | |
| 6984 DECLARE_INSTRUCTION(BinaryInt32Op) | |
| 6985 virtual CompileType ComputeType() const; | |
| 6986 | |
| 6987 virtual bool CanDeoptimize() const; | 6943 virtual bool CanDeoptimize() const; |
| 6988 | 6944 |
| 6989 virtual bool AllowsCSE() const { return true; } | |
| 6990 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 6991 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 6992 virtual bool AttributesEqual(Instruction* other) const; | |
| 6993 | |
| 6994 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 6995 | |
| 6996 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
| 6997 | |
| 6998 virtual Representation representation() const { | 6945 virtual Representation representation() const { |
| 6999 return kUnboxedInt32; | 6946 return kUnboxedInt32; |
| 7000 } | 6947 } |
| 7001 | 6948 |
| 7002 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 6949 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 7003 ASSERT((idx == 0) || (idx == 1)); | 6950 ASSERT((idx == 0) || (idx == 1)); |
| 7004 return kUnboxedInt32; | 6951 return kUnboxedInt32; |
| 7005 } | 6952 } |
| 7006 | 6953 |
| 7007 virtual intptr_t DeoptimizationTarget() const { | 6954 virtual void InferRange(RangeAnalysis* analysis, Range* range); |
| 7008 // Direct access since this instruction cannot deoptimize, and the deopt-id | 6955 virtual CompileType ComputeType() const; |
| 7009 // was inherited from another instruction that could deoptimize. | |
| 7010 return deopt_id_; | |
| 7011 } | |
| 7012 | 6956 |
| 7013 virtual bool MayThrow() const { return false; } | 6957 DECLARE_INSTRUCTION(BinaryInt32Op) |
| 7014 | 6958 |
| 7015 private: | 6959 private: |
| 7016 const Token::Kind op_kind_; | |
| 7017 bool overflow_; | |
| 7018 bool is_truncating_; | |
| 7019 | |
| 7020 DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr); | 6960 DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr); |
| 7021 }; | 6961 }; |
| 7022 | 6962 |
| 7023 | 6963 |
| 7024 // Handles both Smi operations: BIT_OR and NEGATE. | 6964 class BinaryUint32OpInstr : public BinaryIntegerOpInstr { |
| 7025 class UnarySmiOpInstr : public TemplateDefinition<1> { | |
| 7026 public: | 6965 public: |
| 7027 UnarySmiOpInstr(Token::Kind op_kind, | 6966 BinaryUint32OpInstr(Token::Kind op_kind, |
| 7028 Value* value, | 6967 Value* left, |
| 7029 intptr_t deopt_id) | 6968 Value* right, |
| 7030 : op_kind_(op_kind) { | 6969 intptr_t deopt_id) |
| 7031 ASSERT((op_kind == Token::kNEGATE) || (op_kind == Token::kBIT_NOT)); | 6970 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { |
| 7032 SetInputAt(0, value); | 6971 mark_truncating(); |
| 7033 // Override generated deopt-id. | |
| 7034 deopt_id_ = deopt_id; | |
| 7035 } | 6972 } |
| 7036 | 6973 |
| 7037 Value* value() const { return inputs_[0]; } | 6974 virtual bool CanDeoptimize() const { |
| 7038 Token::Kind op_kind() const { return op_kind_; } | 6975 return false; |
| 6976 } | |
| 7039 | 6977 |
| 7040 virtual void PrintOperandsTo(BufferFormatter* f) const; | 6978 virtual Representation representation() const { |
| 6979 return kUnboxedUint32; | |
| 6980 } | |
| 7041 | 6981 |
| 7042 DECLARE_INSTRUCTION(UnarySmiOp) | 6982 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 6983 ASSERT((idx == 0) || (idx == 1)); | |
| 6984 return kUnboxedUint32; | |
| 6985 } | |
| 6986 | |
| 7043 virtual CompileType ComputeType() const; | 6987 virtual CompileType ComputeType() const; |
| 7044 | 6988 |
| 7045 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } | 6989 DECLARE_INSTRUCTION(BinaryUint32Op) |
| 7046 | |
| 7047 virtual bool AllowsCSE() const { return true; } | |
| 7048 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 7049 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 7050 virtual bool AttributesEqual(Instruction* other) const { | |
| 7051 return other->AsUnarySmiOp()->op_kind() == op_kind(); | |
| 7052 } | |
| 7053 | |
| 7054 virtual bool MayThrow() const { return false; } | |
| 7055 | 6990 |
| 7056 private: | 6991 private: |
| 7057 const Token::Kind op_kind_; | 6992 DISALLOW_COPY_AND_ASSIGN(BinaryUint32OpInstr); |
| 7058 | |
| 7059 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); | |
| 7060 }; | 6993 }; |
| 7061 | 6994 |
| 7062 | 6995 |
| 6996 class ShiftUint32OpInstr : public BinaryIntegerOpInstr { | |
| 6997 public: | |
| 6998 ShiftUint32OpInstr(Token::Kind op_kind, | |
| 6999 Value* left, | |
| 7000 Value* right, | |
| 7001 intptr_t deopt_id) | |
| 7002 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | |
| 7003 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); | |
| 7004 } | |
| 7005 | |
| 7006 virtual bool CanDeoptimize() const { return true; } | |
| 7007 | |
| 7008 virtual Representation representation() const { | |
| 7009 return kUnboxedUint32; | |
| 7010 } | |
| 7011 | |
| 7012 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 7013 ASSERT((idx == 0) || (idx == 1)); | |
| 7014 return (idx == 0) ? kUnboxedUint32 : kTagged; | |
| 7015 } | |
| 7016 | |
| 7017 virtual CompileType ComputeType() const; | |
| 7018 | |
| 7019 DECLARE_INSTRUCTION(ShiftUint32Op) | |
| 7020 | |
| 7021 private: | |
| 7022 DISALLOW_COPY_AND_ASSIGN(ShiftUint32OpInstr); | |
| 7023 }; | |
| 7024 | |
| 7025 | |
| 7026 class BinaryMintOpInstr : public BinaryIntegerOpInstr { | |
| 7027 public: | |
| 7028 BinaryMintOpInstr(Token::Kind op_kind, | |
| 7029 Value* left, | |
| 7030 Value* right, | |
| 7031 intptr_t deopt_id) | |
| 7032 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | |
| 7033 } | |
| 7034 | |
| 7035 virtual bool CanDeoptimize() const { | |
| 7036 return FLAG_throw_on_javascript_int_overflow | |
| 7037 || (can_overflow() && ((op_kind() == Token::kADD) || | |
| 7038 (op_kind() == Token::kSUB))) | |
| 7039 || (op_kind() == Token::kMUL); // Deopt if inputs are not int32. | |
| 7040 } | |
| 7041 | |
| 7042 virtual Representation representation() const { | |
| 7043 return kUnboxedMint; | |
| 7044 } | |
| 7045 | |
| 7046 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 7047 ASSERT((idx == 0) || (idx == 1)); | |
| 7048 return kUnboxedMint; | |
| 7049 } | |
| 7050 | |
| 7051 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 7052 virtual CompileType ComputeType() const; | |
| 7053 | |
| 7054 DECLARE_INSTRUCTION(BinaryMintOp) | |
| 7055 | |
| 7056 private: | |
| 7057 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); | |
| 7058 }; | |
| 7059 | |
| 7060 | |
| 7061 class ShiftMintOpInstr : public BinaryIntegerOpInstr { | |
| 7062 public: | |
| 7063 ShiftMintOpInstr(Token::Kind op_kind, | |
| 7064 Value* left, | |
| 7065 Value* right, | |
| 7066 intptr_t deopt_id) | |
| 7067 : BinaryIntegerOpInstr(op_kind, left, right, deopt_id) { | |
| 7068 ASSERT((op_kind == Token::kSHR) || (op_kind == Token::kSHL)); | |
| 7069 } | |
| 7070 | |
| 7071 virtual bool CanDeoptimize() const { | |
| 7072 return FLAG_throw_on_javascript_int_overflow | |
| 7073 || has_shift_count_check() | |
| 7074 || (can_overflow() && (op_kind() == Token::kSHL)); | |
| 7075 } | |
| 7076 | |
| 7077 virtual Representation representation() const { | |
| 7078 return kUnboxedMint; | |
| 7079 } | |
| 7080 | |
| 7081 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 7082 ASSERT((idx == 0) || (idx == 1)); | |
| 7083 return (idx == 0) ? kUnboxedMint : kTagged; | |
| 7084 } | |
| 7085 | |
| 7086 virtual void InferRange(RangeAnalysis* analysis, Range* range); | |
| 7087 virtual CompileType ComputeType() const; | |
| 7088 | |
| 7089 DECLARE_INSTRUCTION(ShiftMintOp) | |
| 7090 | |
| 7091 private: | |
| 7092 bool has_shift_count_check() const; | |
| 7093 | |
| 7094 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); | |
| 7095 }; | |
| 7096 | |
| 7097 | |
| 7063 // Handles only NEGATE. | 7098 // Handles only NEGATE. |
| 7064 class UnaryDoubleOpInstr : public TemplateDefinition<1> { | 7099 class UnaryDoubleOpInstr : public TemplateDefinition<1> { |
| 7065 public: | 7100 public: |
| 7066 UnaryDoubleOpInstr(Token::Kind op_kind, | 7101 UnaryDoubleOpInstr(Token::Kind op_kind, |
| 7067 Value* value, | 7102 Value* value, |
| 7068 intptr_t deopt_id) | 7103 intptr_t deopt_id) |
| 7069 : op_kind_(op_kind) { | 7104 : op_kind_(op_kind) { |
| 7070 ASSERT(op_kind == Token::kNEGATE); | 7105 ASSERT(op_kind == Token::kNEGATE); |
| 7071 SetInputAt(0, value); | 7106 SetInputAt(0, value); |
| 7072 // Overriden generated deopt_id. | 7107 // Overriden generated deopt_id. |
| (...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7785 enum { | 7820 enum { |
| 7786 kLengthPos = 0, | 7821 kLengthPos = 0, |
| 7787 kIndexPos = 1 | 7822 kIndexPos = 1 |
| 7788 }; | 7823 }; |
| 7789 | 7824 |
| 7790 private: | 7825 private: |
| 7791 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); | 7826 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); |
| 7792 }; | 7827 }; |
| 7793 | 7828 |
| 7794 | 7829 |
| 7795 class BinaryUint32OpInstr : public TemplateDefinition<2> { | |
| 7796 public: | |
| 7797 BinaryUint32OpInstr(Token::Kind op_kind, | |
| 7798 Value* left, | |
| 7799 Value* right, | |
| 7800 intptr_t deopt_id) | |
| 7801 : op_kind_(op_kind) { | |
| 7802 SetInputAt(0, left); | |
| 7803 SetInputAt(1, right); | |
| 7804 // Override generated deopt-id. | |
| 7805 deopt_id_ = deopt_id; | |
| 7806 } | |
| 7807 | |
| 7808 Value* left() const { return inputs_[0]; } | |
| 7809 Value* right() const { return inputs_[1]; } | |
| 7810 | |
| 7811 Token::Kind op_kind() const { return op_kind_; } | |
| 7812 | |
| 7813 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 7814 | |
| 7815 virtual bool CanDeoptimize() const { | |
| 7816 return false; | |
| 7817 } | |
| 7818 | |
| 7819 virtual Representation representation() const { | |
| 7820 return kUnboxedUint32; | |
| 7821 } | |
| 7822 | |
| 7823 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 7824 ASSERT((idx == 0) || (idx == 1)); | |
| 7825 return kUnboxedUint32; | |
| 7826 } | |
| 7827 | |
| 7828 virtual intptr_t DeoptimizationTarget() const { | |
| 7829 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
| 7830 // was inherited from another instruction that could deoptimize. | |
| 7831 return deopt_id_; | |
| 7832 } | |
| 7833 | |
| 7834 virtual Definition* Canonicalize(FlowGraph* flow_graph); | |
| 7835 | |
| 7836 DECLARE_INSTRUCTION(BinaryUint32Op) | |
| 7837 virtual CompileType ComputeType() const; | |
| 7838 | |
| 7839 virtual bool AllowsCSE() const { return true; } | |
| 7840 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 7841 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 7842 virtual bool AttributesEqual(Instruction* other) const { | |
| 7843 ASSERT(other->IsBinaryUint32Op()); | |
| 7844 return op_kind() == other->AsBinaryUint32Op()->op_kind(); | |
| 7845 } | |
| 7846 | |
| 7847 virtual bool MayThrow() const { return false; } | |
| 7848 | |
| 7849 private: | |
| 7850 const Token::Kind op_kind_; | |
| 7851 | |
| 7852 DISALLOW_COPY_AND_ASSIGN(BinaryUint32OpInstr); | |
| 7853 }; | |
| 7854 | |
| 7855 | |
| 7856 class ShiftUint32OpInstr : public TemplateDefinition<2> { | |
| 7857 public: | |
| 7858 ShiftUint32OpInstr(Token::Kind op_kind, | |
| 7859 Value* left, | |
| 7860 Value* right, | |
| 7861 intptr_t deopt_id) | |
| 7862 : op_kind_(op_kind) { | |
| 7863 ASSERT(op_kind == Token::kSHR || op_kind == Token::kSHL); | |
| 7864 SetInputAt(0, left); | |
| 7865 SetInputAt(1, right); | |
| 7866 // Override generated deopt-id. | |
| 7867 deopt_id_ = deopt_id; | |
| 7868 } | |
| 7869 | |
| 7870 Value* left() const { return inputs_[0]; } | |
| 7871 Value* right() const { return inputs_[1]; } | |
| 7872 | |
| 7873 Token::Kind op_kind() const { return op_kind_; } | |
| 7874 | |
| 7875 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 7876 | |
| 7877 virtual bool CanDeoptimize() const { | |
| 7878 return true; | |
| 7879 } | |
| 7880 | |
| 7881 virtual CompileType ComputeType() const; | |
| 7882 | |
| 7883 virtual Representation representation() const { | |
| 7884 return kUnboxedUint32; | |
| 7885 } | |
| 7886 | |
| 7887 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 7888 ASSERT((idx == 0) || (idx == 1)); | |
| 7889 return (idx == 0) ? kUnboxedUint32 : kTagged; | |
| 7890 } | |
| 7891 | |
| 7892 virtual intptr_t DeoptimizationTarget() const { | |
| 7893 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
| 7894 // was inherited from another instruction that could deoptimize. | |
| 7895 return deopt_id_; | |
| 7896 } | |
| 7897 | |
| 7898 DECLARE_INSTRUCTION(ShiftUint32Op) | |
| 7899 | |
| 7900 virtual bool AllowsCSE() const { return true; } | |
| 7901 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 7902 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 7903 virtual bool AttributesEqual(Instruction* other) const { | |
| 7904 return op_kind() == other->AsShiftUint32Op()->op_kind(); | |
| 7905 } | |
| 7906 | |
| 7907 virtual bool MayThrow() const { return false; } | |
| 7908 | |
| 7909 private: | |
| 7910 const Token::Kind op_kind_; | |
| 7911 | |
| 7912 DISALLOW_COPY_AND_ASSIGN(ShiftUint32OpInstr); | |
| 7913 }; | |
| 7914 | |
| 7915 | |
| 7916 class UnaryUint32OpInstr : public TemplateDefinition<1> { | |
| 7917 public: | |
| 7918 UnaryUint32OpInstr(Token::Kind op_kind, | |
| 7919 Value* value, | |
| 7920 intptr_t deopt_id) | |
| 7921 : op_kind_(op_kind) { | |
| 7922 ASSERT(op_kind == Token::kBIT_NOT); | |
| 7923 SetInputAt(0, value); | |
| 7924 // Override generated deopt-id. | |
| 7925 deopt_id_ = deopt_id; | |
| 7926 } | |
| 7927 | |
| 7928 Value* value() const { return inputs_[0]; } | |
| 7929 | |
| 7930 Token::Kind op_kind() const { return op_kind_; } | |
| 7931 | |
| 7932 virtual void PrintOperandsTo(BufferFormatter* f) const; | |
| 7933 | |
| 7934 virtual bool CanDeoptimize() const { | |
| 7935 return false; | |
| 7936 } | |
| 7937 | |
| 7938 virtual Representation representation() const { | |
| 7939 return kUnboxedUint32; | |
| 7940 } | |
| 7941 | |
| 7942 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | |
| 7943 ASSERT(idx == 0); | |
| 7944 return kUnboxedUint32; | |
| 7945 } | |
| 7946 | |
| 7947 virtual intptr_t DeoptimizationTarget() const { | |
| 7948 // Direct access since this instruction cannot deoptimize, and the deopt-id | |
| 7949 // was inherited from another instruction that could deoptimize. | |
| 7950 return deopt_id_; | |
| 7951 } | |
| 7952 | |
| 7953 DECLARE_INSTRUCTION(UnaryUint32Op) | |
| 7954 virtual CompileType ComputeType() const; | |
| 7955 | |
| 7956 virtual bool AllowsCSE() const { return true; } | |
| 7957 virtual EffectSet Effects() const { return EffectSet::None(); } | |
| 7958 virtual EffectSet Dependencies() const { return EffectSet::None(); } | |
| 7959 virtual bool AttributesEqual(Instruction* other) const { | |
| 7960 return op_kind() == other->AsUnaryUint32Op()->op_kind(); | |
| 7961 } | |
| 7962 | |
| 7963 virtual bool MayThrow() const { return false; } | |
| 7964 | |
| 7965 private: | |
| 7966 const Token::Kind op_kind_; | |
| 7967 | |
| 7968 DISALLOW_COPY_AND_ASSIGN(UnaryUint32OpInstr); | |
| 7969 }; | |
| 7970 | |
| 7971 | |
| 7972 class BoxIntNInstr : public TemplateDefinition<1> { | 7830 class BoxIntNInstr : public TemplateDefinition<1> { |
| 7973 public: | 7831 public: |
| 7974 BoxIntNInstr(Representation representation, Value* value) | 7832 BoxIntNInstr(Representation representation, Value* value) |
| 7975 : from_representation_(representation) { | 7833 : from_representation_(representation) { |
| 7976 SetInputAt(0, value); | 7834 SetInputAt(0, value); |
| 7977 } | 7835 } |
| 7978 | 7836 |
| 7979 Representation from_representation() const { return from_representation_; } | 7837 Representation from_representation() const { return from_representation_; } |
| 7980 | 7838 |
| 7981 Value* value() const { return inputs_[0]; } | 7839 Value* value() const { return inputs_[0]; } |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8432 Isolate* isolate, bool opt) const { \ | 8290 Isolate* isolate, bool opt) const { \ |
| 8433 UNIMPLEMENTED(); \ | 8291 UNIMPLEMENTED(); \ |
| 8434 return NULL; \ | 8292 return NULL; \ |
| 8435 } \ | 8293 } \ |
| 8436 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } | 8294 void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); } |
| 8437 | 8295 |
| 8438 | 8296 |
| 8439 } // namespace dart | 8297 } // namespace dart |
| 8440 | 8298 |
| 8441 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 8299 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |