| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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" |
| 11 #include "vm/handles_impl.h" | 11 #include "vm/handles_impl.h" |
| 12 #include "vm/locations.h" | 12 #include "vm/locations.h" |
| 13 #include "vm/object.h" | 13 #include "vm/object.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 class BitVector; | 17 class BitVector; |
| 18 class BlockEntryInstr; | 18 class BlockEntryInstr; |
| 19 class BufferFormatter; | 19 class BufferFormatter; |
| 20 class ComparisonInstr; | 20 class ComparisonInstr; |
| 21 class ControlInstruction; | 21 class ControlInstruction; |
| 22 class Definition; | 22 class Definition; |
| 23 class Environment; | 23 class Environment; |
| 24 class FlowGraphCompiler; | 24 class FlowGraphCompiler; |
| 25 class FlowGraphVisitor; | 25 class FlowGraphVisitor; |
| 26 class Instruction; | 26 class Instruction; |
| 27 class LocalVariable; | 27 class LocalVariable; |
| 28 class Range; | 28 class Range; |
| 29 class FlowGraphOptimizer; |
| 29 | 30 |
| 30 | 31 |
| 31 // TODO(srdjan): Add _ByteArrayBase, get:length. | 32 // TODO(srdjan): Add _ByteArrayBase, get:length. |
| 32 // TODO(srdjan): Unify with INTRINSIC_LIST. | 33 // TODO(srdjan): Unify with INTRINSIC_LIST. |
| 33 // (class-name, function-name, recognized enum, fingerprint). | 34 // (class-name, function-name, recognized enum, fingerprint). |
| 34 // See intrinsifier for fingerprint computation. | 35 // See intrinsifier for fingerprint computation. |
| 35 #define RECOGNIZED_LIST(V) \ | 36 #define RECOGNIZED_LIST(V) \ |
| 36 V(_ObjectArray, get:length, ObjectArrayLength, 405297088) \ | 37 V(_ObjectArray, get:length, ObjectArrayLength, 405297088) \ |
| 37 V(_ImmutableArray, get:length, ImmutableArrayLength, 433698233) \ | 38 V(_ImmutableArray, get:length, ImmutableArrayLength, 433698233) \ |
| 38 V(_GrowableObjectArray, get:length, GrowableArrayLength, 725548050) \ | 39 V(_GrowableObjectArray, get:length, GrowableArrayLength, 725548050) \ |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 // that input operands conversions inserted for this instruction can jump | 463 // that input operands conversions inserted for this instruction can jump |
| 463 // to. | 464 // to. |
| 464 virtual intptr_t DeoptimizationTarget() const { | 465 virtual intptr_t DeoptimizationTarget() const { |
| 465 UNREACHABLE(); | 466 UNREACHABLE(); |
| 466 return Isolate::kNoDeoptId; | 467 return Isolate::kNoDeoptId; |
| 467 } | 468 } |
| 468 | 469 |
| 469 // Returns a replacement for the instruction or NULL if the instruction can | 470 // Returns a replacement for the instruction or NULL if the instruction can |
| 470 // be eliminated. By default returns the this instruction which means no | 471 // be eliminated. By default returns the this instruction which means no |
| 471 // change. | 472 // change. |
| 472 virtual Instruction* Canonicalize(); | 473 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); |
| 473 | 474 |
| 474 // Insert this instruction before 'next'. | 475 // Insert this instruction before 'next'. |
| 475 void InsertBefore(Instruction* next); | 476 void InsertBefore(Instruction* next); |
| 476 | 477 |
| 477 // Insert this instruction after 'prev'. | 478 // Insert this instruction after 'prev'. |
| 478 void InsertAfter(Instruction* prev); | 479 void InsertAfter(Instruction* prev); |
| 479 | 480 |
| 480 // Returns true if the instruction is affected by side effects. | 481 // Returns true if the instruction is affected by side effects. |
| 481 // Only instructions that are not affected by side effects can participate | 482 // Only instructions that are not affected by side effects can participate |
| 482 // in redundancy elimination or loop invariant code motion. | 483 // in redundancy elimination or loop invariant code motion. |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 // - unknown sentinel | 1130 // - unknown sentinel |
| 1130 Object& constant_value() const { return constant_value_; } | 1131 Object& constant_value() const { return constant_value_; } |
| 1131 | 1132 |
| 1132 virtual void InferRange(); | 1133 virtual void InferRange(); |
| 1133 | 1134 |
| 1134 Range* range() const { return range_; } | 1135 Range* range() const { return range_; } |
| 1135 | 1136 |
| 1136 // Definitions can be canonicalized only into definitions to ensure | 1137 // Definitions can be canonicalized only into definitions to ensure |
| 1137 // this check statically we override base Canonicalize with a Canonicalize | 1138 // this check statically we override base Canonicalize with a Canonicalize |
| 1138 // returning Definition (return type is covariant). | 1139 // returning Definition (return type is covariant). |
| 1139 virtual Definition* Canonicalize(); | 1140 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); |
| 1140 | 1141 |
| 1141 protected: | 1142 protected: |
| 1142 friend class RangeAnalysis; | 1143 friend class RangeAnalysis; |
| 1143 | 1144 |
| 1144 Range* range_; | 1145 Range* range_; |
| 1145 | 1146 |
| 1146 private: | 1147 private: |
| 1147 intptr_t temp_index_; | 1148 intptr_t temp_index_; |
| 1148 intptr_t ssa_temp_index_; | 1149 intptr_t ssa_temp_index_; |
| 1149 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; | 1150 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 | 1843 |
| 1843 class AssertAssignableInstr : public TemplateDefinition<3> { | 1844 class AssertAssignableInstr : public TemplateDefinition<3> { |
| 1844 public: | 1845 public: |
| 1845 AssertAssignableInstr(intptr_t token_pos, | 1846 AssertAssignableInstr(intptr_t token_pos, |
| 1846 Value* value, | 1847 Value* value, |
| 1847 Value* instantiator, | 1848 Value* instantiator, |
| 1848 Value* instantiator_type_arguments, | 1849 Value* instantiator_type_arguments, |
| 1849 const AbstractType& dst_type, | 1850 const AbstractType& dst_type, |
| 1850 const String& dst_name) | 1851 const String& dst_name) |
| 1851 : token_pos_(token_pos), | 1852 : token_pos_(token_pos), |
| 1852 dst_type_(dst_type), | 1853 dst_type_(AbstractType::ZoneHandle(dst_type.raw())), |
| 1853 dst_name_(dst_name), | 1854 dst_name_(dst_name), |
| 1854 is_eliminated_(false) { | 1855 is_eliminated_(false) { |
| 1855 ASSERT(value != NULL); | 1856 ASSERT(value != NULL); |
| 1856 ASSERT(instantiator != NULL); | 1857 ASSERT(instantiator != NULL); |
| 1857 ASSERT(instantiator_type_arguments != NULL); | 1858 ASSERT(instantiator_type_arguments != NULL); |
| 1858 ASSERT(!dst_type.IsNull()); | 1859 ASSERT(!dst_type.IsNull()); |
| 1859 ASSERT(!dst_name.IsNull()); | 1860 ASSERT(!dst_name.IsNull()); |
| 1860 inputs_[0] = value; | 1861 inputs_[0] = value; |
| 1861 inputs_[1] = instantiator; | 1862 inputs_[1] = instantiator; |
| 1862 inputs_[2] = instantiator_type_arguments; | 1863 inputs_[2] = instantiator_type_arguments; |
| 1863 } | 1864 } |
| 1864 | 1865 |
| 1865 DECLARE_INSTRUCTION(AssertAssignable) | 1866 DECLARE_INSTRUCTION(AssertAssignable) |
| 1866 virtual RawAbstractType* CompileType() const; | 1867 virtual RawAbstractType* CompileType() const; |
| 1867 | 1868 |
| 1868 Value* value() const { return inputs_[0]; } | 1869 Value* value() const { return inputs_[0]; } |
| 1869 Value* instantiator() const { return inputs_[1]; } | 1870 Value* instantiator() const { return inputs_[1]; } |
| 1870 Value* instantiator_type_arguments() const { return inputs_[2]; } | 1871 Value* instantiator_type_arguments() const { return inputs_[2]; } |
| 1871 | 1872 |
| 1872 intptr_t token_pos() const { return token_pos_; } | 1873 intptr_t token_pos() const { return token_pos_; } |
| 1873 const AbstractType& dst_type() const { return dst_type_; } | 1874 const AbstractType& dst_type() const { return dst_type_; } |
| 1875 void set_dst_type(const AbstractType& dst_type) { |
| 1876 dst_type_ = dst_type.raw(); |
| 1877 } |
| 1874 const String& dst_name() const { return dst_name_; } | 1878 const String& dst_name() const { return dst_name_; } |
| 1875 | 1879 |
| 1876 bool is_eliminated() const { | 1880 bool is_eliminated() const { |
| 1877 return is_eliminated_; | 1881 return is_eliminated_; |
| 1878 } | 1882 } |
| 1879 void eliminate() { | 1883 void eliminate() { |
| 1880 ASSERT(!is_eliminated_); | 1884 ASSERT(!is_eliminated_); |
| 1881 is_eliminated_ = true; | 1885 is_eliminated_ = true; |
| 1882 } | 1886 } |
| 1883 | 1887 |
| 1884 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1888 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1885 | 1889 |
| 1886 virtual bool CanDeoptimize() const { return false; } | 1890 virtual bool CanDeoptimize() const { return false; } |
| 1887 | 1891 |
| 1888 virtual bool HasSideEffect() const { return false; } | 1892 virtual bool HasSideEffect() const { return false; } |
| 1889 | 1893 |
| 1890 virtual bool AffectedBySideEffect() const { return false; } | 1894 virtual bool AffectedBySideEffect() const { return false; } |
| 1891 virtual bool AttributesEqual(Instruction* other) const; | 1895 virtual bool AttributesEqual(Instruction* other) const; |
| 1892 | 1896 |
| 1893 virtual intptr_t ResultCid() const { return value()->ResultCid(); } | 1897 virtual intptr_t ResultCid() const { return value()->ResultCid(); } |
| 1894 virtual intptr_t GetPropagatedCid(); | 1898 virtual intptr_t GetPropagatedCid(); |
| 1895 | 1899 |
| 1896 virtual Definition* Canonicalize(); | 1900 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); |
| 1897 | 1901 |
| 1898 private: | 1902 private: |
| 1899 const intptr_t token_pos_; | 1903 const intptr_t token_pos_; |
| 1900 const AbstractType& dst_type_; | 1904 AbstractType& dst_type_; |
| 1901 const String& dst_name_; | 1905 const String& dst_name_; |
| 1902 bool is_eliminated_; | 1906 bool is_eliminated_; |
| 1903 | 1907 |
| 1904 DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr); | 1908 DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr); |
| 1905 }; | 1909 }; |
| 1906 | 1910 |
| 1907 | 1911 |
| 1908 class AssertBooleanInstr : public TemplateDefinition<1> { | 1912 class AssertBooleanInstr : public TemplateDefinition<1> { |
| 1909 public: | 1913 public: |
| 1910 AssertBooleanInstr(intptr_t token_pos, Value* value) | 1914 AssertBooleanInstr(intptr_t token_pos, Value* value) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1932 | 1936 |
| 1933 virtual bool CanDeoptimize() const { return false; } | 1937 virtual bool CanDeoptimize() const { return false; } |
| 1934 | 1938 |
| 1935 virtual bool HasSideEffect() const { return false; } | 1939 virtual bool HasSideEffect() const { return false; } |
| 1936 | 1940 |
| 1937 virtual bool AffectedBySideEffect() const { return false; } | 1941 virtual bool AffectedBySideEffect() const { return false; } |
| 1938 virtual bool AttributesEqual(Instruction* other) const { return true; } | 1942 virtual bool AttributesEqual(Instruction* other) const { return true; } |
| 1939 | 1943 |
| 1940 virtual intptr_t ResultCid() const { return kBoolCid; } | 1944 virtual intptr_t ResultCid() const { return kBoolCid; } |
| 1941 | 1945 |
| 1942 virtual Definition* Canonicalize(); | 1946 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); |
| 1943 | 1947 |
| 1944 private: | 1948 private: |
| 1945 const intptr_t token_pos_; | 1949 const intptr_t token_pos_; |
| 1946 bool is_eliminated_; | 1950 bool is_eliminated_; |
| 1947 | 1951 |
| 1948 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); | 1952 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); |
| 1949 }; | 1953 }; |
| 1950 | 1954 |
| 1951 | 1955 |
| 1952 class ArgumentDefinitionTestInstr : public TemplateDefinition<1> { | 1956 class ArgumentDefinitionTestInstr : public TemplateDefinition<1> { |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2241 | 2245 |
| 2242 virtual void PrintOperandsTo(BufferFormatter* f) const; | 2246 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 2243 | 2247 |
| 2244 virtual bool CanDeoptimize() const { return false; } | 2248 virtual bool CanDeoptimize() const { return false; } |
| 2245 | 2249 |
| 2246 virtual bool HasSideEffect() const { return false; } | 2250 virtual bool HasSideEffect() const { return false; } |
| 2247 | 2251 |
| 2248 virtual bool AttributesEqual(Instruction* other) const; | 2252 virtual bool AttributesEqual(Instruction* other) const; |
| 2249 virtual bool AffectedBySideEffect() const { return false; } | 2253 virtual bool AffectedBySideEffect() const { return false; } |
| 2250 | 2254 |
| 2251 virtual Definition* Canonicalize(); | 2255 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); |
| 2252 | 2256 |
| 2253 virtual intptr_t ResultCid() const { return kBoolCid; } | 2257 virtual intptr_t ResultCid() const { return kBoolCid; } |
| 2254 | 2258 |
| 2255 virtual void EmitBranchCode(FlowGraphCompiler* compiler, | 2259 virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
| 2256 BranchInstr* branch); | 2260 BranchInstr* branch); |
| 2257 | 2261 |
| 2258 bool needs_number_check() const { return needs_number_check_; } | 2262 bool needs_number_check() const { return needs_number_check_; } |
| 2259 void set_needs_number_check(bool value) { needs_number_check_ = value; } | 2263 void set_needs_number_check(bool value) { needs_number_check_ = value; } |
| 2260 | 2264 |
| 2261 private: | 2265 private: |
| (...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3380 virtual bool HasSideEffect() const { return false; } | 3384 virtual bool HasSideEffect() const { return false; } |
| 3381 | 3385 |
| 3382 virtual bool AttributesEqual(Instruction* other) const { return true; } | 3386 virtual bool AttributesEqual(Instruction* other) const { return true; } |
| 3383 | 3387 |
| 3384 virtual bool AffectedBySideEffect() const { return false; } | 3388 virtual bool AffectedBySideEffect() const { return false; } |
| 3385 | 3389 |
| 3386 Value* left() const { return inputs_[0]; } | 3390 Value* left() const { return inputs_[0]; } |
| 3387 | 3391 |
| 3388 Value* right() const { return inputs_[1]; } | 3392 Value* right() const { return inputs_[1]; } |
| 3389 | 3393 |
| 3390 virtual Instruction* Canonicalize(); | 3394 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); |
| 3391 | 3395 |
| 3392 private: | 3396 private: |
| 3393 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr); | 3397 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr); |
| 3394 }; | 3398 }; |
| 3395 | 3399 |
| 3396 | 3400 |
| 3397 class BoxDoubleInstr : public TemplateDefinition<1> { | 3401 class BoxDoubleInstr : public TemplateDefinition<1> { |
| 3398 public: | 3402 public: |
| 3399 BoxDoubleInstr(Value* value, InstanceCallInstr* instance_call) | 3403 BoxDoubleInstr(Value* value, InstanceCallInstr* instance_call) |
| 3400 : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) { | 3404 : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) { |
| (...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3992 virtual bool HasSideEffect() const { return false; } | 3996 virtual bool HasSideEffect() const { return false; } |
| 3993 | 3997 |
| 3994 virtual bool AttributesEqual(Instruction* other) const; | 3998 virtual bool AttributesEqual(Instruction* other) const; |
| 3995 | 3999 |
| 3996 virtual bool AffectedBySideEffect() const { return false; } | 4000 virtual bool AffectedBySideEffect() const { return false; } |
| 3997 | 4001 |
| 3998 Value* value() const { return inputs_[0]; } | 4002 Value* value() const { return inputs_[0]; } |
| 3999 | 4003 |
| 4000 const ICData& unary_checks() const { return unary_checks_; } | 4004 const ICData& unary_checks() const { return unary_checks_; } |
| 4001 | 4005 |
| 4002 virtual Instruction* Canonicalize(); | 4006 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); |
| 4003 | 4007 |
| 4004 virtual void PrintOperandsTo(BufferFormatter* f) const; | 4008 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 4005 | 4009 |
| 4006 private: | 4010 private: |
| 4007 const ICData& unary_checks_; | 4011 const ICData& unary_checks_; |
| 4008 | 4012 |
| 4009 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); | 4013 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); |
| 4010 }; | 4014 }; |
| 4011 | 4015 |
| 4012 | 4016 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4025 virtual intptr_t ArgumentCount() const { return 0; } | 4029 virtual intptr_t ArgumentCount() const { return 0; } |
| 4026 | 4030 |
| 4027 virtual bool CanDeoptimize() const { return true; } | 4031 virtual bool CanDeoptimize() const { return true; } |
| 4028 | 4032 |
| 4029 virtual bool HasSideEffect() const { return false; } | 4033 virtual bool HasSideEffect() const { return false; } |
| 4030 | 4034 |
| 4031 virtual bool AttributesEqual(Instruction* other) const { return true; } | 4035 virtual bool AttributesEqual(Instruction* other) const { return true; } |
| 4032 | 4036 |
| 4033 virtual bool AffectedBySideEffect() const { return false; } | 4037 virtual bool AffectedBySideEffect() const { return false; } |
| 4034 | 4038 |
| 4035 virtual Instruction* Canonicalize(); | 4039 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); |
| 4036 | 4040 |
| 4037 Value* value() const { return inputs_[0]; } | 4041 Value* value() const { return inputs_[0]; } |
| 4038 | 4042 |
| 4039 private: | 4043 private: |
| 4040 DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr); | 4044 DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr); |
| 4041 }; | 4045 }; |
| 4042 | 4046 |
| 4043 | 4047 |
| 4044 class CheckArrayBoundInstr : public TemplateInstruction<2> { | 4048 class CheckArrayBoundInstr : public TemplateInstruction<2> { |
| 4045 public: | 4049 public: |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4292 ForwardInstructionIterator* current_iterator_; | 4296 ForwardInstructionIterator* current_iterator_; |
| 4293 | 4297 |
| 4294 private: | 4298 private: |
| 4295 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 4299 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 4296 }; | 4300 }; |
| 4297 | 4301 |
| 4298 | 4302 |
| 4299 } // namespace dart | 4303 } // namespace dart |
| 4300 | 4304 |
| 4301 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 4305 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |