OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 5 #ifndef V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
6 #define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 6 #define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
7 | 7 |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/bytecode-branch-analysis.h" | |
9 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
10 #include "src/interpreter/bytecode-array-iterator.h" | 11 #include "src/interpreter/bytecode-array-iterator.h" |
11 #include "src/interpreter/bytecodes.h" | 12 #include "src/interpreter/bytecodes.h" |
12 | 13 |
13 namespace v8 { | 14 namespace v8 { |
14 namespace internal { | 15 namespace internal { |
15 namespace compiler { | 16 namespace compiler { |
16 | 17 |
17 // The BytecodeGraphBuilder produces a high-level IR graph based on | 18 // The BytecodeGraphBuilder produces a high-level IR graph based on |
18 // interpreter bytecodes. | 19 // interpreter bytecodes. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) { | 83 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) { |
83 Node* buffer[] = {n1, n2, n3}; | 84 Node* buffer[] = {n1, n2, n3}; |
84 return MakeNode(op, arraysize(buffer), buffer, false); | 85 return MakeNode(op, arraysize(buffer), buffer, false); |
85 } | 86 } |
86 | 87 |
87 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) { | 88 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) { |
88 Node* buffer[] = {n1, n2, n3, n4}; | 89 Node* buffer[] = {n1, n2, n3, n4}; |
89 return MakeNode(op, arraysize(buffer), buffer, false); | 90 return MakeNode(op, arraysize(buffer), buffer, false); |
90 } | 91 } |
91 | 92 |
93 // Helpers to create new control nodes. | |
94 Node* NewIfTrue() { return NewNode(common()->IfTrue()); } | |
95 Node* NewIfFalse() { return NewNode(common()->IfFalse()); } | |
96 Node* NewMerge() { return NewNode(common()->Merge(1), true); } | |
97 Node* NewLoop() { return NewNode(common()->Loop(1), true); } | |
98 Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) { | |
99 return NewNode(common()->Branch(hint), condition); | |
100 } | |
101 | |
102 // Creates a new Phi node having {count} input values. | |
103 Node* NewPhi(int count, Node* input, Node* control); | |
104 Node* NewEffectPhi(int count, Node* input, Node* control); | |
105 | |
106 // Helpers for merging control, effect or value dependencies. | |
107 Node* MergeControl(Node* control, Node* other); | |
108 Node* MergeEffect(Node* effect, Node* other_effect, Node* control); | |
109 Node* MergeValue(Node* value, Node* other_value, Node* control); | |
110 | |
111 // The main node creation chokepoint. Adds context, frame state, effect, | |
112 // and control dependencies depending on the operator. | |
92 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, | 113 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, |
93 bool incomplete); | 114 bool incomplete); |
94 | 115 |
95 Node* MergeControl(Node* control, Node* other); | 116 // Helper to indicate a node exits the function body. |
117 void UpdateControlDependencyToLeaveFunction(Node* exit); | |
96 | 118 |
97 Node** EnsureInputBufferSize(int size); | 119 Node** EnsureInputBufferSize(int size); |
98 | 120 |
99 void UpdateControlDependencyToLeaveFunction(Node* exit); | |
100 | |
101 Node* ProcessCallArguments(const Operator* call_op, Node* callee, | 121 Node* ProcessCallArguments(const Operator* call_op, Node* callee, |
102 interpreter::Register receiver, size_t arity); | 122 interpreter::Register receiver, size_t arity); |
103 Node* ProcessCallNewArguments(const Operator* call_new_op, | 123 Node* ProcessCallNewArguments(const Operator* call_new_op, |
104 interpreter::Register callee, | 124 interpreter::Register callee, |
105 interpreter::Register first_arg, size_t arity); | 125 interpreter::Register first_arg, size_t arity); |
106 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, | 126 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, |
107 interpreter::Register first_arg, | 127 interpreter::Register first_arg, |
108 size_t arity); | 128 size_t arity); |
109 | 129 |
110 void BuildCreateLiteral(const Operator* op); | 130 void BuildCreateLiteral(const Operator* op); |
(...skipping 12 matching lines...) Expand all Loading... | |
123 void BuildKeyedStore(const interpreter::BytecodeArrayIterator& iterator); | 143 void BuildKeyedStore(const interpreter::BytecodeArrayIterator& iterator); |
124 void BuildCall(const interpreter::BytecodeArrayIterator& iterator); | 144 void BuildCall(const interpreter::BytecodeArrayIterator& iterator); |
125 void BuildBinaryOp(const Operator* op, | 145 void BuildBinaryOp(const Operator* op, |
126 const interpreter::BytecodeArrayIterator& iterator); | 146 const interpreter::BytecodeArrayIterator& iterator); |
127 void BuildCompareOp(const Operator* op, | 147 void BuildCompareOp(const Operator* op, |
128 const interpreter::BytecodeArrayIterator& iterator); | 148 const interpreter::BytecodeArrayIterator& iterator); |
129 void BuildDelete(const interpreter::BytecodeArrayIterator& iterator); | 149 void BuildDelete(const interpreter::BytecodeArrayIterator& iterator); |
130 void BuildCastOperator(const Operator* js_op, | 150 void BuildCastOperator(const Operator* js_op, |
131 const interpreter::BytecodeArrayIterator& iterator); | 151 const interpreter::BytecodeArrayIterator& iterator); |
132 | 152 |
153 // Control flow plumbing. | |
154 void BuildJump(int source_offset, int target_offset); | |
155 void BuildJump(); | |
156 void BuildConditionalJump(Node* condition); | |
157 | |
158 // Helpers for building conditions for conditional jumps | |
159 Node* BuildJumpCondition(Node* comperand); | |
160 Node* BuildToBooleanJumpCondition(Node* comperand); | |
rmcilroy
2015/12/15 17:35:43
Drop the "Jump" from these functions - they don't
oth
2015/12/15 22:42:17
Done.
| |
161 | |
162 // Constructing merge and loop headers. | |
163 void ApplyBranchAnalysis(const BytecodeBranchAnalysis* analysis); | |
164 | |
133 // Growth increment for the temporary buffer used to construct input lists to | 165 // Growth increment for the temporary buffer used to construct input lists to |
134 // new nodes. | 166 // new nodes. |
135 static const int kInputBufferSizeIncrement = 64; | 167 static const int kInputBufferSizeIncrement = 64; |
136 | 168 |
137 // Field accessors | 169 // Field accessors |
138 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 170 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
139 Zone* graph_zone() const { return graph()->zone(); } | 171 Zone* graph_zone() const { return graph()->zone(); } |
140 CompilationInfo* info() const { return info_; } | 172 CompilationInfo* info() const { return info_; } |
141 JSGraph* jsgraph() const { return jsgraph_; } | 173 JSGraph* jsgraph() const { return jsgraph_; } |
142 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } | 174 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } |
143 Zone* local_zone() const { return local_zone_; } | 175 Zone* local_zone() const { return local_zone_; } |
144 const Handle<BytecodeArray>& bytecode_array() const { | 176 const Handle<BytecodeArray>& bytecode_array() const { |
145 return bytecode_array_; | 177 return bytecode_array_; |
146 } | 178 } |
147 | 179 |
148 LanguageMode language_mode() const { | 180 LanguageMode language_mode() const { |
149 // TODO(mythria): Don't rely on parse information to get language mode. | 181 // TODO(mythria): Don't rely on parse information to get language mode. |
150 return info()->language_mode(); | 182 return info()->language_mode(); |
151 } | 183 } |
152 | 184 |
185 const interpreter::BytecodeArrayIterator* bytecode_iterator() const { | |
186 return bytecode_iterator_; | |
187 } | |
188 | |
189 void set_bytecode_iterator( | |
190 const interpreter::BytecodeArrayIterator* bytecode_iterator) { | |
191 bytecode_iterator_ = bytecode_iterator; | |
192 } | |
193 | |
194 const BytecodeBranchAnalysis* branch_analysis() const { | |
195 return branch_analysis_; | |
196 } | |
197 | |
198 void set_branch_analysis(const BytecodeBranchAnalysis* branch_analysis) { | |
199 branch_analysis_ = branch_analysis; | |
200 } | |
201 | |
153 #define DECLARE_VISIT_BYTECODE(name, ...) \ | 202 #define DECLARE_VISIT_BYTECODE(name, ...) \ |
154 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); | 203 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); |
155 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) | 204 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) |
156 #undef DECLARE_VISIT_BYTECODE | 205 #undef DECLARE_VISIT_BYTECODE |
157 | 206 |
158 Zone* local_zone_; | 207 Zone* local_zone_; |
159 CompilationInfo* info_; | 208 CompilationInfo* info_; |
160 JSGraph* jsgraph_; | 209 JSGraph* jsgraph_; |
161 Handle<BytecodeArray> bytecode_array_; | 210 Handle<BytecodeArray> bytecode_array_; |
211 const interpreter::BytecodeArrayIterator* bytecode_iterator_; | |
212 const BytecodeBranchAnalysis* branch_analysis_; | |
162 Environment* environment_; | 213 Environment* environment_; |
163 | 214 |
215 // Merge environments are snapshots of the environment at a particular | |
216 // bytecode offset to be merged into a later environment. | |
217 ZoneMap<int, Environment*> merge_environments_; | |
218 | |
219 // Loop header environments are environments created for bytecodes | |
220 // where it is known there are back branches, ie a loop header. | |
221 ZoneMap<int, Environment*> loop_header_environments_; | |
222 | |
164 // Temporary storage for building node input lists. | 223 // Temporary storage for building node input lists. |
165 int input_buffer_size_; | 224 int input_buffer_size_; |
166 Node** input_buffer_; | 225 Node** input_buffer_; |
167 | 226 |
168 // Nodes representing values in the activation record. | 227 // Nodes representing values in the activation record. |
169 SetOncePointer<Node> function_context_; | 228 SetOncePointer<Node> function_context_; |
170 SetOncePointer<Node> function_closure_; | 229 SetOncePointer<Node> function_closure_; |
171 SetOncePointer<Node> new_target_; | 230 SetOncePointer<Node> new_target_; |
172 | 231 |
173 // Optimization to cache loaded feedback vector. | 232 // Optimization to cache loaded feedback vector. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 | 264 |
206 // Control dependency tracked by this environment. | 265 // Control dependency tracked by this environment. |
207 Node* GetControlDependency() const { return control_dependency_; } | 266 Node* GetControlDependency() const { return control_dependency_; } |
208 void UpdateControlDependency(Node* dependency) { | 267 void UpdateControlDependency(Node* dependency) { |
209 control_dependency_ = dependency; | 268 control_dependency_ = dependency; |
210 } | 269 } |
211 | 270 |
212 Node* Context() const { return context_; } | 271 Node* Context() const { return context_; } |
213 void SetContext(Node* new_context) { context_ = new_context; } | 272 void SetContext(Node* new_context) { context_ = new_context; } |
214 | 273 |
274 Environment* CopyForConditional() const; | |
275 Environment* CopyForLoop(); | |
276 void Merge(Environment* other); | |
277 | |
215 private: | 278 private: |
279 explicit Environment(const Environment* copy); | |
280 void PrepareForLoop(); | |
281 | |
216 int RegisterToValuesIndex(interpreter::Register the_register) const; | 282 int RegisterToValuesIndex(interpreter::Register the_register) const; |
217 | |
218 Zone* zone() const { return builder_->local_zone(); } | 283 Zone* zone() const { return builder_->local_zone(); } |
219 Graph* graph() const { return builder_->graph(); } | 284 Graph* graph() const { return builder_->graph(); } |
220 CommonOperatorBuilder* common() const { return builder_->common(); } | 285 CommonOperatorBuilder* common() const { return builder_->common(); } |
221 BytecodeGraphBuilder* builder() const { return builder_; } | 286 BytecodeGraphBuilder* builder() const { return builder_; } |
222 const NodeVector* values() const { return &values_; } | 287 const NodeVector* values() const { return &values_; } |
223 NodeVector* values() { return &values_; } | 288 NodeVector* values() { return &values_; } |
224 Node* accumulator() { return accumulator_; } | 289 Node* accumulator() { return accumulator_; } |
225 int register_base() const { return register_base_; } | 290 int register_base() const { return register_base_; } |
226 | 291 |
227 BytecodeGraphBuilder* builder_; | 292 BytecodeGraphBuilder* builder_; |
228 int register_count_; | 293 int register_count_; |
229 int parameter_count_; | 294 int parameter_count_; |
230 Node* accumulator_; | 295 Node* accumulator_; |
231 Node* context_; | 296 Node* context_; |
232 Node* control_dependency_; | 297 Node* control_dependency_; |
233 Node* effect_dependency_; | 298 Node* effect_dependency_; |
234 NodeVector values_; | 299 NodeVector values_; |
235 int register_base_; | 300 int register_base_; |
236 }; | 301 }; |
237 | 302 |
238 | |
239 } // namespace compiler | 303 } // namespace compiler |
240 } // namespace internal | 304 } // namespace internal |
241 } // namespace v8 | 305 } // namespace v8 |
242 | 306 |
243 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 307 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
OLD | NEW |