Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 10824349: Implement class id checks as a separate instruction and add a local CSE optimization pass. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698