| 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 2679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2690 InstanceCallInstr* instance_call_; | 2690 InstanceCallInstr* instance_call_; |
| 2691 const ICData& ic_data_; | 2691 const ICData& ic_data_; |
| 2692 const bool with_checks_; | 2692 const bool with_checks_; |
| 2693 | 2693 |
| 2694 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 2694 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
| 2695 }; | 2695 }; |
| 2696 | 2696 |
| 2697 | 2697 |
| 2698 class ComparisonInstr : public TemplateDefinition<2> { | 2698 class ComparisonInstr : public TemplateDefinition<2> { |
| 2699 public: | 2699 public: |
| 2700 ComparisonInstr(intptr_t token_pos, | |
| 2701 Token::Kind kind, | |
| 2702 Value* left, | |
| 2703 Value* right) | |
| 2704 : token_pos_(token_pos), kind_(kind) { | |
| 2705 SetInputAt(0, left); | |
| 2706 SetInputAt(1, right); | |
| 2707 } | |
| 2708 | |
| 2709 Value* left() const { return inputs_[0]; } | 2700 Value* left() const { return inputs_[0]; } |
| 2710 Value* right() const { return inputs_[1]; } | 2701 Value* right() const { return inputs_[1]; } |
| 2711 | 2702 |
| 2712 virtual ComparisonInstr* AsComparison() { return this; } | 2703 virtual ComparisonInstr* AsComparison() { return this; } |
| 2713 | 2704 |
| 2714 intptr_t token_pos() const { return token_pos_; } | 2705 intptr_t token_pos() const { return token_pos_; } |
| 2715 Token::Kind kind() const { return kind_; } | 2706 Token::Kind kind() const { return kind_; } |
| 2716 | 2707 |
| 2717 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2708 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2718 BranchInstr* branch) = 0; | 2709 BranchInstr* branch) = 0; |
| 2719 | 2710 |
| 2720 void SetDeoptId(intptr_t deopt_id) { | 2711 void SetDeoptId(intptr_t deopt_id) { |
| 2721 deopt_id_ = deopt_id; | 2712 deopt_id_ = deopt_id; |
| 2722 } | 2713 } |
| 2723 | 2714 |
| 2715 // Operation class id is computed from collected ICData. |
| 2716 void set_operation_cid(intptr_t value) { operation_cid_ = value; } |
| 2717 intptr_t operation_cid() const { return operation_cid_; } |
| 2718 |
| 2724 protected: | 2719 protected: |
| 2720 ComparisonInstr(intptr_t token_pos, |
| 2721 Token::Kind kind, |
| 2722 Value* left, |
| 2723 Value* right) |
| 2724 : token_pos_(token_pos), kind_(kind), operation_cid_(kIllegalCid) { |
| 2725 SetInputAt(0, left); |
| 2726 SetInputAt(1, right); |
| 2727 } |
| 2728 |
| 2725 intptr_t token_pos_; | 2729 intptr_t token_pos_; |
| 2726 Token::Kind kind_; | 2730 Token::Kind kind_; |
| 2731 |
| 2732 private: |
| 2733 intptr_t operation_cid_; // Set by optimizer. |
| 2734 |
| 2735 DISALLOW_COPY_AND_ASSIGN(ComparisonInstr); |
| 2727 }; | 2736 }; |
| 2728 | 2737 |
| 2729 | 2738 |
| 2730 // Inlined functions from class BranchInstr that forward to their comparison. | 2739 // Inlined functions from class BranchInstr that forward to their comparison. |
| 2731 inline intptr_t BranchInstr::ArgumentCount() const { | 2740 inline intptr_t BranchInstr::ArgumentCount() const { |
| 2732 return comparison()->ArgumentCount(); | 2741 return comparison()->ArgumentCount(); |
| 2733 } | 2742 } |
| 2734 | 2743 |
| 2735 | 2744 |
| 2736 inline intptr_t BranchInstr::InputCount() const { | 2745 inline intptr_t BranchInstr::InputCount() const { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2833 | 2842 |
| 2834 class EqualityCompareInstr : public ComparisonInstr { | 2843 class EqualityCompareInstr : public ComparisonInstr { |
| 2835 public: | 2844 public: |
| 2836 EqualityCompareInstr(intptr_t token_pos, | 2845 EqualityCompareInstr(intptr_t token_pos, |
| 2837 Token::Kind kind, | 2846 Token::Kind kind, |
| 2838 Value* left, | 2847 Value* left, |
| 2839 Value* right, | 2848 Value* right, |
| 2840 const Array& ic_data_array) | 2849 const Array& ic_data_array) |
| 2841 : ComparisonInstr(token_pos, kind, left, right), | 2850 : ComparisonInstr(token_pos, kind, left, right), |
| 2842 ic_data_(GetICData(ic_data_array)), | 2851 ic_data_(GetICData(ic_data_array)), |
| 2843 unary_ic_data_(NULL), | 2852 unary_ic_data_(NULL) { |
| 2844 receiver_class_id_(kIllegalCid) { | |
| 2845 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 2853 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 2846 if (HasICData()) { | 2854 if (HasICData()) { |
| 2847 unary_ic_data_ = &ICData::ZoneHandle(ic_data_->AsUnaryClassChecks()); | 2855 unary_ic_data_ = &ICData::ZoneHandle(ic_data_->AsUnaryClassChecks()); |
| 2848 } | 2856 } |
| 2849 } | 2857 } |
| 2850 | 2858 |
| 2851 DECLARE_INSTRUCTION(EqualityCompare) | 2859 DECLARE_INSTRUCTION(EqualityCompare) |
| 2852 virtual CompileType ComputeType() const; | 2860 virtual CompileType ComputeType() const; |
| 2853 virtual bool RecomputeType(); | 2861 virtual bool RecomputeType(); |
| 2854 | 2862 |
| 2855 const ICData* ic_data() const { return ic_data_; } | 2863 const ICData* ic_data() const { return ic_data_; } |
| 2856 bool HasICData() const { | 2864 bool HasICData() const { |
| 2857 return (ic_data() != NULL) && !ic_data()->IsNull(); | 2865 return (ic_data() != NULL) && !ic_data()->IsNull(); |
| 2858 } | 2866 } |
| 2859 void set_ic_data(const ICData* value) { | 2867 void set_ic_data(const ICData* value) { |
| 2860 ic_data_ = value; | 2868 ic_data_ = value; |
| 2861 if (HasICData()) { | 2869 if (HasICData()) { |
| 2862 unary_ic_data_ = &ICData::ZoneHandle(ic_data_->AsUnaryClassChecks()); | 2870 unary_ic_data_ = &ICData::ZoneHandle(ic_data_->AsUnaryClassChecks()); |
| 2863 } | 2871 } |
| 2864 } | 2872 } |
| 2865 | 2873 |
| 2866 // Receiver class id is computed from collected ICData. | |
| 2867 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } | |
| 2868 intptr_t receiver_class_id() const { return receiver_class_id_; } | |
| 2869 | |
| 2870 bool IsInlinedNumericComparison() const { | 2874 bool IsInlinedNumericComparison() const { |
| 2871 return (receiver_class_id() == kDoubleCid) | 2875 return (operation_cid() == kDoubleCid) |
| 2872 || (receiver_class_id() == kMintCid) | 2876 || (operation_cid() == kMintCid) |
| 2873 || (receiver_class_id() == kSmiCid); | 2877 || (operation_cid() == kSmiCid); |
| 2874 } | 2878 } |
| 2875 | 2879 |
| 2876 bool IsCheckedStrictEqual() const; | 2880 bool IsCheckedStrictEqual() const; |
| 2877 | 2881 |
| 2878 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2882 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 2879 | 2883 |
| 2880 virtual bool CanDeoptimize() const { | 2884 virtual bool CanDeoptimize() const { |
| 2881 return !IsInlinedNumericComparison(); | 2885 return !IsInlinedNumericComparison(); |
| 2882 } | 2886 } |
| 2883 | 2887 |
| 2884 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2888 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2885 BranchInstr* branch); | 2889 BranchInstr* branch); |
| 2886 | 2890 |
| 2887 virtual intptr_t DeoptimizationTarget() const { | 2891 virtual intptr_t DeoptimizationTarget() const { |
| 2888 return GetDeoptId(); | 2892 return GetDeoptId(); |
| 2889 } | 2893 } |
| 2890 | 2894 |
| 2891 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2895 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 2892 ASSERT((idx == 0) || (idx == 1)); | 2896 ASSERT((idx == 0) || (idx == 1)); |
| 2893 if (receiver_class_id() == kDoubleCid) return kUnboxedDouble; | 2897 if (operation_cid() == kDoubleCid) return kUnboxedDouble; |
| 2894 if (receiver_class_id() == kMintCid) return kUnboxedMint; | 2898 if (operation_cid() == kMintCid) return kUnboxedMint; |
| 2895 return kTagged; | 2899 return kTagged; |
| 2896 } | 2900 } |
| 2897 | 2901 |
| 2898 bool IsPolymorphic() const; | 2902 bool IsPolymorphic() const; |
| 2899 | 2903 |
| 2900 virtual EffectSet Effects() const { | 2904 virtual EffectSet Effects() const { |
| 2901 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); | 2905 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); |
| 2902 } | 2906 } |
| 2903 | 2907 |
| 2904 virtual bool MayThrow() const { | 2908 virtual bool MayThrow() const { |
| 2905 return !IsInlinedNumericComparison() && !IsCheckedStrictEqual(); | 2909 return !IsInlinedNumericComparison() && !IsCheckedStrictEqual(); |
| 2906 } | 2910 } |
| 2907 | 2911 |
| 2908 private: | 2912 private: |
| 2909 const ICData* ic_data_; | 2913 const ICData* ic_data_; |
| 2910 ICData* unary_ic_data_; | 2914 ICData* unary_ic_data_; |
| 2911 intptr_t receiver_class_id_; // Set by optimizer. | |
| 2912 | 2915 |
| 2913 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); | 2916 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); |
| 2914 }; | 2917 }; |
| 2915 | 2918 |
| 2916 | 2919 |
| 2917 class RelationalOpInstr : public ComparisonInstr { | 2920 class RelationalOpInstr : public ComparisonInstr { |
| 2918 public: | 2921 public: |
| 2919 RelationalOpInstr(intptr_t token_pos, | 2922 RelationalOpInstr(intptr_t token_pos, |
| 2920 Token::Kind kind, | 2923 Token::Kind kind, |
| 2921 Value* left, | 2924 Value* left, |
| 2922 Value* right, | 2925 Value* right, |
| 2923 const Array& ic_data_array) | 2926 const Array& ic_data_array) |
| 2924 : ComparisonInstr(token_pos, kind, left, right), | 2927 : ComparisonInstr(token_pos, kind, left, right), |
| 2925 ic_data_(GetICData(ic_data_array)), | 2928 ic_data_(GetICData(ic_data_array)) { |
| 2926 operands_class_id_(kIllegalCid) { | |
| 2927 ASSERT(Token::IsRelationalOperator(kind)); | 2929 ASSERT(Token::IsRelationalOperator(kind)); |
| 2928 } | 2930 } |
| 2929 | 2931 |
| 2930 DECLARE_INSTRUCTION(RelationalOp) | 2932 DECLARE_INSTRUCTION(RelationalOp) |
| 2931 virtual CompileType ComputeType() const; | 2933 virtual CompileType ComputeType() const; |
| 2932 virtual bool RecomputeType(); | 2934 virtual bool RecomputeType(); |
| 2933 | 2935 |
| 2934 const ICData* ic_data() const { return ic_data_; } | 2936 const ICData* ic_data() const { return ic_data_; } |
| 2935 bool HasICData() const { | 2937 bool HasICData() const { |
| 2936 return (ic_data() != NULL) && !ic_data()->IsNull(); | 2938 return (ic_data() != NULL) && !ic_data()->IsNull(); |
| 2937 } | 2939 } |
| 2938 void set_ic_data(const ICData* value) { ic_data_ = value; } | 2940 void set_ic_data(const ICData* value) { ic_data_ = value; } |
| 2939 | 2941 |
| 2940 // TODO(srdjan): instead of class-id pass an enum that can differentiate | |
| 2941 // between boxed and unboxed doubles and integers. | |
| 2942 void set_operands_class_id(intptr_t value) { | |
| 2943 operands_class_id_ = value; | |
| 2944 } | |
| 2945 | |
| 2946 intptr_t operands_class_id() const { return operands_class_id_; } | |
| 2947 | |
| 2948 bool IsInlinedNumericComparison() const { | 2942 bool IsInlinedNumericComparison() const { |
| 2949 return (operands_class_id() == kDoubleCid) | 2943 return (operation_cid() == kDoubleCid) |
| 2950 || (operands_class_id() == kMintCid) | 2944 || (operation_cid() == kMintCid) |
| 2951 || (operands_class_id() == kSmiCid); | 2945 || (operation_cid() == kSmiCid); |
| 2952 } | 2946 } |
| 2953 | 2947 |
| 2954 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2948 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 2955 | 2949 |
| 2956 virtual bool CanDeoptimize() const { | 2950 virtual bool CanDeoptimize() const { |
| 2957 return !IsInlinedNumericComparison(); | 2951 return !IsInlinedNumericComparison(); |
| 2958 } | 2952 } |
| 2959 | 2953 |
| 2960 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2954 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2961 BranchInstr* branch); | 2955 BranchInstr* branch); |
| 2962 | 2956 |
| 2963 | 2957 |
| 2964 virtual intptr_t DeoptimizationTarget() const { | 2958 virtual intptr_t DeoptimizationTarget() const { |
| 2965 return GetDeoptId(); | 2959 return GetDeoptId(); |
| 2966 } | 2960 } |
| 2967 | 2961 |
| 2968 virtual Representation RequiredInputRepresentation(intptr_t idx) const { | 2962 virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
| 2969 ASSERT((idx == 0) || (idx == 1)); | 2963 ASSERT((idx == 0) || (idx == 1)); |
| 2970 if (operands_class_id() == kDoubleCid) return kUnboxedDouble; | 2964 if (operation_cid() == kDoubleCid) return kUnboxedDouble; |
| 2971 if (operands_class_id() == kMintCid) return kUnboxedMint; | 2965 if (operation_cid() == kMintCid) return kUnboxedMint; |
| 2972 return kTagged; | 2966 return kTagged; |
| 2973 } | 2967 } |
| 2974 | 2968 |
| 2975 virtual EffectSet Effects() const { | 2969 virtual EffectSet Effects() const { |
| 2976 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); | 2970 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); |
| 2977 } | 2971 } |
| 2978 | 2972 |
| 2979 virtual bool MayThrow() const { return !IsInlinedNumericComparison(); } | 2973 virtual bool MayThrow() const { return !IsInlinedNumericComparison(); } |
| 2980 | 2974 |
| 2981 private: | 2975 private: |
| 2982 const ICData* ic_data_; | 2976 const ICData* ic_data_; |
| 2983 intptr_t operands_class_id_; // class id of both operands. | |
| 2984 | 2977 |
| 2985 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); | 2978 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); |
| 2986 }; | 2979 }; |
| 2987 | 2980 |
| 2988 | 2981 |
| 2989 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for | 2982 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for |
| 2990 // materialization of true and false constants. | 2983 // materialization of true and false constants. |
| 2991 class IfThenElseInstr : public TemplateDefinition<2> { | 2984 class IfThenElseInstr : public TemplateDefinition<2> { |
| 2992 public: | 2985 public: |
| 2993 IfThenElseInstr(Token::Kind kind, | 2986 IfThenElseInstr(Token::Kind kind, |
| (...skipping 3567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6561 ForwardInstructionIterator* current_iterator_; | 6554 ForwardInstructionIterator* current_iterator_; |
| 6562 | 6555 |
| 6563 private: | 6556 private: |
| 6564 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 6557 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 6565 }; | 6558 }; |
| 6566 | 6559 |
| 6567 | 6560 |
| 6568 } // namespace dart | 6561 } // namespace dart |
| 6569 | 6562 |
| 6570 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 6563 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |