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

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

Issue 20468002: Allow equality operation on mixed double/smi arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2679 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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_
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/intermediate_language_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698