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

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

Issue 894073002: [turbofan] Put StructuredGraphBuilder out of its misery and merge its remnants back into the AstGra… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 10 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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_AST_GRAPH_BUILDER_H_ 5 #ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_
6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_ 6 #define V8_COMPILER_AST_GRAPH_BUILDER_H_
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/ast.h" 10 #include "src/ast.h"
11 #include "src/compiler/graph-builder.h"
12 #include "src/compiler/js-graph.h" 11 #include "src/compiler/js-graph.h"
13 12
14 namespace v8 { 13 namespace v8 {
15 namespace internal { 14 namespace internal {
15
16 class BitVector;
17
16 namespace compiler { 18 namespace compiler {
17 19
18 class ControlBuilder; 20 class ControlBuilder;
19 class Graph; 21 class Graph;
20 class LoopAssignmentAnalysis; 22 class LoopAssignmentAnalysis;
21 class LoopBuilder; 23 class LoopBuilder;
24 class Node;
22 25
23 // The AstGraphBuilder produces a high-level IR graph, based on an 26 // The AstGraphBuilder produces a high-level IR graph, based on an
24 // underlying AST. The produced graph can either be compiled into a 27 // underlying AST. The produced graph can either be compiled into a
25 // stand-alone function or be wired into another graph for the purposes 28 // stand-alone function or be wired into another graph for the purposes
26 // of function inlining. 29 // of function inlining.
27 class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor { 30 class AstGraphBuilder : public AstVisitor {
28 public: 31 public:
29 AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, 32 AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
30 LoopAssignmentAnalysis* loop_assignment = NULL); 33 LoopAssignmentAnalysis* loop_assignment = NULL);
31 34
32 // Creates a graph by visiting the entire AST. 35 // Creates a graph by visiting the entire AST.
33 bool CreateGraph(); 36 bool CreateGraph();
34 37
35 protected: 38 // Node creation helpers.
39 Node* NewNode(const Operator* op, bool incomplete = false) {
40 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
41 }
42
43 Node* NewNode(const Operator* op, Node* n1) {
44 return MakeNode(op, 1, &n1, false);
45 }
46
47 Node* NewNode(const Operator* op, Node* n1, Node* n2) {
48 Node* buffer[] = {n1, n2};
49 return MakeNode(op, arraysize(buffer), buffer, false);
50 }
51
52 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
53 Node* buffer[] = {n1, n2, n3};
54 return MakeNode(op, arraysize(buffer), buffer, false);
55 }
56
57 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
58 Node* buffer[] = {n1, n2, n3, n4};
59 return MakeNode(op, arraysize(buffer), buffer, false);
60 }
61
62 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
63 Node* n5) {
64 Node* buffer[] = {n1, n2, n3, n4, n5};
65 return MakeNode(op, arraysize(buffer), buffer, false);
66 }
67
68 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
69 Node* n5, Node* n6) {
70 Node* nodes[] = {n1, n2, n3, n4, n5, n6};
71 return MakeNode(op, arraysize(nodes), nodes, false);
72 }
73
74 Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
75 bool incomplete = false) {
76 return MakeNode(op, value_input_count, value_inputs, incomplete);
77 }
78
79 // Creates a new Phi node having {count} input values.
80 Node* NewPhi(int count, Node* input, Node* control);
81 Node* NewEffectPhi(int count, Node* input, Node* control);
82
83 // Helpers for merging control, effect or value dependencies.
84 Node* MergeControl(Node* control, Node* other);
85 Node* MergeEffect(Node* value, Node* other, Node* control);
86 Node* MergeValue(Node* value, Node* other, Node* control);
87
88 // Helpers to create new control nodes.
89 Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
90 Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
91 Node* NewMerge() { return NewNode(common()->Merge(1), true); }
92 Node* NewLoop() { return NewNode(common()->Loop(1), true); }
93 Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
94 return NewNode(common()->Branch(hint), condition);
95 }
96
97 // The main node creation chokepoint. Adds context, frame state, effect,
98 // and control dependencies depending on the operator.
99 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
Michael Starzinger 2015/02/02 18:08:24 Can we try to make these methods protected again.
titzer 2015/02/02 18:26:48 Done.
100 bool incomplete);
101
36 class AstContext; 102 class AstContext;
37 class AstEffectContext; 103 class AstEffectContext;
38 class AstValueContext; 104 class AstValueContext;
39 class AstTestContext; 105 class AstTestContext;
40 class BreakableScope; 106 class BreakableScope;
41 class ContextScope; 107 class ContextScope;
42 class Environment; 108 class Environment;
109 friend class ControlBuilder;
43 110
44 Environment* environment() { 111 Environment* environment() { return environment_; }
45 return reinterpret_cast<Environment*>(
46 StructuredGraphBuilder::environment());
47 }
48
49 AstContext* ast_context() const { return ast_context_; } 112 AstContext* ast_context() const { return ast_context_; }
50 BreakableScope* breakable() const { return breakable_; } 113 BreakableScope* breakable() const { return breakable_; }
51 ContextScope* execution_context() const { return execution_context_; } 114 ContextScope* execution_context() const { return execution_context_; }
115 CommonOperatorBuilder* common() const { return jsgraph_->common(); }
52 116
53 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } 117 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
54 void set_breakable(BreakableScope* brk) { breakable_ = brk; } 118 void set_breakable(BreakableScope* brk) { breakable_ = brk; }
55 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } 119 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }
56 120
57 // Support for control flow builders. The concrete type of the environment
58 // depends on the graph builder, but environments themselves are not virtual.
59 typedef StructuredGraphBuilder::Environment BaseEnvironment;
60 BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE;
61
62 // Getters for values in the activation record. 121 // Getters for values in the activation record.
63 Node* GetFunctionClosure(); 122 Node* GetFunctionClosure();
64 Node* GetFunctionContext(); 123 Node* GetFunctionContext();
65 124
125 // Helper to indicate a node exits the function body.
126 void UpdateControlDependencyToLeaveFunction(Node* exit);
127
66 // 128 //
67 // The following build methods all generate graph fragments and return one 129 // The following build methods all generate graph fragments and return one
68 // resulting node. The operand stack height remains the same, variables and 130 // resulting node. The operand stack height remains the same, variables and
69 // other dependencies tracked by the environment might be mutated though. 131 // other dependencies tracked by the environment might be mutated though.
70 // 132 //
71 133
72 // Builder to create a receiver check for sloppy mode. 134 // Builder to create a receiver check for sloppy mode.
73 Node* BuildPatchReceiverToGlobalProxy(Node* receiver); 135 Node* BuildPatchReceiverToGlobalProxy(Node* receiver);
74 136
75 // Builders to create local function and block contexts. 137 // Builders to create local function and block contexts.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; 185 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
124 186
125 // Visiting functions for AST nodes make this an AstVisitor. 187 // Visiting functions for AST nodes make this an AstVisitor.
126 AST_NODE_LIST(DECLARE_VISIT) 188 AST_NODE_LIST(DECLARE_VISIT)
127 #undef DECLARE_VISIT 189 #undef DECLARE_VISIT
128 190
129 // Visiting function for declarations list is overridden. 191 // Visiting function for declarations list is overridden.
130 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE; 192 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
131 193
132 private: 194 private:
195 Zone* local_zone_;
133 CompilationInfo* info_; 196 CompilationInfo* info_;
197 JSGraph* jsgraph_;
198 LoopAssignmentAnalysis* loop_assignment_analysis_;
Michael Starzinger 2015/02/02 18:08:24 nit: Can we move the loop_assignment_analysis down
titzer 2015/02/02 18:26:48 Done.
199 Environment* environment_;
134 AstContext* ast_context_; 200 AstContext* ast_context_;
135 JSGraph* jsgraph_; 201
202 Zone* local_zone() const { return local_zone_; }
Michael Starzinger 2015/02/02 18:08:24 nit: Can we move the getter down to the others (ne
titzer 2015/02/02 18:26:48 Done.
136 203
137 // List of global declarations for functions and variables. 204 // List of global declarations for functions and variables.
138 ZoneVector<Handle<Object>> globals_; 205 ZoneVector<Handle<Object>> globals_;
139 206
140 // Stack of breakable statements entered by the visitor. 207 // Stack of breakable statements entered by the visitor.
141 BreakableScope* breakable_; 208 BreakableScope* breakable_;
142 209
143 // Stack of context objects pushed onto the chain by the visitor. 210 // Stack of context objects pushed onto the chain by the visitor.
144 ContextScope* execution_context_; 211 ContextScope* execution_context_;
145 212
146 // Nodes representing values in the activation record. 213 // Nodes representing values in the activation record.
147 SetOncePointer<Node> function_closure_; 214 SetOncePointer<Node> function_closure_;
148 SetOncePointer<Node> function_context_; 215 SetOncePointer<Node> function_context_;
149 216
150 // The node representing the OSR entry into the loop, if any. 217 // Temporary storage for building node input lists.
151 SetOncePointer<Node> osr_loop_entry_; 218 int input_buffer_size_;
219 Node** input_buffer_;
152 220
153 // Result of loop assignment analysis performed before graph creation. 221 // Node representing the control dependency for dead code.
154 LoopAssignmentAnalysis* loop_assignment_analysis_; 222 SetOncePointer<Node> dead_control_;
223
224 // Node representing the current context within the function body.
225 Node* current_context_;
226
227 // Merge of all control nodes that exit the function body.
228 Node* exit_control_;
229
230 // Growth increment for the temporary buffer used to construct input lists to
231 // new nodes.
232 static const int kInputBufferSizeIncrement = 64;
233
234 // Helper to wrap a Handle<T> into a Unique<T>.
235 template <class T>
236 Unique<T> MakeUnique(Handle<T> object) {
237 return Unique<T>::CreateUninitialized(object);
238 }
239
240 Node** EnsureInputBufferSize(int size);
155 241
156 CompilationInfo* info() const { return info_; } 242 CompilationInfo* info() const { return info_; }
157 inline StrictMode strict_mode() const; 243 StrictMode strict_mode() const;
158 JSGraph* jsgraph() { return jsgraph_; } 244 JSGraph* jsgraph() { return jsgraph_; }
245 Graph* graph() { return jsgraph_->graph(); }
246 Zone* graph_zone() { return graph()->zone(); }
159 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } 247 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
160 ZoneVector<Handle<Object>>* globals() { return &globals_; } 248 ZoneVector<Handle<Object>>* globals() { return &globals_; }
161 249
162 // Current scope during visitation. 250 // Current scope during visitation.
163 inline Scope* current_scope() const; 251 inline Scope* current_scope() const;
252 Node* current_context() const { return current_context_; }
Michael Starzinger 2015/02/02 18:08:24 nit: Can we move this block of accessors (all six
titzer 2015/02/02 18:26:48 Done.
253 Node* dead_control();
254 Node* exit_control() const { return exit_control_; }
255 void set_exit_control(Node* exit_control) { exit_control_ = exit_control; }
256 void set_current_context(Node* context) { current_context_ = context; }
257 void set_environment(Environment* env) { environment_ = env; }
164 258
165 // Named and keyed loads require a VectorSlotPair for successful lowering. 259 // Named and keyed loads require a VectorSlotPair for successful lowering.
166 VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const; 260 VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const;
167 261
168 // Process arguments to a call by popping {arity} elements off the operand 262 // Process arguments to a call by popping {arity} elements off the operand
169 // stack and build a call node using the given call operator. 263 // stack and build a call node using the given call operator.
170 Node* ProcessArguments(const Operator* op, int arity); 264 Node* ProcessArguments(const Operator* op, int arity);
171 265
172 // Visit statements. 266 // Visit statements.
173 void VisitIfNotNull(Statement* stmt); 267 void VisitIfNotNull(Statement* stmt);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 313
220 314
221 // The abstract execution environment for generated code consists of 315 // The abstract execution environment for generated code consists of
222 // parameter variables, local variables and the operand stack. The 316 // parameter variables, local variables and the operand stack. The
223 // environment will perform proper SSA-renaming of all tracked nodes 317 // environment will perform proper SSA-renaming of all tracked nodes
224 // at split and merge points in the control flow. Internally all the 318 // at split and merge points in the control flow. Internally all the
225 // values are stored in one list using the following layout: 319 // values are stored in one list using the following layout:
226 // 320 //
227 // [parameters (+receiver)] [locals] [operand stack] 321 // [parameters (+receiver)] [locals] [operand stack]
228 // 322 //
229 class AstGraphBuilder::Environment 323 class AstGraphBuilder::Environment : public ZoneObject {
230 : public StructuredGraphBuilder::Environment {
231 public: 324 public:
232 Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency); 325 Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency);
233 Environment(const Environment& copy);
234 326
235 int parameters_count() const { return parameters_count_; } 327 int parameters_count() const { return parameters_count_; }
236 int locals_count() const { return locals_count_; } 328 int locals_count() const { return locals_count_; }
237 int stack_height() { 329 int stack_height() {
238 return static_cast<int>(values()->size()) - parameters_count_ - 330 return static_cast<int>(values()->size()) - parameters_count_ -
239 locals_count_; 331 locals_count_;
240 } 332 }
241 333
242 // Operations on parameter or local variables. The parameter indices are 334 // Operations on parameter or local variables. The parameter indices are
243 // shifted by 1 (receiver is parameter index -1 but environment index 0). 335 // shifted by 1 (receiver is parameter index -1 but environment index 0).
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 } 380 }
289 void Drop(int depth) { 381 void Drop(int depth) {
290 DCHECK(depth >= 0 && depth <= stack_height()); 382 DCHECK(depth >= 0 && depth <= stack_height());
291 values()->erase(values()->end() - depth, values()->end()); 383 values()->erase(values()->end() - depth, values()->end());
292 } 384 }
293 385
294 // Preserve a checkpoint of the environment for the IR graph. Any 386 // Preserve a checkpoint of the environment for the IR graph. Any
295 // further mutation of the environment will not affect checkpoints. 387 // further mutation of the environment will not affect checkpoints.
296 Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine); 388 Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine);
297 389
298 protected: 390 // Control dependency tracked by this environment.
299 AstGraphBuilder* builder() const { 391 Node* GetControlDependency() { return control_dependency_; }
300 return reinterpret_cast<AstGraphBuilder*>( 392 void UpdateControlDependency(Node* dependency) {
301 StructuredGraphBuilder::Environment::builder()); 393 control_dependency_ = dependency;
302 } 394 }
303 395
396 // Effect dependency tracked by this environment.
397 Node* GetEffectDependency() { return effect_dependency_; }
398 void UpdateEffectDependency(Node* dependency) {
399 effect_dependency_ = dependency;
400 }
401
402 // Mark this environment as being unreachable.
403 void MarkAsUnreachable() {
404 UpdateControlDependency(builder()->dead_control());
405 }
406 bool IsMarkedAsUnreachable() {
407 return GetControlDependency()->opcode() == IrOpcode::kDead;
408 }
409
410 // Merge another environment into this one.
411 void Merge(Environment* other);
412
413 // Copies this environment at a control-flow split point.
414 Environment* CopyForConditional() { return Copy(); }
415
416 // Copies this environment to a potentially unreachable control-flow point.
417 Environment* CopyAsUnreachable() {
418 Environment* env = Copy();
419 env->MarkAsUnreachable();
420 return env;
421 }
422
423 // Copies this environment at a loop header control-flow point.
424 Environment* CopyForLoop(BitVector* assigned, bool is_osr = false) {
425 PrepareForLoop(assigned, is_osr);
426 return Copy();
427 }
428
429 Node* GetContext() { return builder_->current_context(); }
Michael Starzinger 2015/02/02 18:08:24 nit: This seems to only have one use, can we inlin
titzer 2015/02/02 18:26:48 Done.
430
304 private: 431 private:
305 void UpdateStateValues(Node** state_values, int offset, int count); 432 AstGraphBuilder* builder_;
306
307 int parameters_count_; 433 int parameters_count_;
308 int locals_count_; 434 int locals_count_;
435 NodeVector values_;
436 Node* control_dependency_;
437 Node* effect_dependency_;
309 Node* parameters_node_; 438 Node* parameters_node_;
310 Node* locals_node_; 439 Node* locals_node_;
311 Node* stack_node_; 440 Node* stack_node_;
441
442 explicit Environment(const Environment* copy);
443 Environment* Copy() { return new (zone()) Environment(this); }
444 void UpdateStateValues(Node** state_values, int offset, int count);
445 Zone* zone() const { return builder_->local_zone(); }
446 Graph* graph() const { return builder_->graph(); }
447 AstGraphBuilder* builder() const { return builder_; }
448 CommonOperatorBuilder* common() { return builder_->common(); }
449 NodeVector* values() { return &values_; }
450
451 // Prepare environment to be used as loop header.
452 void PrepareForLoop(BitVector* assigned, bool is_osr = false);
312 }; 453 };
313 454
314 455
315 // Each expression in the AST is evaluated in a specific context. This context 456 // Each expression in the AST is evaluated in a specific context. This context
316 // decides how the evaluation result is passed up the visitor. 457 // decides how the evaluation result is passed up the visitor.
317 class AstGraphBuilder::AstContext BASE_EMBEDDED { 458 class AstGraphBuilder::AstContext BASE_EMBEDDED {
318 public: 459 public:
319 bool IsEffect() const { return kind_ == Expression::kEffect; } 460 bool IsEffect() const { return kind_ == Expression::kEffect; }
320 bool IsValue() const { return kind_ == Expression::kValue; } 461 bool IsValue() const { return kind_ == Expression::kValue; }
321 bool IsTest() const { return kind_ == Expression::kTest; } 462 bool IsTest() const { return kind_ == Expression::kTest; }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 599
459 Scope* AstGraphBuilder::current_scope() const { 600 Scope* AstGraphBuilder::current_scope() const {
460 return execution_context_->scope(); 601 return execution_context_->scope();
461 } 602 }
462 603
463 } // namespace compiler 604 } // namespace compiler
464 } // namespace internal 605 } // namespace internal
465 } // namespace v8 606 } // namespace v8
466 607
467 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ 608 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | src/compiler/ast-graph-builder.cc » ('j') | src/compiler/ast-graph-builder.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698