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 |