| 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 2691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2702 InstanceCallInstr* instance_call_; | 2702 InstanceCallInstr* instance_call_; |
| 2703 const ICData& ic_data_; | 2703 const ICData& ic_data_; |
| 2704 const bool with_checks_; | 2704 const bool with_checks_; |
| 2705 | 2705 |
| 2706 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); | 2706 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); |
| 2707 }; | 2707 }; |
| 2708 | 2708 |
| 2709 | 2709 |
| 2710 class ComparisonInstr : public TemplateDefinition<2> { | 2710 class ComparisonInstr : public TemplateDefinition<2> { |
| 2711 public: | 2711 public: |
| 2712 ComparisonInstr(Token::Kind kind, Value* left, Value* right) | 2712 ComparisonInstr(intptr_t token_pos, |
| 2713 : kind_(kind) { | 2713 Token::Kind kind, |
| 2714 Value* left, |
| 2715 Value* right) |
| 2716 : token_pos_(token_pos), kind_(kind) { |
| 2714 SetInputAt(0, left); | 2717 SetInputAt(0, left); |
| 2715 SetInputAt(1, right); | 2718 SetInputAt(1, right); |
| 2716 } | 2719 } |
| 2717 | 2720 |
| 2718 Value* left() const { return inputs_[0]; } | 2721 Value* left() const { return inputs_[0]; } |
| 2719 Value* right() const { return inputs_[1]; } | 2722 Value* right() const { return inputs_[1]; } |
| 2720 | 2723 |
| 2721 virtual ComparisonInstr* AsComparison() { return this; } | 2724 virtual ComparisonInstr* AsComparison() { return this; } |
| 2722 | 2725 |
| 2726 intptr_t token_pos() const { return token_pos_; } |
| 2723 Token::Kind kind() const { return kind_; } | 2727 Token::Kind kind() const { return kind_; } |
| 2724 | 2728 |
| 2725 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2729 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2726 BranchInstr* branch) = 0; | 2730 BranchInstr* branch) = 0; |
| 2727 | 2731 |
| 2728 void SetDeoptId(intptr_t deopt_id) { | 2732 void SetDeoptId(intptr_t deopt_id) { |
| 2729 deopt_id_ = deopt_id; | 2733 deopt_id_ = deopt_id; |
| 2730 } | 2734 } |
| 2731 | 2735 |
| 2732 protected: | 2736 protected: |
| 2737 intptr_t token_pos_; |
| 2733 Token::Kind kind_; | 2738 Token::Kind kind_; |
| 2734 }; | 2739 }; |
| 2735 | 2740 |
| 2736 | 2741 |
| 2737 // Inlined functions from class BranchInstr that forward to their comparison. | 2742 // Inlined functions from class BranchInstr that forward to their comparison. |
| 2738 inline intptr_t BranchInstr::ArgumentCount() const { | 2743 inline intptr_t BranchInstr::ArgumentCount() const { |
| 2739 return comparison()->ArgumentCount(); | 2744 return comparison()->ArgumentCount(); |
| 2740 } | 2745 } |
| 2741 | 2746 |
| 2742 | 2747 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 } | 2794 } |
| 2790 | 2795 |
| 2791 | 2796 |
| 2792 inline bool BranchInstr::MayThrow() const { | 2797 inline bool BranchInstr::MayThrow() const { |
| 2793 return comparison()->MayThrow(); | 2798 return comparison()->MayThrow(); |
| 2794 } | 2799 } |
| 2795 | 2800 |
| 2796 | 2801 |
| 2797 class StrictCompareInstr : public ComparisonInstr { | 2802 class StrictCompareInstr : public ComparisonInstr { |
| 2798 public: | 2803 public: |
| 2799 StrictCompareInstr(Token::Kind kind, Value* left, Value* right); | 2804 StrictCompareInstr(intptr_t token_pos, |
| 2805 Token::Kind kind, |
| 2806 Value* left, |
| 2807 Value* right); |
| 2800 | 2808 |
| 2801 DECLARE_INSTRUCTION(StrictCompare) | 2809 DECLARE_INSTRUCTION(StrictCompare) |
| 2802 virtual CompileType ComputeType() const; | 2810 virtual CompileType ComputeType() const; |
| 2803 | 2811 |
| 2804 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2812 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 2805 | 2813 |
| 2806 virtual bool CanBeDeoptimizationTarget() const { | 2814 virtual bool CanBeDeoptimizationTarget() const { |
| 2807 // StrictCompare can be merged into Branch and thus needs an environment. | 2815 // StrictCompare can be merged into Branch and thus needs an environment. |
| 2808 return true; | 2816 return true; |
| 2809 } | 2817 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2835 }; | 2843 }; |
| 2836 | 2844 |
| 2837 | 2845 |
| 2838 class EqualityCompareInstr : public ComparisonInstr { | 2846 class EqualityCompareInstr : public ComparisonInstr { |
| 2839 public: | 2847 public: |
| 2840 EqualityCompareInstr(intptr_t token_pos, | 2848 EqualityCompareInstr(intptr_t token_pos, |
| 2841 Token::Kind kind, | 2849 Token::Kind kind, |
| 2842 Value* left, | 2850 Value* left, |
| 2843 Value* right, | 2851 Value* right, |
| 2844 const Array& ic_data_array) | 2852 const Array& ic_data_array) |
| 2845 : ComparisonInstr(kind, left, right), | 2853 : ComparisonInstr(token_pos, kind, left, right), |
| 2846 ic_data_(GetICData(ic_data_array)), | 2854 ic_data_(GetICData(ic_data_array)), |
| 2847 token_pos_(token_pos), | |
| 2848 receiver_class_id_(kIllegalCid) { | 2855 receiver_class_id_(kIllegalCid) { |
| 2849 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 2856 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 2850 } | 2857 } |
| 2851 | 2858 |
| 2852 DECLARE_INSTRUCTION(EqualityCompare) | 2859 DECLARE_INSTRUCTION(EqualityCompare) |
| 2853 virtual CompileType ComputeType() const; | 2860 virtual CompileType ComputeType() const; |
| 2854 virtual bool RecomputeType(); | 2861 virtual bool RecomputeType(); |
| 2855 | 2862 |
| 2856 const ICData* ic_data() const { return ic_data_; } | 2863 const ICData* ic_data() const { return ic_data_; } |
| 2857 bool HasICData() const { | 2864 bool HasICData() const { |
| 2858 return (ic_data() != NULL) && !ic_data()->IsNull(); | 2865 return (ic_data() != NULL) && !ic_data()->IsNull(); |
| 2859 } | 2866 } |
| 2860 void set_ic_data(const ICData* value) { ic_data_ = value; } | 2867 void set_ic_data(const ICData* value) { ic_data_ = value; } |
| 2861 | 2868 |
| 2862 intptr_t token_pos() const { return token_pos_; } | |
| 2863 | |
| 2864 // Receiver class id is computed from collected ICData. | 2869 // Receiver class id is computed from collected ICData. |
| 2865 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } | 2870 void set_receiver_class_id(intptr_t value) { receiver_class_id_ = value; } |
| 2866 intptr_t receiver_class_id() const { return receiver_class_id_; } | 2871 intptr_t receiver_class_id() const { return receiver_class_id_; } |
| 2867 | 2872 |
| 2868 bool IsInlinedNumericComparison() const { | 2873 bool IsInlinedNumericComparison() const { |
| 2869 return (receiver_class_id() == kDoubleCid) | 2874 return (receiver_class_id() == kDoubleCid) |
| 2870 || (receiver_class_id() == kMintCid) | 2875 || (receiver_class_id() == kMintCid) |
| 2871 || (receiver_class_id() == kSmiCid); | 2876 || (receiver_class_id() == kSmiCid); |
| 2872 } | 2877 } |
| 2873 | 2878 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2900 virtual EffectSet Effects() const { | 2905 virtual EffectSet Effects() const { |
| 2901 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); | 2906 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); |
| 2902 } | 2907 } |
| 2903 | 2908 |
| 2904 virtual bool MayThrow() const { | 2909 virtual bool MayThrow() const { |
| 2905 return !IsInlinedNumericComparison() && !is_checked_strict_equal(); | 2910 return !IsInlinedNumericComparison() && !is_checked_strict_equal(); |
| 2906 } | 2911 } |
| 2907 | 2912 |
| 2908 private: | 2913 private: |
| 2909 const ICData* ic_data_; | 2914 const ICData* ic_data_; |
| 2910 const intptr_t token_pos_; | |
| 2911 intptr_t receiver_class_id_; // Set by optimizer. | 2915 intptr_t receiver_class_id_; // Set by optimizer. |
| 2912 | 2916 |
| 2913 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); | 2917 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); |
| 2914 }; | 2918 }; |
| 2915 | 2919 |
| 2916 | 2920 |
| 2917 class RelationalOpInstr : public ComparisonInstr { | 2921 class RelationalOpInstr : public ComparisonInstr { |
| 2918 public: | 2922 public: |
| 2919 RelationalOpInstr(intptr_t token_pos, | 2923 RelationalOpInstr(intptr_t token_pos, |
| 2920 Token::Kind kind, | 2924 Token::Kind kind, |
| 2921 Value* left, | 2925 Value* left, |
| 2922 Value* right, | 2926 Value* right, |
| 2923 const Array& ic_data_array) | 2927 const Array& ic_data_array) |
| 2924 : ComparisonInstr(kind, left, right), | 2928 : ComparisonInstr(token_pos, kind, left, right), |
| 2925 ic_data_(GetICData(ic_data_array)), | 2929 ic_data_(GetICData(ic_data_array)), |
| 2926 token_pos_(token_pos), | |
| 2927 operands_class_id_(kIllegalCid) { | 2930 operands_class_id_(kIllegalCid) { |
| 2928 ASSERT(Token::IsRelationalOperator(kind)); | 2931 ASSERT(Token::IsRelationalOperator(kind)); |
| 2929 } | 2932 } |
| 2930 | 2933 |
| 2931 DECLARE_INSTRUCTION(RelationalOp) | 2934 DECLARE_INSTRUCTION(RelationalOp) |
| 2932 virtual CompileType ComputeType() const; | 2935 virtual CompileType ComputeType() const; |
| 2933 virtual bool RecomputeType(); | 2936 virtual bool RecomputeType(); |
| 2934 | 2937 |
| 2935 const ICData* ic_data() const { return ic_data_; } | 2938 const ICData* ic_data() const { return ic_data_; } |
| 2936 bool HasICData() const { | 2939 bool HasICData() const { |
| 2937 return (ic_data() != NULL) && !ic_data()->IsNull(); | 2940 return (ic_data() != NULL) && !ic_data()->IsNull(); |
| 2938 } | 2941 } |
| 2939 void set_ic_data(const ICData* value) { ic_data_ = value; } | 2942 void set_ic_data(const ICData* value) { ic_data_ = value; } |
| 2940 | 2943 |
| 2941 intptr_t token_pos() const { return token_pos_; } | |
| 2942 | |
| 2943 // TODO(srdjan): instead of class-id pass an enum that can differentiate | 2944 // TODO(srdjan): instead of class-id pass an enum that can differentiate |
| 2944 // between boxed and unboxed doubles and integers. | 2945 // between boxed and unboxed doubles and integers. |
| 2945 void set_operands_class_id(intptr_t value) { | 2946 void set_operands_class_id(intptr_t value) { |
| 2946 operands_class_id_ = value; | 2947 operands_class_id_ = value; |
| 2947 } | 2948 } |
| 2948 | 2949 |
| 2949 intptr_t operands_class_id() const { return operands_class_id_; } | 2950 intptr_t operands_class_id() const { return operands_class_id_; } |
| 2950 | 2951 |
| 2951 bool IsInlinedNumericComparison() const { | 2952 bool IsInlinedNumericComparison() const { |
| 2952 return (operands_class_id() == kDoubleCid) | 2953 return (operands_class_id() == kDoubleCid) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2976 } | 2977 } |
| 2977 | 2978 |
| 2978 virtual EffectSet Effects() const { | 2979 virtual EffectSet Effects() const { |
| 2979 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); | 2980 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All(); |
| 2980 } | 2981 } |
| 2981 | 2982 |
| 2982 virtual bool MayThrow() const { return !IsInlinedNumericComparison(); } | 2983 virtual bool MayThrow() const { return !IsInlinedNumericComparison(); } |
| 2983 | 2984 |
| 2984 private: | 2985 private: |
| 2985 const ICData* ic_data_; | 2986 const ICData* ic_data_; |
| 2986 const intptr_t token_pos_; | |
| 2987 intptr_t operands_class_id_; // class id of both operands. | 2987 intptr_t operands_class_id_; // class id of both operands. |
| 2988 | 2988 |
| 2989 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); | 2989 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); |
| 2990 }; | 2990 }; |
| 2991 | 2991 |
| 2992 | 2992 |
| 2993 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for | 2993 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for |
| 2994 // materialization of true and false constants. | 2994 // materialization of true and false constants. |
| 2995 class IfThenElseInstr : public TemplateDefinition<2> { | 2995 class IfThenElseInstr : public TemplateDefinition<2> { |
| 2996 public: | 2996 public: |
| (...skipping 3413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6410 ForwardInstructionIterator* current_iterator_; | 6410 ForwardInstructionIterator* current_iterator_; |
| 6411 | 6411 |
| 6412 private: | 6412 private: |
| 6413 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 6413 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 6414 }; | 6414 }; |
| 6415 | 6415 |
| 6416 | 6416 |
| 6417 } // namespace dart | 6417 } // namespace dart |
| 6418 | 6418 |
| 6419 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 6419 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |