| 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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) | 704 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
| 705 #undef FORWARD_DECLARATION | 705 #undef FORWARD_DECLARATION |
| 706 | 706 |
| 707 | 707 |
| 708 // Functions required in all concrete instruction classes. | 708 // Functions required in all concrete instruction classes. |
| 709 #define DECLARE_INSTRUCTION(type) \ | 709 #define DECLARE_INSTRUCTION(type) \ |
| 710 virtual Tag tag() const { return k##type; } \ | 710 virtual Tag tag() const { return k##type; } \ |
| 711 virtual void Accept(FlowGraphVisitor* visitor); \ | 711 virtual void Accept(FlowGraphVisitor* visitor); \ |
| 712 virtual type##Instr* As##type() { return this; } \ | 712 virtual type##Instr* As##type() { return this; } \ |
| 713 virtual const char* DebugName() const { return #type; } \ | 713 virtual const char* DebugName() const { return #type; } \ |
| 714 virtual LocationSummary* MakeLocationSummary() const; \ | 714 virtual LocationSummary* MakeLocationSummary(bool optimizing) const; \ |
| 715 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ | 715 virtual void EmitNativeCode(FlowGraphCompiler* compiler); \ |
| 716 | 716 |
| 717 | 717 |
| 718 class Instruction : public ZoneAllocated { | 718 class Instruction : public ZoneAllocated { |
| 719 public: | 719 public: |
| 720 #define DECLARE_TAG(type) k##type, | 720 #define DECLARE_TAG(type) k##type, |
| 721 enum Tag { | 721 enum Tag { |
| 722 FOR_EACH_INSTRUCTION(DECLARE_TAG) | 722 FOR_EACH_INSTRUCTION(DECLARE_TAG) |
| 723 }; | 723 }; |
| 724 #undef DECLARE_TAG | 724 #undef DECLARE_TAG |
| 725 | 725 |
| 726 Instruction() | 726 Instruction() |
| 727 : deopt_id_(Isolate::Current()->GetNextDeoptId()), | 727 : deopt_id_(Isolate::Current()->GetNextDeoptId()), |
| 728 lifetime_position_(-1), | 728 lifetime_position_(-1), |
| 729 previous_(NULL), | 729 previous_(NULL), |
| 730 next_(NULL), | 730 next_(NULL), |
| 731 env_(NULL), | 731 env_(NULL), |
| 732 locs_(NULL), |
| 732 place_id_(kNoPlaceId) { } | 733 place_id_(kNoPlaceId) { } |
| 733 | 734 |
| 734 virtual Tag tag() const = 0; | 735 virtual Tag tag() const = 0; |
| 735 | 736 |
| 736 intptr_t deopt_id() const { | 737 intptr_t deopt_id() const { |
| 737 ASSERT(CanDeoptimize() || CanBecomeDeoptimizationTarget()); | 738 ASSERT(CanDeoptimize() || CanBecomeDeoptimizationTarget()); |
| 738 return deopt_id_; | 739 return deopt_id_; |
| 739 } | 740 } |
| 740 | 741 |
| 741 ICData* GetICData(const Array& ic_data_array) const; | 742 ICData* GetICData(const Array& ic_data_array) const; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 | 824 |
| 824 #define INSTRUCTION_TYPE_CHECK(type) \ | 825 #define INSTRUCTION_TYPE_CHECK(type) \ |
| 825 bool Is##type() { return (As##type() != NULL); } \ | 826 bool Is##type() { return (As##type() != NULL); } \ |
| 826 virtual type##Instr* As##type() { return NULL; } | 827 virtual type##Instr* As##type() { return NULL; } |
| 827 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 828 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| 828 #undef INSTRUCTION_TYPE_CHECK | 829 #undef INSTRUCTION_TYPE_CHECK |
| 829 | 830 |
| 830 // Returns structure describing location constraints required | 831 // Returns structure describing location constraints required |
| 831 // to emit native code for this instruction. | 832 // to emit native code for this instruction. |
| 832 virtual LocationSummary* locs() { | 833 virtual LocationSummary* locs() { |
| 833 // TODO(vegorov): This should be pure virtual method. | 834 ASSERT(locs_ != NULL); |
| 834 // However we are temporary using NULL for instructions that | 835 return locs_; |
| 835 // were not converted to the location based code generation yet. | |
| 836 return NULL; | |
| 837 } | 836 } |
| 838 | 837 |
| 839 virtual LocationSummary* MakeLocationSummary() const = 0; | 838 virtual LocationSummary* MakeLocationSummary(bool is_optimizing) const = 0; |
| 839 |
| 840 void InitializeLocationSummary(bool optimizing) { |
| 841 ASSERT(locs_ == NULL); |
| 842 locs_ = MakeLocationSummary(optimizing); |
| 843 } |
| 840 | 844 |
| 841 static LocationSummary* MakeCallSummary(); | 845 static LocationSummary* MakeCallSummary(); |
| 842 | 846 |
| 843 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | 847 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { |
| 844 UNIMPLEMENTED(); | 848 UNIMPLEMENTED(); |
| 845 } | 849 } |
| 846 | 850 |
| 847 Environment* env() const { return env_; } | 851 Environment* env() const { return env_; } |
| 848 void SetEnvironment(Environment* deopt_env); | 852 void SetEnvironment(Environment* deopt_env); |
| 849 void RemoveEnvironment(); | 853 void RemoveEnvironment(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 946 | 950 |
| 947 virtual bool MayThrow() const = 0; | 951 virtual bool MayThrow() const = 0; |
| 948 | 952 |
| 949 protected: | 953 protected: |
| 950 // Fetch deopt id without checking if this computation can deoptimize. | 954 // Fetch deopt id without checking if this computation can deoptimize. |
| 951 intptr_t GetDeoptId() const { | 955 intptr_t GetDeoptId() const { |
| 952 return deopt_id_; | 956 return deopt_id_; |
| 953 } | 957 } |
| 954 | 958 |
| 955 private: | 959 private: |
| 960 friend class FlowGraphPrinter; |
| 956 friend class Definition; // Needed for InsertBefore, InsertAfter. | 961 friend class Definition; // Needed for InsertBefore, InsertAfter. |
| 957 | 962 |
| 958 // Classes that set or read deopt_id_. | 963 // Classes that set or read deopt_id_. |
| 959 friend class UnboxIntegerInstr; | 964 friend class UnboxIntegerInstr; |
| 960 friend class UnboxDoubleInstr; | 965 friend class UnboxDoubleInstr; |
| 961 friend class UnboxFloat32x4Instr; | 966 friend class UnboxFloat32x4Instr; |
| 962 friend class UnboxInt32x4Instr; | 967 friend class UnboxInt32x4Instr; |
| 963 friend class BinaryDoubleOpInstr; | 968 friend class BinaryDoubleOpInstr; |
| 964 friend class BinaryFloat32x4OpInstr; | 969 friend class BinaryFloat32x4OpInstr; |
| 965 friend class Float32x4ZeroInstr; | 970 friend class Float32x4ZeroInstr; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1020 | 1025 |
| 1021 enum { | 1026 enum { |
| 1022 kNoPlaceId = -1 | 1027 kNoPlaceId = -1 |
| 1023 }; | 1028 }; |
| 1024 | 1029 |
| 1025 intptr_t deopt_id_; | 1030 intptr_t deopt_id_; |
| 1026 intptr_t lifetime_position_; // Position used by register allocator. | 1031 intptr_t lifetime_position_; // Position used by register allocator. |
| 1027 Instruction* previous_; | 1032 Instruction* previous_; |
| 1028 Instruction* next_; | 1033 Instruction* next_; |
| 1029 Environment* env_; | 1034 Environment* env_; |
| 1035 LocationSummary* locs_; |
| 1030 intptr_t place_id_; | 1036 intptr_t place_id_; |
| 1031 | 1037 |
| 1032 DISALLOW_COPY_AND_ASSIGN(Instruction); | 1038 DISALLOW_COPY_AND_ASSIGN(Instruction); |
| 1033 }; | 1039 }; |
| 1034 | 1040 |
| 1035 | 1041 |
| 1036 template<intptr_t N> | 1042 template<intptr_t N> |
| 1037 class TemplateInstruction: public Instruction { | 1043 class TemplateInstruction: public Instruction { |
| 1038 public: | 1044 public: |
| 1039 TemplateInstruction<N>() : locs_(NULL) { } | 1045 TemplateInstruction<N>() : inputs_() { } |
| 1040 | 1046 |
| 1041 virtual intptr_t InputCount() const { return N; } | 1047 virtual intptr_t InputCount() const { return N; } |
| 1042 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 1048 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
| 1043 | 1049 |
| 1044 virtual LocationSummary* locs() { | |
| 1045 if (locs_ == NULL) { | |
| 1046 locs_ = MakeLocationSummary(); | |
| 1047 } | |
| 1048 return locs_; | |
| 1049 } | |
| 1050 | |
| 1051 protected: | 1050 protected: |
| 1052 EmbeddedArray<Value*, N> inputs_; | 1051 EmbeddedArray<Value*, N> inputs_; |
| 1053 | 1052 |
| 1054 private: | 1053 private: |
| 1055 virtual void RawSetInputAt(intptr_t i, Value* value) { | 1054 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 1056 inputs_[i] = value; | 1055 inputs_[i] = value; |
| 1057 } | 1056 } |
| 1058 | |
| 1059 LocationSummary* locs_; | |
| 1060 }; | 1057 }; |
| 1061 | 1058 |
| 1062 | 1059 |
| 1063 class MoveOperands : public ZoneAllocated { | 1060 class MoveOperands : public ZoneAllocated { |
| 1064 public: | 1061 public: |
| 1065 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } | 1062 MoveOperands(Location dest, Location src) : dest_(dest), src_(src) { } |
| 1066 | 1063 |
| 1067 Location src() const { return src_; } | 1064 Location src() const { return src_; } |
| 1068 Location dest() const { return dest_; } | 1065 Location dest() const { return dest_; } |
| 1069 | 1066 |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1922 | 1919 |
| 1923 const intptr_t index_; | 1920 const intptr_t index_; |
| 1924 BlockEntryInstr* block_; | 1921 BlockEntryInstr* block_; |
| 1925 | 1922 |
| 1926 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); | 1923 DISALLOW_COPY_AND_ASSIGN(ParameterInstr); |
| 1927 }; | 1924 }; |
| 1928 | 1925 |
| 1929 | 1926 |
| 1930 class PushArgumentInstr : public Definition { | 1927 class PushArgumentInstr : public Definition { |
| 1931 public: | 1928 public: |
| 1932 explicit PushArgumentInstr(Value* value) : locs_(NULL) { | 1929 explicit PushArgumentInstr(Value* value) { |
| 1933 SetInputAt(0, value); | 1930 SetInputAt(0, value); |
| 1934 set_use_kind(kEffect); // Override the default. | 1931 set_use_kind(kEffect); // Override the default. |
| 1935 } | 1932 } |
| 1936 | 1933 |
| 1937 DECLARE_INSTRUCTION(PushArgument) | 1934 DECLARE_INSTRUCTION(PushArgument) |
| 1938 | 1935 |
| 1939 intptr_t InputCount() const { return 1; } | 1936 intptr_t InputCount() const { return 1; } |
| 1940 Value* InputAt(intptr_t i) const { | 1937 Value* InputAt(intptr_t i) const { |
| 1941 ASSERT(i == 0); | 1938 ASSERT(i == 0); |
| 1942 return value_; | 1939 return value_; |
| 1943 } | 1940 } |
| 1944 | 1941 |
| 1945 virtual intptr_t ArgumentCount() const { return 0; } | 1942 virtual intptr_t ArgumentCount() const { return 0; } |
| 1946 | 1943 |
| 1947 virtual CompileType ComputeType() const; | 1944 virtual CompileType ComputeType() const; |
| 1948 | 1945 |
| 1949 Value* value() const { return value_; } | 1946 Value* value() const { return value_; } |
| 1950 | 1947 |
| 1951 virtual LocationSummary* locs() { | |
| 1952 if (locs_ == NULL) { | |
| 1953 locs_ = MakeLocationSummary(); | |
| 1954 } | |
| 1955 return locs_; | |
| 1956 } | |
| 1957 | |
| 1958 virtual intptr_t Hashcode() const { | 1948 virtual intptr_t Hashcode() const { |
| 1959 UNREACHABLE(); | 1949 UNREACHABLE(); |
| 1960 return 0; | 1950 return 0; |
| 1961 } | 1951 } |
| 1962 | 1952 |
| 1963 virtual bool CanDeoptimize() const { return false; } | 1953 virtual bool CanDeoptimize() const { return false; } |
| 1964 | 1954 |
| 1965 virtual EffectSet Effects() const { return EffectSet::None(); } | 1955 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 1966 | 1956 |
| 1967 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1957 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1968 | 1958 |
| 1969 virtual bool MayThrow() const { return false; } | 1959 virtual bool MayThrow() const { return false; } |
| 1970 | 1960 |
| 1971 private: | 1961 private: |
| 1972 virtual void RawSetInputAt(intptr_t i, Value* value) { | 1962 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 1973 ASSERT(i == 0); | 1963 ASSERT(i == 0); |
| 1974 value_ = value; | 1964 value_ = value; |
| 1975 } | 1965 } |
| 1976 | 1966 |
| 1977 Value* value_; | 1967 Value* value_; |
| 1978 LocationSummary* locs_; | |
| 1979 | 1968 |
| 1980 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr); | 1969 DISALLOW_COPY_AND_ASSIGN(PushArgumentInstr); |
| 1981 }; | 1970 }; |
| 1982 | 1971 |
| 1983 | 1972 |
| 1984 inline Definition* Instruction::ArgumentAt(intptr_t index) const { | 1973 inline Definition* Instruction::ArgumentAt(intptr_t index) const { |
| 1985 return PushArgumentAt(index)->value()->definition(); | 1974 return PushArgumentAt(index)->value()->definition(); |
| 1986 } | 1975 } |
| 1987 | 1976 |
| 1988 | 1977 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2126 | 2115 |
| 2127 // Parallel move that will be used by linear scan register allocator to | 2116 // Parallel move that will be used by linear scan register allocator to |
| 2128 // connect live ranges at the end of the block and resolve phis. | 2117 // connect live ranges at the end of the block and resolve phis. |
| 2129 ParallelMoveInstr* parallel_move_; | 2118 ParallelMoveInstr* parallel_move_; |
| 2130 }; | 2119 }; |
| 2131 | 2120 |
| 2132 | 2121 |
| 2133 template<intptr_t N> | 2122 template<intptr_t N> |
| 2134 class TemplateDefinition : public Definition { | 2123 class TemplateDefinition : public Definition { |
| 2135 public: | 2124 public: |
| 2136 TemplateDefinition<N>() : locs_(NULL) { } | 2125 TemplateDefinition<N>() : inputs_() { } |
| 2137 | 2126 |
| 2138 virtual intptr_t InputCount() const { return N; } | 2127 virtual intptr_t InputCount() const { return N; } |
| 2139 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 2128 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
| 2140 | 2129 |
| 2141 // Returns a structure describing the location constraints required | |
| 2142 // to emit native code for this definition. | |
| 2143 LocationSummary* locs() { | |
| 2144 if (locs_ == NULL) { | |
| 2145 locs_ = MakeLocationSummary(); | |
| 2146 } | |
| 2147 return locs_; | |
| 2148 } | |
| 2149 | |
| 2150 protected: | 2130 protected: |
| 2151 EmbeddedArray<Value*, N> inputs_; | 2131 EmbeddedArray<Value*, N> inputs_; |
| 2152 | 2132 |
| 2153 private: | 2133 private: |
| 2154 friend class BranchInstr; | 2134 friend class BranchInstr; |
| 2155 friend class IfThenElseInstr; | 2135 friend class IfThenElseInstr; |
| 2156 | 2136 |
| 2157 virtual void RawSetInputAt(intptr_t i, Value* value) { | 2137 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 2158 inputs_[i] = value; | 2138 inputs_[i] = value; |
| 2159 } | 2139 } |
| 2160 | |
| 2161 LocationSummary* locs_; | |
| 2162 }; | 2140 }; |
| 2163 | 2141 |
| 2164 | 2142 |
| 2165 struct BranchLabels { | 2143 struct BranchLabels { |
| 2166 Label* true_label; | 2144 Label* true_label; |
| 2167 Label* false_label; | 2145 Label* false_label; |
| 2168 Label* fall_through; | 2146 Label* fall_through; |
| 2169 }; | 2147 }; |
| 2170 | 2148 |
| 2171 | 2149 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2253 | 2231 |
| 2254 virtual EffectSet Effects() const { | 2232 virtual EffectSet Effects() const { |
| 2255 return comparison()->Effects(); | 2233 return comparison()->Effects(); |
| 2256 } | 2234 } |
| 2257 | 2235 |
| 2258 ComparisonInstr* comparison() const { return comparison_; } | 2236 ComparisonInstr* comparison() const { return comparison_; } |
| 2259 void SetComparison(ComparisonInstr* comp); | 2237 void SetComparison(ComparisonInstr* comp); |
| 2260 | 2238 |
| 2261 bool is_checked() const { return is_checked_; } | 2239 bool is_checked() const { return is_checked_; } |
| 2262 | 2240 |
| 2263 virtual LocationSummary* locs() { | |
| 2264 if (comparison()->locs_ == NULL) { | |
| 2265 LocationSummary* summary = comparison()->MakeLocationSummary(); | |
| 2266 // Branches don't produce a result. | |
| 2267 summary->set_out(Location::NoLocation()); | |
| 2268 // The back-end expects the location summary to be stored in the | |
| 2269 // comparison. | |
| 2270 comparison()->locs_ = summary; | |
| 2271 } | |
| 2272 return comparison()->locs_; | |
| 2273 } | |
| 2274 | |
| 2275 virtual intptr_t DeoptimizationTarget() const { | 2241 virtual intptr_t DeoptimizationTarget() const { |
| 2276 return comparison()->DeoptimizationTarget(); | 2242 return comparison()->DeoptimizationTarget(); |
| 2277 } | 2243 } |
| 2278 | 2244 |
| 2279 virtual Representation RequiredInputRepresentation(intptr_t i) const { | 2245 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
| 2280 return comparison()->RequiredInputRepresentation(i); | 2246 return comparison()->RequiredInputRepresentation(i); |
| 2281 } | 2247 } |
| 2282 | 2248 |
| 2283 virtual Instruction* Canonicalize(FlowGraph* flow_graph); | 2249 virtual Instruction* Canonicalize(FlowGraph* flow_graph); |
| 2284 | 2250 |
| (...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3146 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } | 3112 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } |
| 3147 | 3113 |
| 3148 virtual bool CanDeoptimize() const { | 3114 virtual bool CanDeoptimize() const { |
| 3149 return comparison()->CanDeoptimize(); | 3115 return comparison()->CanDeoptimize(); |
| 3150 } | 3116 } |
| 3151 | 3117 |
| 3152 virtual bool CanBecomeDeoptimizationTarget() const { | 3118 virtual bool CanBecomeDeoptimizationTarget() const { |
| 3153 return comparison()->CanBecomeDeoptimizationTarget(); | 3119 return comparison()->CanBecomeDeoptimizationTarget(); |
| 3154 } | 3120 } |
| 3155 | 3121 |
| 3156 virtual LocationSummary* locs() { | |
| 3157 if (comparison()->locs_ == NULL) { | |
| 3158 LocationSummary* summary = MakeLocationSummary(); | |
| 3159 // The back-end expects the location summary to be stored in the | |
| 3160 // comparison. | |
| 3161 comparison()->locs_ = summary; | |
| 3162 } | |
| 3163 return comparison()->locs_; | |
| 3164 } | |
| 3165 | |
| 3166 virtual intptr_t DeoptimizationTarget() const { | 3122 virtual intptr_t DeoptimizationTarget() const { |
| 3167 return comparison()->DeoptimizationTarget(); | 3123 return comparison()->DeoptimizationTarget(); |
| 3168 } | 3124 } |
| 3169 | 3125 |
| 3170 virtual Representation RequiredInputRepresentation(intptr_t i) const { | 3126 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
| 3171 return comparison()->RequiredInputRepresentation(i); | 3127 return comparison()->RequiredInputRepresentation(i); |
| 3172 } | 3128 } |
| 3173 | 3129 |
| 3174 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3130 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3175 | 3131 |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3462 kNoStoreBarrier, | 3418 kNoStoreBarrier, |
| 3463 kEmitStoreBarrier | 3419 kEmitStoreBarrier |
| 3464 }; | 3420 }; |
| 3465 | 3421 |
| 3466 | 3422 |
| 3467 class StoreInstanceFieldInstr : public TemplateDefinition<2> { | 3423 class StoreInstanceFieldInstr : public TemplateDefinition<2> { |
| 3468 public: | 3424 public: |
| 3469 StoreInstanceFieldInstr(const Field& field, | 3425 StoreInstanceFieldInstr(const Field& field, |
| 3470 Value* instance, | 3426 Value* instance, |
| 3471 Value* value, | 3427 Value* value, |
| 3472 StoreBarrierType emit_store_barrier) | 3428 StoreBarrierType emit_store_barrier, |
| 3429 bool is_initialization = false) |
| 3473 : field_(field), | 3430 : field_(field), |
| 3474 emit_store_barrier_(emit_store_barrier) { | 3431 emit_store_barrier_(emit_store_barrier), |
| 3432 is_initialization_(is_initialization) { |
| 3475 SetInputAt(kInstancePos, instance); | 3433 SetInputAt(kInstancePos, instance); |
| 3476 SetInputAt(kValuePos, value); | 3434 SetInputAt(kValuePos, value); |
| 3477 } | 3435 } |
| 3478 | 3436 |
| 3479 DECLARE_INSTRUCTION(StoreInstanceField) | 3437 DECLARE_INSTRUCTION(StoreInstanceField) |
| 3480 | 3438 |
| 3481 enum { | 3439 enum { |
| 3482 kInstancePos = 0, | 3440 kInstancePos = 0, |
| 3483 kValuePos = 1 | 3441 kValuePos = 1 |
| 3484 }; | 3442 }; |
| 3485 | 3443 |
| 3486 Value* instance() const { return inputs_[kInstancePos]; } | 3444 Value* instance() const { return inputs_[kInstancePos]; } |
| 3487 Value* value() const { return inputs_[kValuePos]; } | 3445 Value* value() const { return inputs_[kValuePos]; } |
| 3488 | 3446 |
| 3489 virtual CompileType* ComputeInitialType() const; | 3447 virtual CompileType* ComputeInitialType() const; |
| 3490 | 3448 |
| 3491 const Field& field() const { return field_; } | 3449 const Field& field() const { return field_; } |
| 3492 | 3450 |
| 3493 bool ShouldEmitStoreBarrier() const { | 3451 bool ShouldEmitStoreBarrier() const { |
| 3494 return value()->NeedsStoreBuffer() | 3452 return value()->NeedsStoreBuffer() |
| 3495 && (emit_store_barrier_ == kEmitStoreBarrier); | 3453 && (emit_store_barrier_ == kEmitStoreBarrier); |
| 3496 } | 3454 } |
| 3497 | 3455 |
| 3498 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3456 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3499 | 3457 |
| 3500 virtual bool CanDeoptimize() const { return false; } | 3458 virtual bool CanDeoptimize() const { return false; } |
| 3501 | 3459 |
| 3460 // May require a deoptimization target for input conversions. |
| 3461 virtual intptr_t DeoptimizationTarget() const { |
| 3462 return GetDeoptId(); |
| 3463 } |
| 3464 |
| 3502 // Currently CSE/LICM don't operate on any instructions that can be affected | 3465 // Currently CSE/LICM don't operate on any instructions that can be affected |
| 3503 // by stores/loads. LoadOptimizer handles loads separately. Hence stores | 3466 // by stores/loads. LoadOptimizer handles loads separately. Hence stores |
| 3504 // are marked as having no side-effects. | 3467 // are marked as having no side-effects. |
| 3505 virtual EffectSet Effects() const { return EffectSet::None(); } | 3468 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 3506 | 3469 |
| 3507 virtual bool MayThrow() const { return false; } | 3470 virtual bool MayThrow() const { return false; } |
| 3508 | 3471 |
| 3472 bool IsUnboxedStore() const; |
| 3473 |
| 3474 bool IsPotentialUnboxedStore() const; |
| 3475 |
| 3476 virtual Representation RequiredInputRepresentation(intptr_t index) const { |
| 3477 ASSERT((index == 0) || (index == 1)); |
| 3478 if ((index == 1) && IsUnboxedStore()) return kUnboxedDouble; |
| 3479 return kTagged; |
| 3480 } |
| 3481 |
| 3509 private: | 3482 private: |
| 3483 friend class FlowGraphOptimizer; // For ASSERT(initialization_). |
| 3484 |
| 3510 bool CanValueBeSmi() const { | 3485 bool CanValueBeSmi() const { |
| 3511 const intptr_t cid = value()->Type()->ToNullableCid(); | 3486 const intptr_t cid = value()->Type()->ToNullableCid(); |
| 3512 // Write barrier is skipped for nullable and non-nullable smis. | 3487 // Write barrier is skipped for nullable and non-nullable smis. |
| 3513 ASSERT(cid != kSmiCid); | 3488 ASSERT(cid != kSmiCid); |
| 3514 return (cid == kDynamicCid); | 3489 return (cid == kDynamicCid); |
| 3515 } | 3490 } |
| 3516 | 3491 |
| 3517 const Field& field_; | 3492 const Field& field_; |
| 3518 const StoreBarrierType emit_store_barrier_; | 3493 const StoreBarrierType emit_store_barrier_; |
| 3494 const bool is_initialization_; // Marks stores in the constructor. |
| 3519 | 3495 |
| 3520 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); | 3496 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); |
| 3521 }; | 3497 }; |
| 3522 | 3498 |
| 3523 | 3499 |
| 3524 class GuardFieldInstr : public TemplateInstruction<1> { | 3500 class GuardFieldInstr : public TemplateInstruction<1> { |
| 3525 public: | 3501 public: |
| 3526 GuardFieldInstr(Value* value, | 3502 GuardFieldInstr(Value* value, |
| 3527 const Field& field, | 3503 const Field& field, |
| 3528 intptr_t deopt_id) | 3504 intptr_t deopt_id) |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3989 return values_->length(); | 3965 return values_->length(); |
| 3990 } | 3966 } |
| 3991 | 3967 |
| 3992 virtual Value* InputAt(intptr_t i) const { | 3968 virtual Value* InputAt(intptr_t i) const { |
| 3993 return (*values_)[i]; | 3969 return (*values_)[i]; |
| 3994 } | 3970 } |
| 3995 | 3971 |
| 3996 virtual bool CanDeoptimize() const { return false; } | 3972 virtual bool CanDeoptimize() const { return false; } |
| 3997 virtual EffectSet Effects() const { return EffectSet::None(); } | 3973 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 3998 | 3974 |
| 3999 LocationSummary* locs() { | |
| 4000 UNREACHABLE(); | |
| 4001 return NULL; | |
| 4002 } | |
| 4003 | |
| 4004 Location* locations() { return locations_; } | 3975 Location* locations() { return locations_; } |
| 4005 void set_locations(Location* locations) { locations_ = locations; } | 3976 void set_locations(Location* locations) { locations_ = locations; } |
| 4006 | 3977 |
| 4007 virtual bool MayThrow() const { return false; } | 3978 virtual bool MayThrow() const { return false; } |
| 4008 | 3979 |
| 4009 private: | 3980 private: |
| 4010 virtual void RawSetInputAt(intptr_t i, Value* value) { | 3981 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 4011 (*values_)[i] = value; | 3982 (*values_)[i] = value; |
| 4012 } | 3983 } |
| 4013 | 3984 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4209 | 4180 |
| 4210 Value* instance() const { return inputs_[0]; } | 4181 Value* instance() const { return inputs_[0]; } |
| 4211 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 4182 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
| 4212 const AbstractType& type() const { return type_; } | 4183 const AbstractType& type() const { return type_; } |
| 4213 void set_result_cid(intptr_t value) { result_cid_ = value; } | 4184 void set_result_cid(intptr_t value) { result_cid_ = value; } |
| 4214 intptr_t result_cid() const { return result_cid_; } | 4185 intptr_t result_cid() const { return result_cid_; } |
| 4215 | 4186 |
| 4216 const Field* field() const { return field_; } | 4187 const Field* field() const { return field_; } |
| 4217 void set_field(const Field* field) { field_ = field; } | 4188 void set_field(const Field* field) { field_ = field; } |
| 4218 | 4189 |
| 4190 virtual Representation representation() const { |
| 4191 return IsUnboxedLoad() ? kUnboxedDouble : kTagged; |
| 4192 } |
| 4193 |
| 4194 bool IsUnboxedLoad() const; |
| 4195 |
| 4196 bool IsPotentialUnboxedLoad() const; |
| 4197 |
| 4219 void set_recognized_kind(MethodRecognizer::Kind kind) { | 4198 void set_recognized_kind(MethodRecognizer::Kind kind) { |
| 4220 recognized_kind_ = kind; | 4199 recognized_kind_ = kind; |
| 4221 } | 4200 } |
| 4222 | 4201 |
| 4223 MethodRecognizer::Kind recognized_kind() const { | 4202 MethodRecognizer::Kind recognized_kind() const { |
| 4224 return recognized_kind_; | 4203 return recognized_kind_; |
| 4225 } | 4204 } |
| 4226 | 4205 |
| 4227 DECLARE_INSTRUCTION(LoadField) | 4206 DECLARE_INSTRUCTION(LoadField) |
| 4228 virtual CompileType ComputeType() const; | 4207 virtual CompileType ComputeType() const; |
| (...skipping 2381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6610 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } | 6589 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } |
| 6611 | 6590 |
| 6612 virtual intptr_t InputCount() const { | 6591 virtual intptr_t InputCount() const { |
| 6613 return inputs_->length(); | 6592 return inputs_->length(); |
| 6614 } | 6593 } |
| 6615 | 6594 |
| 6616 virtual Value* InputAt(intptr_t i) const { | 6595 virtual Value* InputAt(intptr_t i) const { |
| 6617 return (*inputs_)[i]; | 6596 return (*inputs_)[i]; |
| 6618 } | 6597 } |
| 6619 | 6598 |
| 6620 // Returns a structure describing the location constraints required | |
| 6621 // to emit native code for this definition. | |
| 6622 LocationSummary* locs() { | |
| 6623 if (locs_ == NULL) { | |
| 6624 locs_ = MakeLocationSummary(); | |
| 6625 } | |
| 6626 return locs_; | |
| 6627 } | |
| 6628 | |
| 6629 virtual bool AllowsCSE() const { return true; } | 6599 virtual bool AllowsCSE() const { return true; } |
| 6630 virtual EffectSet Effects() const { return EffectSet::None(); } | 6600 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 6631 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 6601 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 6632 virtual bool AttributesEqual(Instruction* other) const { | 6602 virtual bool AttributesEqual(Instruction* other) const { |
| 6633 InvokeMathCFunctionInstr* other_invoke = other->AsInvokeMathCFunction(); | 6603 InvokeMathCFunctionInstr* other_invoke = other->AsInvokeMathCFunction(); |
| 6634 return other_invoke->recognized_kind() == recognized_kind(); | 6604 return other_invoke->recognized_kind() == recognized_kind(); |
| 6635 } | 6605 } |
| 6636 | 6606 |
| 6637 virtual bool MayThrow() const { return false; } | 6607 virtual bool MayThrow() const { return false; } |
| 6638 | 6608 |
| 6639 private: | 6609 private: |
| 6640 virtual void RawSetInputAt(intptr_t i, Value* value) { | 6610 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 6641 (*inputs_)[i] = value; | 6611 (*inputs_)[i] = value; |
| 6642 } | 6612 } |
| 6643 | 6613 |
| 6644 ZoneGrowableArray<Value*>* inputs_; | 6614 ZoneGrowableArray<Value*>* inputs_; |
| 6645 | 6615 |
| 6646 LocationSummary* locs_; | |
| 6647 | |
| 6648 const MethodRecognizer::Kind recognized_kind_; | 6616 const MethodRecognizer::Kind recognized_kind_; |
| 6649 | 6617 |
| 6650 DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr); | 6618 DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr); |
| 6651 }; | 6619 }; |
| 6652 | 6620 |
| 6653 | 6621 |
| 6654 class MergedMathInstr : public Definition { | 6622 class MergedMathInstr : public Definition { |
| 6655 public: | 6623 public: |
| 6656 enum Kind { | 6624 enum Kind { |
| 6657 kTruncDivMod, | 6625 kTruncDivMod, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6720 } | 6688 } |
| 6721 | 6689 |
| 6722 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } | 6690 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } |
| 6723 | 6691 |
| 6724 // Returns the result index for one of the merged instructjons | 6692 // Returns the result index for one of the merged instructjons |
| 6725 static intptr_t ResultIndexOf(MethodRecognizer::Kind kind); | 6693 static intptr_t ResultIndexOf(MethodRecognizer::Kind kind); |
| 6726 static intptr_t ResultIndexOf(Token::Kind token); | 6694 static intptr_t ResultIndexOf(Token::Kind token); |
| 6727 | 6695 |
| 6728 DECLARE_INSTRUCTION(MergedMath) | 6696 DECLARE_INSTRUCTION(MergedMath) |
| 6729 | 6697 |
| 6730 // Returns a structure describing the location constraints required | |
| 6731 // to emit native code for this definition. | |
| 6732 LocationSummary* locs() { | |
| 6733 if (locs_ == NULL) { | |
| 6734 locs_ = MakeLocationSummary(); | |
| 6735 } | |
| 6736 return locs_; | |
| 6737 } | |
| 6738 | |
| 6739 virtual bool AllowsCSE() const { return true; } | 6698 virtual bool AllowsCSE() const { return true; } |
| 6740 virtual EffectSet Effects() const { return EffectSet::None(); } | 6699 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 6741 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 6700 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 6742 virtual bool AttributesEqual(Instruction* other) const { | 6701 virtual bool AttributesEqual(Instruction* other) const { |
| 6743 MergedMathInstr* other_invoke = other->AsMergedMath(); | 6702 MergedMathInstr* other_invoke = other->AsMergedMath(); |
| 6744 return other_invoke->kind() == kind(); | 6703 return other_invoke->kind() == kind(); |
| 6745 } | 6704 } |
| 6746 | 6705 |
| 6747 virtual bool MayThrow() const { return false; } | 6706 virtual bool MayThrow() const { return false; } |
| 6748 | 6707 |
| 6749 static const char* KindToCString(MergedMathInstr::Kind kind) { | 6708 static const char* KindToCString(MergedMathInstr::Kind kind) { |
| 6750 if (kind == kTruncDivMod) return "TruncDivMod"; | 6709 if (kind == kTruncDivMod) return "TruncDivMod"; |
| 6751 if (kind == kSinCos) return "SinCos"; | 6710 if (kind == kSinCos) return "SinCos"; |
| 6752 UNIMPLEMENTED(); | 6711 UNIMPLEMENTED(); |
| 6753 return ""; | 6712 return ""; |
| 6754 } | 6713 } |
| 6755 | 6714 |
| 6756 private: | 6715 private: |
| 6757 virtual void RawSetInputAt(intptr_t i, Value* value) { | 6716 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 6758 (*inputs_)[i] = value; | 6717 (*inputs_)[i] = value; |
| 6759 } | 6718 } |
| 6760 | 6719 |
| 6761 ZoneGrowableArray<Value*>* inputs_; | 6720 ZoneGrowableArray<Value*>* inputs_; |
| 6762 LocationSummary* locs_; | |
| 6763 MergedMathInstr::Kind kind_; | 6721 MergedMathInstr::Kind kind_; |
| 6764 | 6722 |
| 6765 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); | 6723 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); |
| 6766 }; | 6724 }; |
| 6767 | 6725 |
| 6768 | 6726 |
| 6769 class CheckClassInstr : public TemplateInstruction<1> { | 6727 class CheckClassInstr : public TemplateInstruction<1> { |
| 6770 public: | 6728 public: |
| 6771 CheckClassInstr(Value* value, | 6729 CheckClassInstr(Value* value, |
| 6772 intptr_t deopt_id, | 6730 intptr_t deopt_id, |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7095 ForwardInstructionIterator* current_iterator_; | 7053 ForwardInstructionIterator* current_iterator_; |
| 7096 | 7054 |
| 7097 private: | 7055 private: |
| 7098 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 7056 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 7099 }; | 7057 }; |
| 7100 | 7058 |
| 7101 | 7059 |
| 7102 } // namespace dart | 7060 } // namespace dart |
| 7103 | 7061 |
| 7104 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 7062 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |