Chromium Code Reviews| 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" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 94 M(AllocateContext, AllocateContextComp) \ | 94 M(AllocateContext, AllocateContextComp) \ |
| 95 M(ChainContext, ChainContextComp) \ | 95 M(ChainContext, ChainContextComp) \ |
| 96 M(CloneContext, CloneContextComp) \ | 96 M(CloneContext, CloneContextComp) \ |
| 97 M(CatchEntry, CatchEntryComp) \ | 97 M(CatchEntry, CatchEntryComp) \ |
| 98 M(BinaryOp, BinaryOpComp) \ | 98 M(BinaryOp, BinaryOpComp) \ |
| 99 M(DoubleBinaryOp, DoubleBinaryOpComp) \ | 99 M(DoubleBinaryOp, DoubleBinaryOpComp) \ |
| 100 M(UnarySmiOp, UnarySmiOpComp) \ | 100 M(UnarySmiOp, UnarySmiOpComp) \ |
| 101 M(NumberNegate, NumberNegateComp) \ | 101 M(NumberNegate, NumberNegateComp) \ |
| 102 M(CheckStackOverflow, CheckStackOverflowComp) \ | 102 M(CheckStackOverflow, CheckStackOverflowComp) \ |
| 103 M(DoubleToDouble, DoubleToDoubleComp) \ | 103 M(DoubleToDouble, DoubleToDoubleComp) \ |
| 104 M(SmiToDouble, SmiToDoubleComp) | 104 M(SmiToDouble, SmiToDoubleComp) \ |
| 105 M(CheckClass, CheckClassComp) | |
| 105 | 106 |
| 106 | 107 |
| 107 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 108 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 108 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 109 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 109 #undef FORWARD_DECLARATION | 110 #undef FORWARD_DECLARATION |
| 110 | 111 |
| 111 // Forward declarations. | 112 // Forward declarations. |
| 112 class BindInstr; | 113 class BindInstr; |
| 113 class BranchInstr; | 114 class BranchInstr; |
| 114 class BufferFormatter; | 115 class BufferFormatter; |
| 115 class ComparisonComp; | 116 class ComparisonComp; |
| 116 class Definition; | 117 class Definition; |
| 117 class Instruction; | 118 class Instruction; |
| 118 class PushArgumentInstr; | 119 class PushArgumentInstr; |
| 119 class Value; | 120 class Value; |
| 120 | 121 |
| 121 class Computation : public ZoneAllocated { | 122 class Computation : public ZoneAllocated { |
| 122 public: | 123 public: |
| 123 Computation() : deopt_id_(Isolate::kNoDeoptId), ic_data_(NULL), locs_(NULL) { | 124 Computation() : deopt_id_(Isolate::kNoDeoptId), ic_data_(NULL), locs_(NULL) { |
| 124 Isolate* isolate = Isolate::Current(); | 125 Isolate* isolate = Isolate::Current(); |
| 125 deopt_id_ = isolate->GetNextDeoptId(); | 126 deopt_id_ = isolate->GetNextDeoptId(); |
| 126 ic_data_ = isolate->GetICDataForDeoptId(deopt_id_); | 127 ic_data_ = isolate->GetICDataForDeoptId(deopt_id_); |
| 127 } | 128 } |
| 128 | 129 |
| 129 // Unique id used for deoptimization. | 130 // Unique id used for deoptimization. |
| 130 intptr_t deopt_id() const { return deopt_id_; } | 131 intptr_t deopt_id() const { return deopt_id_; } |
| 131 | 132 |
| 132 ICData* ic_data() const { return ic_data_; } | 133 const ICData* ic_data() const { return ic_data_; } |
| 133 void set_ic_data(ICData* value) { ic_data_ = value; } | 134 void set_ic_data(const ICData* value) { ic_data_ = value; } |
| 134 bool HasICData() const { | 135 bool HasICData() const { |
| 135 return (ic_data() != NULL) && !ic_data()->IsNull(); | 136 return (ic_data() != NULL) && !ic_data()->IsNull(); |
| 136 } | 137 } |
| 137 | 138 |
| 138 // Visiting support. | 139 // Visiting support. |
| 139 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; | 140 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; |
| 140 | 141 |
| 141 virtual intptr_t InputCount() const = 0; | 142 virtual intptr_t InputCount() const = 0; |
| 142 virtual Value* InputAt(intptr_t i) const = 0; | 143 virtual Value* InputAt(intptr_t i) const = 0; |
| 143 virtual void SetInputAt(intptr_t i, Value* value) = 0; | 144 virtual void SetInputAt(intptr_t i, Value* value) = 0; |
| 144 | 145 |
| 145 // Call computations override this function and return the | 146 // Call computations override this function and return the |
| 146 // number of pushed arguments. | 147 // number of pushed arguments. |
| 147 virtual intptr_t ArgumentCount() const = 0; | 148 virtual intptr_t ArgumentCount() const = 0; |
| 148 | 149 |
| 149 // Returns true, if this computation can deoptimize. | 150 // Returns true, if this computation can deoptimize. |
| 150 virtual bool CanDeoptimize() const = 0; | 151 virtual bool CanDeoptimize() const = 0; |
| 151 | 152 |
| 152 // Optimize this computation. Returns a replacement for the instruction | 153 // Optimize this computation. Returns a replacement for the instruction |
| 153 // that wraps this computation or NULL if nothing to replace. | 154 // that wraps this computation or NULL if nothing to replace. |
| 154 virtual Definition* TryReplace(BindInstr* instr) { return NULL; } | 155 virtual Definition* TryReplace(BindInstr* instr) { return NULL; } |
| 155 | 156 |
| 157 // Functions to support CSE. | |
|
srdjan
2012/08/17 22:30:22
Please document these functions briefly.
Florian Schneider
2012/08/20 12:09:37
Done.
| |
| 158 bool Equals(Computation* other) const; | |
| 159 virtual intptr_t Hashcode() const; | |
| 160 virtual bool AttributesEqual(Computation* other) const { return true; } | |
| 161 virtual bool HasSideEffect() const { return true; } | |
| 162 | |
| 156 // Compile time type of the computation, which typically depends on the | 163 // Compile time type of the computation, which typically depends on the |
| 157 // compile time types (and possibly propagated types) of its inputs. | 164 // compile time types (and possibly propagated types) of its inputs. |
| 158 virtual RawAbstractType* CompileType() const = 0; | 165 virtual RawAbstractType* CompileType() const = 0; |
| 159 virtual intptr_t ResultCid() const { return kDynamicCid; } | 166 virtual intptr_t ResultCid() const { return kDynamicCid; } |
| 160 | 167 |
| 161 // Mutate assigned_vars to add the local variable index for all | 168 // Mutate assigned_vars to add the local variable index for all |
| 162 // frame-allocated locals assigned to by the computation. | 169 // frame-allocated locals assigned to by the computation. |
| 163 virtual void RecordAssignedVars(BitVector* assigned_vars, | 170 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 164 intptr_t fixed_parameter_count); | 171 intptr_t fixed_parameter_count); |
| 165 | 172 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 // Declare predicate for each computation. | 214 // Declare predicate for each computation. |
| 208 #define DECLARE_PREDICATE(ShortName, ClassName) \ | 215 #define DECLARE_PREDICATE(ShortName, ClassName) \ |
| 209 inline bool Is##ShortName() const; \ | 216 inline bool Is##ShortName() const; \ |
| 210 inline const ClassName* As##ShortName() const; \ | 217 inline const ClassName* As##ShortName() const; \ |
| 211 inline ClassName* As##ShortName(); | 218 inline ClassName* As##ShortName(); |
| 212 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | 219 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) |
| 213 #undef DECLARE_PREDICATE | 220 #undef DECLARE_PREDICATE |
| 214 | 221 |
| 215 private: | 222 private: |
| 216 intptr_t deopt_id_; | 223 intptr_t deopt_id_; |
| 217 ICData* ic_data_; | 224 const ICData* ic_data_; |
| 218 LocationSummary* locs_; | 225 LocationSummary* locs_; |
| 219 | 226 |
| 220 DISALLOW_COPY_AND_ASSIGN(Computation); | 227 DISALLOW_COPY_AND_ASSIGN(Computation); |
| 221 }; | 228 }; |
| 222 | 229 |
| 223 | 230 |
| 224 // An embedded container with N elements of type T. Used (with partial | 231 // An embedded container with N elements of type T. Used (with partial |
| 225 // specialization for N=0) because embedded arrays cannot have size 0. | 232 // specialization for N=0) because embedded arrays cannot have size 0. |
| 226 template<typename T, intptr_t N> | 233 template<typename T, intptr_t N> |
| 227 class EmbeddedArray { | 234 class EmbeddedArray { |
| (...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 } | 950 } |
| 944 | 951 |
| 945 DECLARE_COMPUTATION(LoadInstanceField) | 952 DECLARE_COMPUTATION(LoadInstanceField) |
| 946 | 953 |
| 947 const Field& field() const { return field_; } | 954 const Field& field() const { return field_; } |
| 948 Value* instance() const { return inputs_[0]; } | 955 Value* instance() const { return inputs_[0]; } |
| 949 const InstanceCallComp* original() const { return original_; } | 956 const InstanceCallComp* original() const { return original_; } |
| 950 | 957 |
| 951 virtual void PrintOperandsTo(BufferFormatter* f) const; | 958 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 952 | 959 |
| 953 virtual bool CanDeoptimize() const { return true; } | 960 virtual bool CanDeoptimize() const { return true; } |
|
srdjan
2012/08/17 22:30:22
Should this be false if we have added a CheckClass
Florian Schneider
2012/08/20 12:09:37
Yes. I'll add a TODO to change it when we remove t
| |
| 954 | 961 |
| 955 private: | 962 private: |
| 956 const Field& field_; | 963 const Field& field_; |
| 957 const InstanceCallComp* original_; // For optimizations. | 964 const InstanceCallComp* original_; // For optimizations. |
| 958 | 965 |
| 959 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); | 966 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); |
| 960 }; | 967 }; |
| 961 | 968 |
| 962 | 969 |
| 963 class StoreInstanceFieldComp : public TemplateComputation<2> { | 970 class StoreInstanceFieldComp : public TemplateComputation<2> { |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1766 virtual bool CanDeoptimize() const { return true; } | 1773 virtual bool CanDeoptimize() const { return true; } |
| 1767 virtual intptr_t ResultCid() const { return kDoubleCid; } | 1774 virtual intptr_t ResultCid() const { return kDoubleCid; } |
| 1768 | 1775 |
| 1769 private: | 1776 private: |
| 1770 InstanceCallComp* instance_call_; | 1777 InstanceCallComp* instance_call_; |
| 1771 | 1778 |
| 1772 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); | 1779 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); |
| 1773 }; | 1780 }; |
| 1774 | 1781 |
| 1775 | 1782 |
| 1783 class CheckClassComp : public TemplateComputation<1> { | |
|
srdjan
2012/08/17 22:30:22
Consider renaming it to CheckClassesComp since it
Florian Schneider
2012/08/20 12:09:37
Done.
| |
| 1784 public: | |
| 1785 CheckClassComp(Value* value, InstanceCallComp* original) | |
| 1786 : original_(original) { | |
| 1787 ASSERT(value != NULL); | |
| 1788 inputs_[0] = value; | |
| 1789 } | |
| 1790 | |
| 1791 DECLARE_COMPUTATION(CheckClass) | |
| 1792 | |
| 1793 virtual bool CanDeoptimize() const { return true; } | |
| 1794 | |
| 1795 virtual bool AttributesEqual(Computation* other) const; | |
| 1796 | |
| 1797 virtual bool HasSideEffect() const { return false; } | |
|
srdjan
2012/08/17 22:30:22
Why is CheckClassComp the only computation that do
Florian Schneider
2012/08/20 12:09:37
Currently only CheckClass participates in CSE, but
| |
| 1798 | |
| 1799 Value* value() const { return inputs_[0]; } | |
| 1800 | |
| 1801 intptr_t deopt_id() const { return original_->deopt_id(); } | |
| 1802 intptr_t try_index() const { return original_->try_index(); } | |
| 1803 | |
| 1804 private: | |
| 1805 InstanceCallComp* original_; | |
| 1806 | |
| 1807 DISALLOW_COPY_AND_ASSIGN(CheckClassComp); | |
| 1808 }; | |
| 1809 | |
| 1810 | |
| 1776 #undef DECLARE_COMPUTATION | 1811 #undef DECLARE_COMPUTATION |
| 1777 | 1812 |
| 1778 | 1813 |
| 1779 // Implementation of type testers and cast functins. | 1814 // Implementation of type testers and cast functins. |
| 1780 #define DEFINE_PREDICATE(ShortName, ClassName) \ | 1815 #define DEFINE_PREDICATE(ShortName, ClassName) \ |
| 1781 bool Computation::Is##ShortName() const { \ | 1816 bool Computation::Is##ShortName() const { \ |
| 1782 return computation_kind() == k##ShortName; \ | 1817 return computation_kind() == k##ShortName; \ |
| 1783 } \ | 1818 } \ |
| 1784 const ClassName* Computation::As##ShortName() const { \ | 1819 const ClassName* Computation::As##ShortName() const { \ |
| 1785 if (!Is##ShortName()) return NULL; \ | 1820 if (!Is##ShortName()) return NULL; \ |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1875 ASSERT(instr == NULL || !instr->IsBlockEntry()); | 1910 ASSERT(instr == NULL || !instr->IsBlockEntry()); |
| 1876 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions | 1911 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions |
| 1877 // that do not have a successor. Currently, the graph builder will continue | 1912 // that do not have a successor. Currently, the graph builder will continue |
| 1878 // to append instruction in case of a Throw inside an expression. This | 1913 // to append instruction in case of a Throw inside an expression. This |
| 1879 // condition should be handled in the graph builder | 1914 // condition should be handled in the graph builder |
| 1880 next_ = instr; | 1915 next_ = instr; |
| 1881 } | 1916 } |
| 1882 | 1917 |
| 1883 // Removed this instruction from the graph. | 1918 // Removed this instruction from the graph. |
| 1884 Instruction* RemoveFromGraph(bool return_previous = true); | 1919 Instruction* RemoveFromGraph(bool return_previous = true); |
| 1920 | |
| 1885 // Remove value uses within this instruction and its inputs. | 1921 // Remove value uses within this instruction and its inputs. |
| 1886 virtual void RemoveInputUses() = 0; | 1922 virtual void RemoveInputUses() = 0; |
| 1887 | 1923 |
| 1924 // Insert this instruction before 'next'. | |
| 1925 void InsertBefore(Instruction* next); | |
| 1926 | |
| 1888 // Normal instructions can have 0 (inside a block) or 1 (last instruction in | 1927 // Normal instructions can have 0 (inside a block) or 1 (last instruction in |
| 1889 // a block) successors. Branch instruction with >1 successors override this | 1928 // a block) successors. Branch instruction with >1 successors override this |
| 1890 // function. | 1929 // function. |
| 1891 virtual intptr_t SuccessorCount() const; | 1930 virtual intptr_t SuccessorCount() const; |
| 1892 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1931 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 1893 | 1932 |
| 1894 void Goto(JoinEntryInstr* entry); | 1933 void Goto(JoinEntryInstr* entry); |
| 1895 | 1934 |
| 1896 // Discover basic-block structure by performing a recursive depth first | 1935 // Discover basic-block structure by performing a recursive depth first |
| 1897 // traversal of the instruction graph reachable from this instruction. As | 1936 // traversal of the instruction graph reachable from this instruction. As |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2496 Computation* computation() const { return computation_; } | 2535 Computation* computation() const { return computation_; } |
| 2497 void set_computation(Computation* value) { computation_ = value; } | 2536 void set_computation(Computation* value) { computation_ = value; } |
| 2498 bool is_used() const { return is_used_; } | 2537 bool is_used() const { return is_used_; } |
| 2499 | 2538 |
| 2500 virtual RawAbstractType* CompileType() const; | 2539 virtual RawAbstractType* CompileType() const; |
| 2501 virtual intptr_t GetPropagatedCid(); | 2540 virtual intptr_t GetPropagatedCid(); |
| 2502 | 2541 |
| 2503 virtual void RecordAssignedVars(BitVector* assigned_vars, | 2542 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 2504 intptr_t fixed_parameter_count); | 2543 intptr_t fixed_parameter_count); |
| 2505 | 2544 |
| 2545 intptr_t Hashcode() const { return computation()->Hashcode(); } | |
| 2546 | |
| 2547 bool Equals(BindInstr* other) const { | |
| 2548 return computation()->Equals(other->computation()); | |
| 2549 } | |
| 2550 | |
| 2506 virtual LocationSummary* locs() { | 2551 virtual LocationSummary* locs() { |
| 2507 return computation()->locs(); | 2552 return computation()->locs(); |
| 2508 } | 2553 } |
| 2509 | 2554 |
| 2510 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2555 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 2511 | 2556 |
| 2512 virtual void RemoveInputUses() { computation()->RemoveInputUses(); } | 2557 virtual void RemoveInputUses() { computation()->RemoveInputUses(); } |
| 2513 | 2558 |
| 2514 private: | 2559 private: |
| 2515 Computation* computation_; | 2560 Computation* computation_; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2964 ForwardInstructionIterator* current_iterator_; | 3009 ForwardInstructionIterator* current_iterator_; |
| 2965 | 3010 |
| 2966 private: | 3011 private: |
| 2967 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3012 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 2968 }; | 3013 }; |
| 2969 | 3014 |
| 2970 | 3015 |
| 2971 } // namespace dart | 3016 } // namespace dart |
| 2972 | 3017 |
| 2973 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3018 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |