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 |