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

Side by Side Diff: src/compiler/bytecode-graph-builder.h

Issue 1502243002: [Interpreter] Local flow control in the bytecode graph builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Build fix. Created 5 years 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
OLDNEW
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/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/interpreter/bytecode-array-iterator.h" 10 #include "src/interpreter/bytecode-array-iterator.h"
11 #include "src/interpreter/bytecodes.h" 11 #include "src/interpreter/bytecodes.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 namespace compiler { 15 namespace compiler {
16 16
17 class BytecodeBasicBlock;
18
17 // The BytecodeGraphBuilder produces a high-level IR graph based on 19 // The BytecodeGraphBuilder produces a high-level IR graph based on
18 // interpreter bytecodes. 20 // interpreter bytecodes.
19 class BytecodeGraphBuilder { 21 class BytecodeGraphBuilder {
20 public: 22 public:
21 BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info, 23 BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info,
22 JSGraph* jsgraph); 24 JSGraph* jsgraph);
23 25
24 // Creates a graph by visiting bytecodes. 26 // Creates a graph by visiting bytecodes.
25 bool CreateGraph(bool stack_check = true); 27 bool CreateGraph(bool stack_check = true);
26 28
27 Graph* graph() const { return jsgraph_->graph(); } 29 Graph* graph() const { return jsgraph_->graph(); }
28 30
29 private: 31 private:
30 class Environment; 32 class Environment;
33 class BlockEnvironmentInfo;
31 34
32 void CreateGraphBody(bool stack_check); 35 void CreateGraphBody(bool stack_check);
33 void VisitBytecodes(); 36 void VisitBasicBlocks();
37 void VisitBytecodesInBasicBlock(BytecodeBasicBlock* block);
34 38
35 Node* LoadAccumulator(Node* value); 39 Node* LoadAccumulator(Node* value);
36 40
37 // Get or create the node that represents the outer function closure. 41 // Get or create the node that represents the outer function closure.
38 Node* GetFunctionClosure(); 42 Node* GetFunctionClosure();
39 43
40 // Get or create the node that represents the outer function context. 44 // Get or create the node that represents the outer function context.
41 Node* GetFunctionContext(); 45 Node* GetFunctionContext();
42 46
43 // Get or create the node that represents the incoming new target value. 47 // Get or create the node that represents the incoming new target value.
(...skipping 13 matching lines...) Expand all
57 // a feedback slot. 61 // a feedback slot.
58 VectorSlotPair CreateVectorSlotPair(int slot_id); 62 VectorSlotPair CreateVectorSlotPair(int slot_id);
59 63
60 // Replaces the frame state inputs with empty frame states. 64 // Replaces the frame state inputs with empty frame states.
61 void AddEmptyFrameStateInputs(Node* node); 65 void AddEmptyFrameStateInputs(Node* node);
62 66
63 void set_environment(Environment* env) { environment_ = env; } 67 void set_environment(Environment* env) { environment_ = env; }
64 const Environment* environment() const { return environment_; } 68 const Environment* environment() const { return environment_; }
65 Environment* environment() { return environment_; } 69 Environment* environment() { return environment_; }
66 70
71 void set_basic_block(const BytecodeBasicBlock* block) {
72 basic_block_ = block;
73 }
74 const BytecodeBasicBlock* basic_block() const { return basic_block_; }
75
67 // Node creation helpers 76 // Node creation helpers
68 Node* NewNode(const Operator* op, bool incomplete = false) { 77 Node* NewNode(const Operator* op, bool incomplete = false) {
69 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); 78 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
70 } 79 }
71 80
72 Node* NewNode(const Operator* op, Node* n1) { 81 Node* NewNode(const Operator* op, Node* n1) {
73 Node* buffer[] = {n1}; 82 Node* buffer[] = {n1};
74 return MakeNode(op, arraysize(buffer), buffer, false); 83 return MakeNode(op, arraysize(buffer), buffer, false);
75 } 84 }
76 85
77 Node* NewNode(const Operator* op, Node* n1, Node* n2) { 86 Node* NewNode(const Operator* op, Node* n1, Node* n2) {
78 Node* buffer[] = {n1, n2}; 87 Node* buffer[] = {n1, n2};
79 return MakeNode(op, arraysize(buffer), buffer, false); 88 return MakeNode(op, arraysize(buffer), buffer, false);
80 } 89 }
81 90
82 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) { 91 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
83 Node* buffer[] = {n1, n2, n3}; 92 Node* buffer[] = {n1, n2, n3};
84 return MakeNode(op, arraysize(buffer), buffer, false); 93 return MakeNode(op, arraysize(buffer), buffer, false);
85 } 94 }
86 95
87 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) { 96 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
88 Node* buffer[] = {n1, n2, n3, n4}; 97 Node* buffer[] = {n1, n2, n3, n4};
89 return MakeNode(op, arraysize(buffer), buffer, false); 98 return MakeNode(op, arraysize(buffer), buffer, false);
90 } 99 }
91 100
101 // Helpers to create new control nodes.
102 Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
103 Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
104 Node* NewMerge() { return NewNode(common()->Merge(1), true); }
105 Node* NewLoop() { return NewNode(common()->Loop(1), true); }
106 Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
107 return NewNode(common()->Branch(hint), condition);
108 }
109
110 // Creates a new Phi node having {count} input values.
111 Node* NewPhi(int count, Node* input, Node* control);
112 Node* NewEffectPhi(int count, Node* input, Node* control);
113
114 // Helpers for merging control, effect or value dependencies.
115 Node* MergeControl(Node* control, Node* other);
116 Node* MergeEffect(Node* effect, Node* other_effect, Node* control);
117 Node* MergeValue(Node* value, Node* other_value, Node* control);
118
119 // The main node creation chokepoint. Adds context, frame state, effect,
120 // and control dependencies depending on the operator.
92 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, 121 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
93 bool incomplete); 122 bool incomplete);
94 123
95 Node* MergeControl(Node* control, Node* other); 124 // Helper to indicate a node exits the function body.
125 void UpdateControlDependencyToLeaveFunction(Node* exit);
96 126
97 Node** EnsureInputBufferSize(int size); 127 Node** EnsureInputBufferSize(int size);
98 128
99 void UpdateControlDependencyToLeaveFunction(Node* exit);
100
101 Node* ProcessCallArguments(const Operator* call_op, Node* callee, 129 Node* ProcessCallArguments(const Operator* call_op, Node* callee,
102 interpreter::Register receiver, size_t arity); 130 interpreter::Register receiver, size_t arity);
103 Node* ProcessCallNewArguments(const Operator* call_new_op, 131 Node* ProcessCallNewArguments(const Operator* call_new_op,
104 interpreter::Register callee, 132 interpreter::Register callee,
105 interpreter::Register first_arg, size_t arity); 133 interpreter::Register first_arg, size_t arity);
106 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op, 134 Node* ProcessCallRuntimeArguments(const Operator* call_runtime_op,
107 interpreter::Register first_arg, 135 interpreter::Register first_arg,
108 size_t arity); 136 size_t arity);
109 137
110 void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator, 138 void BuildLoadGlobal(const interpreter::BytecodeArrayIterator& iterator,
111 TypeofMode typeof_mode); 139 TypeofMode typeof_mode);
112 void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator); 140 void BuildStoreGlobal(const interpreter::BytecodeArrayIterator& iterator);
113 void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator); 141 void BuildNamedLoad(const interpreter::BytecodeArrayIterator& iterator);
114 void BuildKeyedLoad(const interpreter::BytecodeArrayIterator& iterator); 142 void BuildKeyedLoad(const interpreter::BytecodeArrayIterator& iterator);
115 void BuildNamedStore(const interpreter::BytecodeArrayIterator& iterator); 143 void BuildNamedStore(const interpreter::BytecodeArrayIterator& iterator);
116 void BuildKeyedStore(const interpreter::BytecodeArrayIterator& iterator); 144 void BuildKeyedStore(const interpreter::BytecodeArrayIterator& iterator);
117 void BuildCall(const interpreter::BytecodeArrayIterator& iterator); 145 void BuildCall(const interpreter::BytecodeArrayIterator& iterator);
118 void BuildBinaryOp(const Operator* op, 146 void BuildBinaryOp(const Operator* op,
119 const interpreter::BytecodeArrayIterator& iterator); 147 const interpreter::BytecodeArrayIterator& iterator);
120 void BuildCompareOp(const Operator* op, 148 void BuildCompareOp(const Operator* op,
121 const interpreter::BytecodeArrayIterator& iterator); 149 const interpreter::BytecodeArrayIterator& iterator);
122 void BuildDelete(const interpreter::BytecodeArrayIterator& iterator); 150 void BuildDelete(const interpreter::BytecodeArrayIterator& iterator);
123 void BuildCastOperator(const Operator* js_op, 151 void BuildCastOperator(const Operator* js_op,
124 const interpreter::BytecodeArrayIterator& iterator); 152 const interpreter::BytecodeArrayIterator& iterator);
125 153
154 // Control flow plumbing.
155 void PrepareForNewBasicBlockVisit();
156 void CompleteNewBasicBlockVisit();
157 void BuildReturn();
158 void BuildJump();
159 void BuildConditionalJump(Node* condition);
160 void BuildBackEdgeIfRequired(BytecodeBasicBlock* target);
161
126 // Growth increment for the temporary buffer used to construct input lists to 162 // Growth increment for the temporary buffer used to construct input lists to
127 // new nodes. 163 // new nodes.
128 static const int kInputBufferSizeIncrement = 64; 164 static const int kInputBufferSizeIncrement = 64;
129 165
130 // Field accessors 166 // Field accessors
131 CommonOperatorBuilder* common() const { return jsgraph_->common(); } 167 CommonOperatorBuilder* common() const { return jsgraph_->common(); }
132 Zone* graph_zone() const { return graph()->zone(); } 168 Zone* graph_zone() const { return graph()->zone(); }
133 CompilationInfo* info() const { return info_; } 169 CompilationInfo* info() const { return info_; }
134 JSGraph* jsgraph() const { return jsgraph_; } 170 JSGraph* jsgraph() const { return jsgraph_; }
135 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } 171 JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); }
(...skipping 11 matching lines...) Expand all
147 void Visit##name(const interpreter::BytecodeArrayIterator& iterator); 183 void Visit##name(const interpreter::BytecodeArrayIterator& iterator);
148 BYTECODE_LIST(DECLARE_VISIT_BYTECODE) 184 BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
149 #undef DECLARE_VISIT_BYTECODE 185 #undef DECLARE_VISIT_BYTECODE
150 186
151 Zone* local_zone_; 187 Zone* local_zone_;
152 CompilationInfo* info_; 188 CompilationInfo* info_;
153 JSGraph* jsgraph_; 189 JSGraph* jsgraph_;
154 Handle<BytecodeArray> bytecode_array_; 190 Handle<BytecodeArray> bytecode_array_;
155 Environment* environment_; 191 Environment* environment_;
156 192
193 const BytecodeBasicBlock* basic_block_;
194 ZoneVector<BlockEnvironmentInfo*> block_environment_infos_;
195
157 // Temporary storage for building node input lists. 196 // Temporary storage for building node input lists.
158 int input_buffer_size_; 197 int input_buffer_size_;
159 Node** input_buffer_; 198 Node** input_buffer_;
160 199
161 // Nodes representing values in the activation record. 200 // Nodes representing values in the activation record.
162 SetOncePointer<Node> function_context_; 201 SetOncePointer<Node> function_context_;
163 SetOncePointer<Node> function_closure_; 202 SetOncePointer<Node> function_closure_;
164 SetOncePointer<Node> new_target_; 203 SetOncePointer<Node> new_target_;
165 204
166 // Optimization to cache loaded feedback vector. 205 // Optimization to cache loaded feedback vector.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 237
199 // Control dependency tracked by this environment. 238 // Control dependency tracked by this environment.
200 Node* GetControlDependency() const { return control_dependency_; } 239 Node* GetControlDependency() const { return control_dependency_; }
201 void UpdateControlDependency(Node* dependency) { 240 void UpdateControlDependency(Node* dependency) {
202 control_dependency_ = dependency; 241 control_dependency_ = dependency;
203 } 242 }
204 243
205 Node* Context() const { return context_; } 244 Node* Context() const { return context_; }
206 void SetContext(Node* new_context) { context_ = new_context; } 245 void SetContext(Node* new_context) { context_ = new_context; }
207 246
247 Environment* CopyForConditional() const;
248 Environment* CopyForLoop();
249 void Merge(Environment* other);
250
208 private: 251 private:
252 explicit Environment(const Environment* copy);
253 void PrepareForLoop();
254
209 int RegisterToValuesIndex(interpreter::Register the_register) const; 255 int RegisterToValuesIndex(interpreter::Register the_register) const;
210
211 Zone* zone() const { return builder_->local_zone(); } 256 Zone* zone() const { return builder_->local_zone(); }
212 Graph* graph() const { return builder_->graph(); } 257 Graph* graph() const { return builder_->graph(); }
213 CommonOperatorBuilder* common() const { return builder_->common(); } 258 CommonOperatorBuilder* common() const { return builder_->common(); }
214 BytecodeGraphBuilder* builder() const { return builder_; } 259 BytecodeGraphBuilder* builder() const { return builder_; }
215 const NodeVector* values() const { return &values_; } 260 const NodeVector* values() const { return &values_; }
216 NodeVector* values() { return &values_; } 261 NodeVector* values() { return &values_; }
217 Node* accumulator() { return accumulator_; } 262 Node* accumulator() { return accumulator_; }
218 int register_base() const { return register_base_; } 263 int register_base() const { return register_base_; }
219 264
220 BytecodeGraphBuilder* builder_; 265 BytecodeGraphBuilder* builder_;
221 int register_count_; 266 int register_count_;
222 int parameter_count_; 267 int parameter_count_;
223 Node* accumulator_; 268 Node* accumulator_;
224 Node* context_; 269 Node* context_;
225 Node* control_dependency_; 270 Node* control_dependency_;
226 Node* effect_dependency_; 271 Node* effect_dependency_;
227 NodeVector values_; 272 NodeVector values_;
228 int register_base_; 273 int register_base_;
229 }; 274 };
230 275
276 // A class to help passage between the environments associated with basic
277 // blocks.
278 class BytecodeGraphBuilder::BlockEnvironmentInfo final : public ZoneObject {
279 public:
280 typedef BytecodeGraphBuilder::Environment Environment;
281
282 BlockEnvironmentInfo()
283 : loop_header_env_(nullptr),
284 if_true_env_(nullptr),
285 if_false_env_(nullptr) {}
286
287 Environment* loop_header_environment() const { return loop_header_env_; }
288 Environment* if_true_environment() const { return if_true_env_; }
289 Environment* if_false_environment() const { return if_false_env_; }
290
291 void set_loop_header_environment(Environment* env) { loop_header_env_ = env; }
292 void set_if_true_environment(Environment* env) { if_true_env_ = env; }
293 void set_if_false_environment(Environment* env) { if_false_env_ = env; }
294
295 private:
296 Environment* loop_header_env_;
297 Environment* if_true_env_;
298 Environment* if_false_env_;
299 };
231 300
232 } // namespace compiler 301 } // namespace compiler
233 } // namespace internal 302 } // namespace internal
234 } // namespace v8 303 } // namespace v8
235 304
236 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ 305 #endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698