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* BuildCondition(Node* comperand); |
| 160 Node* BuildToBooleanCondition(Node* comperand); |
| 161 |
| 162 // Constructing merge and loop headers. |
| 163 void MergeEnvironmentsOfBackwardBranches(int source_offset, |
| 164 int target_offset); |
| 165 void MergeEnvironmentsOfForwardBranches(int source_offset); |
| 166 void BuildLoopHeaderForBackwardBranches(int source_offset); |
| 167 |
133 // Growth increment for the temporary buffer used to construct input lists to | 168 // Growth increment for the temporary buffer used to construct input lists to |
134 // new nodes. | 169 // new nodes. |
135 static const int kInputBufferSizeIncrement = 64; | 170 static const int kInputBufferSizeIncrement = 64; |
136 | 171 |
137 // Field accessors | 172 // Field accessors |
138 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 173 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
139 Zone* graph_zone() const { return graph()->zone(); } | 174 Zone* graph_zone() const { return graph()->zone(); } |
140 CompilationInfo* info() const { return info_; } | 175 CompilationInfo* info() const { return info_; } |
141 JSGraph* jsgraph() const { return jsgraph_; } | 176 JSGraph* jsgraph() const { return jsgraph_; } |
142 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } | 177 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } |
143 Zone* local_zone() const { return local_zone_; } | 178 Zone* local_zone() const { return local_zone_; } |
144 const Handle<BytecodeArray>& bytecode_array() const { | 179 const Handle<BytecodeArray>& bytecode_array() const { |
145 return bytecode_array_; | 180 return bytecode_array_; |
146 } | 181 } |
147 | 182 |
148 LanguageMode language_mode() const { | 183 LanguageMode language_mode() const { |
149 // TODO(mythria): Don't rely on parse information to get language mode. | 184 // TODO(mythria): Don't rely on parse information to get language mode. |
150 return info()->language_mode(); | 185 return info()->language_mode(); |
151 } | 186 } |
152 | 187 |
| 188 const interpreter::BytecodeArrayIterator* bytecode_iterator() const { |
| 189 return bytecode_iterator_; |
| 190 } |
| 191 |
| 192 void set_bytecode_iterator( |
| 193 const interpreter::BytecodeArrayIterator* bytecode_iterator) { |
| 194 bytecode_iterator_ = bytecode_iterator; |
| 195 } |
| 196 |
| 197 const BytecodeBranchAnalysis* branch_analysis() const { |
| 198 return branch_analysis_; |
| 199 } |
| 200 |
| 201 void set_branch_analysis(const BytecodeBranchAnalysis* branch_analysis) { |
| 202 branch_analysis_ = branch_analysis; |
| 203 } |
| 204 |
153 #define DECLARE_VISIT_BYTECODE(name, ...) \ | 205 #define DECLARE_VISIT_BYTECODE(name, ...) \ |
154 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); | 206 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); |
155 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) | 207 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) |
156 #undef DECLARE_VISIT_BYTECODE | 208 #undef DECLARE_VISIT_BYTECODE |
157 | 209 |
158 Zone* local_zone_; | 210 Zone* local_zone_; |
159 CompilationInfo* info_; | 211 CompilationInfo* info_; |
160 JSGraph* jsgraph_; | 212 JSGraph* jsgraph_; |
161 Handle<BytecodeArray> bytecode_array_; | 213 Handle<BytecodeArray> bytecode_array_; |
| 214 const interpreter::BytecodeArrayIterator* bytecode_iterator_; |
| 215 const BytecodeBranchAnalysis* branch_analysis_; |
162 Environment* environment_; | 216 Environment* environment_; |
163 | 217 |
| 218 // Merge environments are snapshots of the environment at a particular |
| 219 // bytecode offset to be merged into a later environment. |
| 220 ZoneMap<int, Environment*> merge_environments_; |
| 221 |
| 222 // Loop header environments are environments created for bytecodes |
| 223 // where it is known there are back branches, ie a loop header. |
| 224 ZoneMap<int, Environment*> loop_header_environments_; |
| 225 |
164 // Temporary storage for building node input lists. | 226 // Temporary storage for building node input lists. |
165 int input_buffer_size_; | 227 int input_buffer_size_; |
166 Node** input_buffer_; | 228 Node** input_buffer_; |
167 | 229 |
168 // Nodes representing values in the activation record. | 230 // Nodes representing values in the activation record. |
169 SetOncePointer<Node> function_context_; | 231 SetOncePointer<Node> function_context_; |
170 SetOncePointer<Node> function_closure_; | 232 SetOncePointer<Node> function_closure_; |
171 SetOncePointer<Node> new_target_; | 233 SetOncePointer<Node> new_target_; |
172 | 234 |
173 // Optimization to cache loaded feedback vector. | 235 // Optimization to cache loaded feedback vector. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 267 |
206 // Control dependency tracked by this environment. | 268 // Control dependency tracked by this environment. |
207 Node* GetControlDependency() const { return control_dependency_; } | 269 Node* GetControlDependency() const { return control_dependency_; } |
208 void UpdateControlDependency(Node* dependency) { | 270 void UpdateControlDependency(Node* dependency) { |
209 control_dependency_ = dependency; | 271 control_dependency_ = dependency; |
210 } | 272 } |
211 | 273 |
212 Node* Context() const { return context_; } | 274 Node* Context() const { return context_; } |
213 void SetContext(Node* new_context) { context_ = new_context; } | 275 void SetContext(Node* new_context) { context_ = new_context; } |
214 | 276 |
| 277 Environment* CopyForConditional() const; |
| 278 Environment* CopyForLoop(); |
| 279 void Merge(Environment* other); |
| 280 |
215 private: | 281 private: |
| 282 explicit Environment(const Environment* copy); |
| 283 void PrepareForLoop(); |
| 284 |
216 int RegisterToValuesIndex(interpreter::Register the_register) const; | 285 int RegisterToValuesIndex(interpreter::Register the_register) const; |
217 | |
218 Zone* zone() const { return builder_->local_zone(); } | 286 Zone* zone() const { return builder_->local_zone(); } |
219 Graph* graph() const { return builder_->graph(); } | 287 Graph* graph() const { return builder_->graph(); } |
220 CommonOperatorBuilder* common() const { return builder_->common(); } | 288 CommonOperatorBuilder* common() const { return builder_->common(); } |
221 BytecodeGraphBuilder* builder() const { return builder_; } | 289 BytecodeGraphBuilder* builder() const { return builder_; } |
222 const NodeVector* values() const { return &values_; } | 290 const NodeVector* values() const { return &values_; } |
223 NodeVector* values() { return &values_; } | 291 NodeVector* values() { return &values_; } |
224 Node* accumulator() { return accumulator_; } | 292 Node* accumulator() { return accumulator_; } |
225 int register_base() const { return register_base_; } | 293 int register_base() const { return register_base_; } |
226 | 294 |
227 BytecodeGraphBuilder* builder_; | 295 BytecodeGraphBuilder* builder_; |
228 int register_count_; | 296 int register_count_; |
229 int parameter_count_; | 297 int parameter_count_; |
230 Node* accumulator_; | 298 Node* accumulator_; |
231 Node* context_; | 299 Node* context_; |
232 Node* control_dependency_; | 300 Node* control_dependency_; |
233 Node* effect_dependency_; | 301 Node* effect_dependency_; |
234 NodeVector values_; | 302 NodeVector values_; |
235 int register_base_; | 303 int register_base_; |
236 }; | 304 }; |
237 | 305 |
238 | |
239 } // namespace compiler | 306 } // namespace compiler |
240 } // namespace internal | 307 } // namespace internal |
241 } // namespace v8 | 308 } // namespace v8 |
242 | 309 |
243 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ | 310 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
OLD | NEW |