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

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

Issue 564843002: Initial steps towards cleaning up integer arithmetic IR. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #ifndef 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
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
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
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698