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

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: Limit visibility of members 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
« no previous file with comments | « BUILD.gn ('k') | src/compiler/ast-graph-builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
38 // Get the node that represents the outer function context.
39 Node* GetFunctionContext();
Michael Starzinger 2015/02/02 18:34:55 nit: This can be made protected I think.
titzer 2015/02/02 18:39:06 Done.
40
41 // Helpers to create new control nodes.
42 Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
43 Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
44 Node* NewMerge() { return NewNode(common()->Merge(1), true); }
45 Node* NewLoop() { return NewNode(common()->Loop(1), true); }
46 Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
47 return NewNode(common()->Branch(hint), condition);
48 }
49
35 protected: 50 protected:
51 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
52 // Visiting functions for AST nodes make this an AstVisitor.
53 AST_NODE_LIST(DECLARE_VISIT)
54 #undef DECLARE_VISIT
55
56 // Visiting function for declarations list is overridden.
57 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
58
59 private:
36 class AstContext; 60 class AstContext;
37 class AstEffectContext; 61 class AstEffectContext;
38 class AstValueContext; 62 class AstValueContext;
39 class AstTestContext; 63 class AstTestContext;
40 class BreakableScope; 64 class BreakableScope;
41 class ContextScope; 65 class ContextScope;
42 class Environment; 66 class Environment;
67 friend class ControlBuilder;
43 68
44 Environment* environment() { 69 Zone* local_zone_;
45 return reinterpret_cast<Environment*>( 70 CompilationInfo* info_;
46 StructuredGraphBuilder::environment()); 71 JSGraph* jsgraph_;
47 } 72 Environment* environment_;
73 AstContext* ast_context_;
48 74
75 // List of global declarations for functions and variables.
76 ZoneVector<Handle<Object>> globals_;
77
78 // Stack of breakable statements entered by the visitor.
79 BreakableScope* breakable_;
80
81 // Stack of context objects pushed onto the chain by the visitor.
82 ContextScope* execution_context_;
83
84 // Nodes representing values in the activation record.
85 SetOncePointer<Node> function_closure_;
86 SetOncePointer<Node> function_context_;
87
88 // Temporary storage for building node input lists.
89 int input_buffer_size_;
90 Node** input_buffer_;
91
92 // Node representing the control dependency for dead code.
93 SetOncePointer<Node> dead_control_;
94
95 // Node representing the current context within the function body.
96 Node* current_context_;
97
98 // Merge of all control nodes that exit the function body.
99 Node* exit_control_;
100
101 // Result of loop assignment analysis performed before graph creation.
102 LoopAssignmentAnalysis* loop_assignment_analysis_;
103
104 // Growth increment for the temporary buffer used to construct input lists to
105 // new nodes.
106 static const int kInputBufferSizeIncrement = 64;
107
108 Zone* local_zone() const { return local_zone_; }
109 Environment* environment() { return environment_; }
49 AstContext* ast_context() const { return ast_context_; } 110 AstContext* ast_context() const { return ast_context_; }
50 BreakableScope* breakable() const { return breakable_; } 111 BreakableScope* breakable() const { return breakable_; }
51 ContextScope* execution_context() const { return execution_context_; } 112 ContextScope* execution_context() const { return execution_context_; }
113 CommonOperatorBuilder* common() const { return jsgraph_->common(); }
114 CompilationInfo* info() const { return info_; }
115 StrictMode strict_mode() const;
116 JSGraph* jsgraph() { return jsgraph_; }
117 Graph* graph() { return jsgraph_->graph(); }
118 Zone* graph_zone() { return graph()->zone(); }
119 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
120 ZoneVector<Handle<Object>>* globals() { return &globals_; }
121 inline Scope* current_scope() const;
122 Node* current_context() const { return current_context_; }
123 Node* dead_control();
124 Node* exit_control() const { return exit_control_; }
52 125
53 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } 126 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; }
54 void set_breakable(BreakableScope* brk) { breakable_ = brk; } 127 void set_breakable(BreakableScope* brk) { breakable_ = brk; }
55 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } 128 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; }
129 void set_exit_control(Node* exit) { exit_control_ = exit; }
130 void set_current_context(Node* ctx) { current_context_ = ctx; }
131 void set_environment(Environment* env) { environment_ = env; }
56 132
57 // Support for control flow builders. The concrete type of the environment 133 // Node creation helpers.
58 // depends on the graph builder, but environments themselves are not virtual. 134 Node* NewNode(const Operator* op, bool incomplete = false) {
59 typedef StructuredGraphBuilder::Environment BaseEnvironment; 135 return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
60 BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE; 136 }
137
138 Node* NewNode(const Operator* op, Node* n1) {
139 return MakeNode(op, 1, &n1, false);
140 }
141
142 Node* NewNode(const Operator* op, Node* n1, Node* n2) {
143 Node* buffer[] = {n1, n2};
144 return MakeNode(op, arraysize(buffer), buffer, false);
145 }
146
147 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
148 Node* buffer[] = {n1, n2, n3};
149 return MakeNode(op, arraysize(buffer), buffer, false);
150 }
151
152 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
153 Node* buffer[] = {n1, n2, n3, n4};
154 return MakeNode(op, arraysize(buffer), buffer, false);
155 }
156
157 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
158 Node* n5) {
159 Node* buffer[] = {n1, n2, n3, n4, n5};
160 return MakeNode(op, arraysize(buffer), buffer, false);
161 }
162
163 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
164 Node* n5, Node* n6) {
165 Node* nodes[] = {n1, n2, n3, n4, n5, n6};
166 return MakeNode(op, arraysize(nodes), nodes, false);
167 }
168
169 Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
170 bool incomplete = false) {
171 return MakeNode(op, value_input_count, value_inputs, incomplete);
172 }
173
174 // Creates a new Phi node having {count} input values.
175 Node* NewPhi(int count, Node* input, Node* control);
176 Node* NewEffectPhi(int count, Node* input, Node* control);
177
178 // Helpers for merging control, effect or value dependencies.
179 Node* MergeControl(Node* control, Node* other);
180 Node* MergeEffect(Node* value, Node* other, Node* control);
181 Node* MergeValue(Node* value, Node* other, Node* control);
182
183 // The main node creation chokepoint. Adds context, frame state, effect,
184 // and control dependencies depending on the operator.
185 Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
186 bool incomplete);
61 187
62 // Getters for values in the activation record. 188 // Getters for values in the activation record.
63 Node* GetFunctionClosure(); 189 Node* GetFunctionClosure();
Michael Starzinger 2015/02/02 18:34:55 nit: Can we keep this one together with GetFunctio
titzer 2015/02/02 18:39:06 Done.
64 Node* GetFunctionContext(); 190
191 // Helper to indicate a node exits the function body.
192 void UpdateControlDependencyToLeaveFunction(Node* exit);
65 193
66 // 194 //
67 // The following build methods all generate graph fragments and return one 195 // The following build methods all generate graph fragments and return one
68 // resulting node. The operand stack height remains the same, variables and 196 // resulting node. The operand stack height remains the same, variables and
69 // other dependencies tracked by the environment might be mutated though. 197 // other dependencies tracked by the environment might be mutated though.
70 // 198 //
71 199
72 // Builder to create a receiver check for sloppy mode. 200 // Builder to create a receiver check for sloppy mode.
73 Node* BuildPatchReceiverToGlobalProxy(Node* receiver); 201 Node* BuildPatchReceiverToGlobalProxy(Node* receiver);
74 202
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 // Builders for binary operations. 241 // Builders for binary operations.
114 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); 242 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op);
115 243
116 // Builder for stack-check guards. 244 // Builder for stack-check guards.
117 Node* BuildStackCheck(); 245 Node* BuildStackCheck();
118 246
119 // Check if the given statement is an OSR entry. 247 // Check if the given statement is an OSR entry.
120 // If so, record the stack height into the compilation and return {true}. 248 // If so, record the stack height into the compilation and return {true}.
121 bool CheckOsrEntry(IterationStatement* stmt); 249 bool CheckOsrEntry(IterationStatement* stmt);
122 250
123 #define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE; 251 // Helper to wrap a Handle<T> into a Unique<T>.
252 template <class T>
253 Unique<T> MakeUnique(Handle<T> object) {
254 return Unique<T>::CreateUninitialized(object);
255 }
124 256
125 // Visiting functions for AST nodes make this an AstVisitor. 257 Node** EnsureInputBufferSize(int size);
126 AST_NODE_LIST(DECLARE_VISIT)
127 #undef DECLARE_VISIT
128
129 // Visiting function for declarations list is overridden.
130 void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
131
132 private:
133 CompilationInfo* info_;
134 AstContext* ast_context_;
135 JSGraph* jsgraph_;
136
137 // List of global declarations for functions and variables.
138 ZoneVector<Handle<Object>> globals_;
139
140 // Stack of breakable statements entered by the visitor.
141 BreakableScope* breakable_;
142
143 // Stack of context objects pushed onto the chain by the visitor.
144 ContextScope* execution_context_;
145
146 // Nodes representing values in the activation record.
147 SetOncePointer<Node> function_closure_;
148 SetOncePointer<Node> function_context_;
149
150 // The node representing the OSR entry into the loop, if any.
151 SetOncePointer<Node> osr_loop_entry_;
152
153 // Result of loop assignment analysis performed before graph creation.
154 LoopAssignmentAnalysis* loop_assignment_analysis_;
155
156 CompilationInfo* info() const { return info_; }
157 inline StrictMode strict_mode() const;
158 JSGraph* jsgraph() { return jsgraph_; }
159 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
160 ZoneVector<Handle<Object>>* globals() { return &globals_; }
161
162 // Current scope during visitation.
163 inline Scope* current_scope() const;
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;
394 }
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();
302 } 427 }
303 428
304 private: 429 private:
305 void UpdateStateValues(Node** state_values, int offset, int count); 430 AstGraphBuilder* builder_;
306
307 int parameters_count_; 431 int parameters_count_;
308 int locals_count_; 432 int locals_count_;
433 NodeVector values_;
434 Node* control_dependency_;
435 Node* effect_dependency_;
309 Node* parameters_node_; 436 Node* parameters_node_;
310 Node* locals_node_; 437 Node* locals_node_;
311 Node* stack_node_; 438 Node* stack_node_;
439
440 explicit Environment(const Environment* copy);
441 Environment* Copy() { return new (zone()) Environment(this); }
442 void UpdateStateValues(Node** state_values, int offset, int count);
443 Zone* zone() const { return builder_->local_zone(); }
444 Graph* graph() const { return builder_->graph(); }
445 AstGraphBuilder* builder() const { return builder_; }
446 CommonOperatorBuilder* common() { return builder_->common(); }
447 NodeVector* values() { return &values_; }
448
449 // Prepare environment to be used as loop header.
450 void PrepareForLoop(BitVector* assigned, bool is_osr = false);
312 }; 451 };
313 452
314 453
315 // Each expression in the AST is evaluated in a specific context. This context 454 // Each expression in the AST is evaluated in a specific context. This context
316 // decides how the evaluation result is passed up the visitor. 455 // decides how the evaluation result is passed up the visitor.
317 class AstGraphBuilder::AstContext BASE_EMBEDDED { 456 class AstGraphBuilder::AstContext BASE_EMBEDDED {
318 public: 457 public:
319 bool IsEffect() const { return kind_ == Expression::kEffect; } 458 bool IsEffect() const { return kind_ == Expression::kEffect; }
320 bool IsValue() const { return kind_ == Expression::kValue; } 459 bool IsValue() const { return kind_ == Expression::kValue; }
321 bool IsTest() const { return kind_ == Expression::kTest; } 460 bool IsTest() const { return kind_ == Expression::kTest; }
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 597
459 Scope* AstGraphBuilder::current_scope() const { 598 Scope* AstGraphBuilder::current_scope() const {
460 return execution_context_->scope(); 599 return execution_context_->scope();
461 } 600 }
462 601
463 } // namespace compiler 602 } // namespace compiler
464 } // namespace internal 603 } // namespace internal
465 } // namespace v8 604 } // namespace v8
466 605
467 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ 606 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | src/compiler/ast-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698