Chromium Code Reviews| 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 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3147 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } | 3113 Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); } |
| 3148 | 3114 |
| 3149 virtual bool CanDeoptimize() const { | 3115 virtual bool CanDeoptimize() const { |
| 3150 return comparison()->CanDeoptimize(); | 3116 return comparison()->CanDeoptimize(); |
| 3151 } | 3117 } |
| 3152 | 3118 |
| 3153 virtual bool CanBecomeDeoptimizationTarget() const { | 3119 virtual bool CanBecomeDeoptimizationTarget() const { |
| 3154 return comparison()->CanBecomeDeoptimizationTarget(); | 3120 return comparison()->CanBecomeDeoptimizationTarget(); |
| 3155 } | 3121 } |
| 3156 | 3122 |
| 3157 virtual LocationSummary* locs() { | |
| 3158 if (comparison()->locs_ == NULL) { | |
| 3159 LocationSummary* summary = MakeLocationSummary(); | |
| 3160 // The back-end expects the location summary to be stored in the | |
| 3161 // comparison. | |
| 3162 comparison()->locs_ = summary; | |
| 3163 } | |
| 3164 return comparison()->locs_; | |
| 3165 } | |
| 3166 | |
| 3167 virtual intptr_t DeoptimizationTarget() const { | 3123 virtual intptr_t DeoptimizationTarget() const { |
| 3168 return comparison()->DeoptimizationTarget(); | 3124 return comparison()->DeoptimizationTarget(); |
| 3169 } | 3125 } |
| 3170 | 3126 |
| 3171 virtual Representation RequiredInputRepresentation(intptr_t i) const { | 3127 virtual Representation RequiredInputRepresentation(intptr_t i) const { |
| 3172 return comparison()->RequiredInputRepresentation(i); | 3128 return comparison()->RequiredInputRepresentation(i); |
| 3173 } | 3129 } |
| 3174 | 3130 |
| 3175 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3131 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3176 | 3132 |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3463 kNoStoreBarrier, | 3419 kNoStoreBarrier, |
| 3464 kEmitStoreBarrier | 3420 kEmitStoreBarrier |
| 3465 }; | 3421 }; |
| 3466 | 3422 |
| 3467 | 3423 |
| 3468 class StoreInstanceFieldInstr : public TemplateDefinition<2> { | 3424 class StoreInstanceFieldInstr : public TemplateDefinition<2> { |
| 3469 public: | 3425 public: |
| 3470 StoreInstanceFieldInstr(const Field& field, | 3426 StoreInstanceFieldInstr(const Field& field, |
| 3471 Value* instance, | 3427 Value* instance, |
| 3472 Value* value, | 3428 Value* value, |
| 3473 StoreBarrierType emit_store_barrier) | 3429 StoreBarrierType emit_store_barrier, |
| 3430 bool initialization = false) | |
| 3474 : field_(field), | 3431 : field_(field), |
| 3475 emit_store_barrier_(emit_store_barrier) { | 3432 emit_store_barrier_(emit_store_barrier), |
| 3433 initialization_(initialization) { | |
| 3476 SetInputAt(kInstancePos, instance); | 3434 SetInputAt(kInstancePos, instance); |
| 3477 SetInputAt(kValuePos, value); | 3435 SetInputAt(kValuePos, value); |
| 3478 } | 3436 } |
| 3479 | 3437 |
| 3480 DECLARE_INSTRUCTION(StoreInstanceField) | 3438 DECLARE_INSTRUCTION(StoreInstanceField) |
| 3481 | 3439 |
| 3482 enum { | 3440 enum { |
| 3483 kInstancePos = 0, | 3441 kInstancePos = 0, |
| 3484 kValuePos = 1 | 3442 kValuePos = 1 |
| 3485 }; | 3443 }; |
| 3486 | 3444 |
| 3487 Value* instance() const { return inputs_[kInstancePos]; } | 3445 Value* instance() const { return inputs_[kInstancePos]; } |
| 3488 Value* value() const { return inputs_[kValuePos]; } | 3446 Value* value() const { return inputs_[kValuePos]; } |
| 3489 | 3447 |
| 3490 virtual CompileType* ComputeInitialType() const; | 3448 virtual CompileType* ComputeInitialType() const; |
| 3491 | 3449 |
| 3492 const Field& field() const { return field_; } | 3450 const Field& field() const { return field_; } |
| 3493 | 3451 |
| 3494 bool ShouldEmitStoreBarrier() const { | 3452 bool ShouldEmitStoreBarrier() const { |
| 3495 return value()->NeedsStoreBuffer() | 3453 return value()->NeedsStoreBuffer() |
| 3496 && (emit_store_barrier_ == kEmitStoreBarrier); | 3454 && (emit_store_barrier_ == kEmitStoreBarrier); |
| 3497 } | 3455 } |
| 3498 | 3456 |
| 3499 virtual void PrintOperandsTo(BufferFormatter* f) const; | 3457 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 3500 | 3458 |
| 3501 virtual bool CanDeoptimize() const { return false; } | 3459 virtual bool CanDeoptimize() const { return false; } |
| 3502 | 3460 |
| 3461 // May require a deoptimziation target for input conversions. | |
|
srdjan
2013/12/13 18:13:17
s/deoptimziation/deoptimization/
Florian Schneider
2013/12/16 13:08:09
Done.
| |
| 3462 virtual intptr_t DeoptimizationTarget() const { | |
| 3463 return deopt_id_; | |
|
srdjan
2013/12/13 18:13:17
return GetDeoptId() (similar to other places).
Florian Schneider
2013/12/16 13:08:09
Done.
| |
| 3464 } | |
| 3465 | |
| 3503 // Currently CSE/LICM don't operate on any instructions that can be affected | 3466 // Currently CSE/LICM don't operate on any instructions that can be affected |
| 3504 // by stores/loads. LoadOptimizer handles loads separately. Hence stores | 3467 // by stores/loads. LoadOptimizer handles loads separately. Hence stores |
| 3505 // are marked as having no side-effects. | 3468 // are marked as having no side-effects. |
| 3506 virtual EffectSet Effects() const { return EffectSet::None(); } | 3469 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 3507 | 3470 |
| 3508 virtual bool MayThrow() const { return false; } | 3471 virtual bool MayThrow() const { return false; } |
| 3509 | 3472 |
| 3473 bool IsUnboxedStore() const; | |
| 3474 | |
| 3475 bool IsPotentialUnboxedStore() const; | |
| 3476 | |
| 3477 virtual Representation RequiredInputRepresentation(intptr_t index) const { | |
| 3478 ASSERT(index == 0 || index == 1); | |
|
srdjan
2013/12/13 18:13:17
Add parentheses please. Introducing an abbreviatio
Florian Schneider
2013/12/16 13:08:09
Done.
| |
| 3479 if (index == 1 && IsUnboxedStore()) return kUnboxedDouble; | |
|
srdjan
2013/12/13 18:13:17
APP
Florian Schneider
2013/12/16 13:08:09
Again? :)
| |
| 3480 return kTagged; | |
| 3481 } | |
| 3482 | |
| 3510 private: | 3483 private: |
| 3484 friend class FlowGraphOptimizer; // For ASSERT(initialization_). | |
| 3485 | |
| 3511 bool CanValueBeSmi() const { | 3486 bool CanValueBeSmi() const { |
| 3512 const intptr_t cid = value()->Type()->ToNullableCid(); | 3487 const intptr_t cid = value()->Type()->ToNullableCid(); |
| 3513 // Write barrier is skipped for nullable and non-nullable smis. | 3488 // Write barrier is skipped for nullable and non-nullable smis. |
| 3514 ASSERT(cid != kSmiCid); | 3489 ASSERT(cid != kSmiCid); |
| 3515 return (cid == kDynamicCid); | 3490 return (cid == kDynamicCid); |
| 3516 } | 3491 } |
| 3517 | 3492 |
| 3518 const Field& field_; | 3493 const Field& field_; |
| 3519 const StoreBarrierType emit_store_barrier_; | 3494 const StoreBarrierType emit_store_barrier_; |
| 3495 const bool initialization_; | |
| 3520 | 3496 |
|
srdjan
2013/12/13 18:13:17
Please add brief comment what initialization_ mean
Florian Schneider
2013/12/16 13:08:09
Done.
| |
| 3521 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); | 3497 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); |
| 3522 }; | 3498 }; |
| 3523 | 3499 |
| 3524 | 3500 |
| 3525 class GuardFieldInstr : public TemplateInstruction<1> { | 3501 class GuardFieldInstr : public TemplateInstruction<1> { |
| 3526 public: | 3502 public: |
| 3527 GuardFieldInstr(Value* value, | 3503 GuardFieldInstr(Value* value, |
| 3528 const Field& field, | 3504 const Field& field, |
| 3529 intptr_t deopt_id) | 3505 intptr_t deopt_id) |
| 3530 : field_(field) { | 3506 : field_(field) { |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3990 return values_->length(); | 3966 return values_->length(); |
| 3991 } | 3967 } |
| 3992 | 3968 |
| 3993 virtual Value* InputAt(intptr_t i) const { | 3969 virtual Value* InputAt(intptr_t i) const { |
| 3994 return (*values_)[i]; | 3970 return (*values_)[i]; |
| 3995 } | 3971 } |
| 3996 | 3972 |
| 3997 virtual bool CanDeoptimize() const { return false; } | 3973 virtual bool CanDeoptimize() const { return false; } |
| 3998 virtual EffectSet Effects() const { return EffectSet::None(); } | 3974 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 3999 | 3975 |
| 4000 LocationSummary* locs() { | |
| 4001 UNREACHABLE(); | |
| 4002 return NULL; | |
| 4003 } | |
| 4004 | |
| 4005 Location* locations() { return locations_; } | 3976 Location* locations() { return locations_; } |
| 4006 void set_locations(Location* locations) { locations_ = locations; } | 3977 void set_locations(Location* locations) { locations_ = locations; } |
| 4007 | 3978 |
| 4008 virtual bool MayThrow() const { return false; } | 3979 virtual bool MayThrow() const { return false; } |
| 4009 | 3980 |
| 4010 private: | 3981 private: |
| 4011 virtual void RawSetInputAt(intptr_t i, Value* value) { | 3982 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 4012 (*values_)[i] = value; | 3983 (*values_)[i] = value; |
| 4013 } | 3984 } |
| 4014 | 3985 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4210 | 4181 |
| 4211 Value* instance() const { return inputs_[0]; } | 4182 Value* instance() const { return inputs_[0]; } |
| 4212 intptr_t offset_in_bytes() const { return offset_in_bytes_; } | 4183 intptr_t offset_in_bytes() const { return offset_in_bytes_; } |
| 4213 const AbstractType& type() const { return type_; } | 4184 const AbstractType& type() const { return type_; } |
| 4214 void set_result_cid(intptr_t value) { result_cid_ = value; } | 4185 void set_result_cid(intptr_t value) { result_cid_ = value; } |
| 4215 intptr_t result_cid() const { return result_cid_; } | 4186 intptr_t result_cid() const { return result_cid_; } |
| 4216 | 4187 |
| 4217 const Field* field() const { return field_; } | 4188 const Field* field() const { return field_; } |
| 4218 void set_field(const Field* field) { field_ = field; } | 4189 void set_field(const Field* field) { field_ = field; } |
| 4219 | 4190 |
| 4191 virtual Representation representation() const { | |
| 4192 return IsUnboxedLoad() ? kUnboxedDouble : kTagged; | |
|
Cutch
2013/12/13 19:48:43
Can we not hardcode kUnboxedDouble as the represen
Florian Schneider
2013/12/16 13:08:09
Yes. I agree. I'd like to generalize the approach
| |
| 4193 } | |
| 4194 | |
| 4195 bool IsUnboxedLoad() const; | |
| 4196 | |
| 4197 bool IsPotentialUnboxedLoad() const; | |
| 4198 | |
| 4220 void set_recognized_kind(MethodRecognizer::Kind kind) { | 4199 void set_recognized_kind(MethodRecognizer::Kind kind) { |
| 4221 recognized_kind_ = kind; | 4200 recognized_kind_ = kind; |
| 4222 } | 4201 } |
| 4223 | 4202 |
| 4224 MethodRecognizer::Kind recognized_kind() const { | 4203 MethodRecognizer::Kind recognized_kind() const { |
| 4225 return recognized_kind_; | 4204 return recognized_kind_; |
| 4226 } | 4205 } |
| 4227 | 4206 |
| 4228 DECLARE_INSTRUCTION(LoadField) | 4207 DECLARE_INSTRUCTION(LoadField) |
| 4229 virtual CompileType ComputeType() const; | 4208 virtual CompileType ComputeType() const; |
| (...skipping 2381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6611 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } | 6590 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } |
| 6612 | 6591 |
| 6613 virtual intptr_t InputCount() const { | 6592 virtual intptr_t InputCount() const { |
| 6614 return inputs_->length(); | 6593 return inputs_->length(); |
| 6615 } | 6594 } |
| 6616 | 6595 |
| 6617 virtual Value* InputAt(intptr_t i) const { | 6596 virtual Value* InputAt(intptr_t i) const { |
| 6618 return (*inputs_)[i]; | 6597 return (*inputs_)[i]; |
| 6619 } | 6598 } |
| 6620 | 6599 |
| 6621 // Returns a structure describing the location constraints required | |
| 6622 // to emit native code for this definition. | |
| 6623 LocationSummary* locs() { | |
| 6624 if (locs_ == NULL) { | |
| 6625 locs_ = MakeLocationSummary(); | |
| 6626 } | |
| 6627 return locs_; | |
| 6628 } | |
| 6629 | |
| 6630 virtual bool AllowsCSE() const { return true; } | 6600 virtual bool AllowsCSE() const { return true; } |
| 6631 virtual EffectSet Effects() const { return EffectSet::None(); } | 6601 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 6632 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 6602 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 6633 virtual bool AttributesEqual(Instruction* other) const { | 6603 virtual bool AttributesEqual(Instruction* other) const { |
| 6634 InvokeMathCFunctionInstr* other_invoke = other->AsInvokeMathCFunction(); | 6604 InvokeMathCFunctionInstr* other_invoke = other->AsInvokeMathCFunction(); |
| 6635 return other_invoke->recognized_kind() == recognized_kind(); | 6605 return other_invoke->recognized_kind() == recognized_kind(); |
| 6636 } | 6606 } |
| 6637 | 6607 |
| 6638 virtual bool MayThrow() const { return false; } | 6608 virtual bool MayThrow() const { return false; } |
| 6639 | 6609 |
| 6640 private: | 6610 private: |
| 6641 virtual void RawSetInputAt(intptr_t i, Value* value) { | 6611 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 6642 (*inputs_)[i] = value; | 6612 (*inputs_)[i] = value; |
| 6643 } | 6613 } |
| 6644 | 6614 |
| 6645 ZoneGrowableArray<Value*>* inputs_; | 6615 ZoneGrowableArray<Value*>* inputs_; |
| 6646 | 6616 |
| 6647 LocationSummary* locs_; | |
| 6648 | |
| 6649 const MethodRecognizer::Kind recognized_kind_; | 6617 const MethodRecognizer::Kind recognized_kind_; |
| 6650 | 6618 |
| 6651 DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr); | 6619 DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr); |
| 6652 }; | 6620 }; |
| 6653 | 6621 |
| 6654 | 6622 |
| 6655 class MergedMathInstr : public Definition { | 6623 class MergedMathInstr : public Definition { |
| 6656 public: | 6624 public: |
| 6657 enum Kind { | 6625 enum Kind { |
| 6658 kTruncDivMod, | 6626 kTruncDivMod, |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6721 } | 6689 } |
| 6722 | 6690 |
| 6723 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } | 6691 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } |
| 6724 | 6692 |
| 6725 // Returns the result index for one of the merged instructjons | 6693 // Returns the result index for one of the merged instructjons |
| 6726 static intptr_t ResultIndexOf(MethodRecognizer::Kind kind); | 6694 static intptr_t ResultIndexOf(MethodRecognizer::Kind kind); |
| 6727 static intptr_t ResultIndexOf(Token::Kind token); | 6695 static intptr_t ResultIndexOf(Token::Kind token); |
| 6728 | 6696 |
| 6729 DECLARE_INSTRUCTION(MergedMath) | 6697 DECLARE_INSTRUCTION(MergedMath) |
| 6730 | 6698 |
| 6731 // Returns a structure describing the location constraints required | |
| 6732 // to emit native code for this definition. | |
| 6733 LocationSummary* locs() { | |
| 6734 if (locs_ == NULL) { | |
| 6735 locs_ = MakeLocationSummary(); | |
| 6736 } | |
| 6737 return locs_; | |
| 6738 } | |
| 6739 | |
| 6740 virtual bool AllowsCSE() const { return true; } | 6699 virtual bool AllowsCSE() const { return true; } |
| 6741 virtual EffectSet Effects() const { return EffectSet::None(); } | 6700 virtual EffectSet Effects() const { return EffectSet::None(); } |
| 6742 virtual EffectSet Dependencies() const { return EffectSet::None(); } | 6701 virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| 6743 virtual bool AttributesEqual(Instruction* other) const { | 6702 virtual bool AttributesEqual(Instruction* other) const { |
| 6744 MergedMathInstr* other_invoke = other->AsMergedMath(); | 6703 MergedMathInstr* other_invoke = other->AsMergedMath(); |
| 6745 return other_invoke->kind() == kind(); | 6704 return other_invoke->kind() == kind(); |
| 6746 } | 6705 } |
| 6747 | 6706 |
| 6748 virtual bool MayThrow() const { return false; } | 6707 virtual bool MayThrow() const { return false; } |
| 6749 | 6708 |
| 6750 static const char* KindToCString(MergedMathInstr::Kind kind) { | 6709 static const char* KindToCString(MergedMathInstr::Kind kind) { |
| 6751 if (kind == kTruncDivMod) return "TruncDivMod"; | 6710 if (kind == kTruncDivMod) return "TruncDivMod"; |
| 6752 if (kind == kSinCos) return "SinCos"; | 6711 if (kind == kSinCos) return "SinCos"; |
| 6753 UNIMPLEMENTED(); | 6712 UNIMPLEMENTED(); |
| 6754 return ""; | 6713 return ""; |
| 6755 } | 6714 } |
| 6756 | 6715 |
| 6757 private: | 6716 private: |
| 6758 virtual void RawSetInputAt(intptr_t i, Value* value) { | 6717 virtual void RawSetInputAt(intptr_t i, Value* value) { |
| 6759 (*inputs_)[i] = value; | 6718 (*inputs_)[i] = value; |
| 6760 } | 6719 } |
| 6761 | 6720 |
| 6762 ZoneGrowableArray<Value*>* inputs_; | 6721 ZoneGrowableArray<Value*>* inputs_; |
| 6763 LocationSummary* locs_; | |
| 6764 MergedMathInstr::Kind kind_; | 6722 MergedMathInstr::Kind kind_; |
| 6765 | 6723 |
| 6766 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); | 6724 DISALLOW_COPY_AND_ASSIGN(MergedMathInstr); |
| 6767 }; | 6725 }; |
| 6768 | 6726 |
| 6769 | 6727 |
| 6770 class CheckClassInstr : public TemplateInstruction<1> { | 6728 class CheckClassInstr : public TemplateInstruction<1> { |
| 6771 public: | 6729 public: |
| 6772 CheckClassInstr(Value* value, | 6730 CheckClassInstr(Value* value, |
| 6773 intptr_t deopt_id, | 6731 intptr_t deopt_id, |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7096 ForwardInstructionIterator* current_iterator_; | 7054 ForwardInstructionIterator* current_iterator_; |
| 7097 | 7055 |
| 7098 private: | 7056 private: |
| 7099 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 7057 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 7100 }; | 7058 }; |
| 7101 | 7059 |
| 7102 | 7060 |
| 7103 } // namespace dart | 7061 } // namespace dart |
| 7104 | 7062 |
| 7105 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 7063 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |