OLD | NEW |
---|---|
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/ast.h" | 8 #include "src/ast.h" |
9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 class BitVector; | 14 class BitVector; |
15 | 15 |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 class ControlBuilder; | 18 class ControlBuilder; |
19 class Graph; | 19 class Graph; |
20 class LivenessAnalyzer; | |
21 class LivenessAnalyzerBlock; | |
20 class LoopAssignmentAnalysis; | 22 class LoopAssignmentAnalysis; |
21 class LoopBuilder; | 23 class LoopBuilder; |
22 class Node; | 24 class Node; |
23 | 25 |
24 // The AstGraphBuilder produces a high-level IR graph, based on an | 26 // The AstGraphBuilder produces a high-level IR graph, based on an |
25 // underlying AST. The produced graph can either be compiled into a | 27 // underlying AST. The produced graph can either be compiled into a |
26 // 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 |
27 // of function inlining. | 29 // of function inlining. |
28 class AstGraphBuilder : public AstVisitor { | 30 class AstGraphBuilder : public AstVisitor { |
29 public: | 31 public: |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 // Temporary storage for building node input lists. | 92 // Temporary storage for building node input lists. |
91 int input_buffer_size_; | 93 int input_buffer_size_; |
92 Node** input_buffer_; | 94 Node** input_buffer_; |
93 | 95 |
94 // Merge of all control nodes that exit the function body. | 96 // Merge of all control nodes that exit the function body. |
95 Node* exit_control_; | 97 Node* exit_control_; |
96 | 98 |
97 // Result of loop assignment analysis performed before graph creation. | 99 // Result of loop assignment analysis performed before graph creation. |
98 LoopAssignmentAnalysis* loop_assignment_analysis_; | 100 LoopAssignmentAnalysis* loop_assignment_analysis_; |
99 | 101 |
102 // Analyzer of local variable liveness. | |
103 LivenessAnalyzer* liveness_analyzer_; | |
104 | |
100 // Growth increment for the temporary buffer used to construct input lists to | 105 // Growth increment for the temporary buffer used to construct input lists to |
101 // new nodes. | 106 // new nodes. |
102 static const int kInputBufferSizeIncrement = 64; | 107 static const int kInputBufferSizeIncrement = 64; |
103 | 108 |
104 Zone* local_zone() const { return local_zone_; } | 109 Zone* local_zone() const { return local_zone_; } |
105 Environment* environment() const { return environment_; } | 110 Environment* environment() const { return environment_; } |
106 AstContext* ast_context() const { return ast_context_; } | 111 AstContext* ast_context() const { return ast_context_; } |
107 ControlScope* execution_control() const { return execution_control_; } | 112 ControlScope* execution_control() const { return execution_control_; } |
108 ContextScope* execution_context() const { return execution_context_; } | 113 ContextScope* execution_context() const { return execution_context_; } |
109 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 114 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
110 CompilationInfo* info() const { return info_; } | 115 CompilationInfo* info() const { return info_; } |
111 LanguageMode language_mode() const; | 116 LanguageMode language_mode() const; |
112 JSGraph* jsgraph() { return jsgraph_; } | 117 JSGraph* jsgraph() { return jsgraph_; } |
113 Graph* graph() { return jsgraph_->graph(); } | 118 Graph* graph() { return jsgraph_->graph(); } |
114 Zone* graph_zone() { return graph()->zone(); } | 119 Zone* graph_zone() { return graph()->zone(); } |
115 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } | 120 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } |
116 ZoneVector<Handle<Object>>* globals() { return &globals_; } | 121 ZoneVector<Handle<Object>>* globals() { return &globals_; } |
117 Scope* current_scope() const; | 122 Scope* current_scope() const; |
118 Node* current_context() const; | 123 Node* current_context() const; |
119 Node* exit_control() const { return exit_control_; } | 124 Node* exit_control() const { return exit_control_; } |
125 LivenessAnalyzer* liveness_analyzer() { return liveness_analyzer_; } | |
120 | 126 |
121 void set_environment(Environment* env) { environment_ = env; } | 127 void set_environment(Environment* env) { environment_ = env; } |
122 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } | 128 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } |
123 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } | 129 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } |
124 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } | 130 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } |
125 void set_exit_control(Node* exit) { exit_control_ = exit; } | 131 void set_exit_control(Node* exit) { exit_control_ = exit; } |
126 | 132 |
127 // Create the main graph body by visiting the AST. | 133 // Create the main graph body by visiting the AST. |
128 void CreateGraphBody(); | 134 void CreateGraphBody(); |
129 | 135 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 // Builders for binary operations. | 261 // Builders for binary operations. |
256 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); | 262 Node* BuildBinaryOp(Node* left, Node* right, Token::Value op); |
257 | 263 |
258 // Builder for stack-check guards. | 264 // Builder for stack-check guards. |
259 Node* BuildStackCheck(); | 265 Node* BuildStackCheck(); |
260 | 266 |
261 // Check if the given statement is an OSR entry. | 267 // Check if the given statement is an OSR entry. |
262 // If so, record the stack height into the compilation and return {true}. | 268 // If so, record the stack height into the compilation and return {true}. |
263 bool CheckOsrEntry(IterationStatement* stmt); | 269 bool CheckOsrEntry(IterationStatement* stmt); |
264 | 270 |
271 // Computes local variable liveness and replaces dead variables in | |
272 // frame states with the undefined values. | |
273 void RelaxFrameStatesWithLiveness(); | |
titzer
2015/02/27 21:09:55
Can we use another word than "Relax", here and els
| |
274 | |
265 // Helper to wrap a Handle<T> into a Unique<T>. | 275 // Helper to wrap a Handle<T> into a Unique<T>. |
266 template <class T> | 276 template <class T> |
267 Unique<T> MakeUnique(Handle<T> object) { | 277 Unique<T> MakeUnique(Handle<T> object) { |
268 return Unique<T>::CreateUninitialized(object); | 278 return Unique<T>::CreateUninitialized(object); |
269 } | 279 } |
270 | 280 |
271 Node** EnsureInputBufferSize(int size); | 281 Node** EnsureInputBufferSize(int size); |
272 | 282 |
273 // Named and keyed loads require a VectorSlotPair for successful lowering. | 283 // Named and keyed loads require a VectorSlotPair for successful lowering. |
274 VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const; | 284 VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency); | 349 Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency); |
340 | 350 |
341 int parameters_count() const { return parameters_count_; } | 351 int parameters_count() const { return parameters_count_; } |
342 int locals_count() const { return locals_count_; } | 352 int locals_count() const { return locals_count_; } |
343 int stack_height() { | 353 int stack_height() { |
344 return static_cast<int>(values()->size()) - parameters_count_ - | 354 return static_cast<int>(values()->size()) - parameters_count_ - |
345 locals_count_; | 355 locals_count_; |
346 } | 356 } |
347 | 357 |
348 // Operations on parameter or local variables. The parameter indices are | 358 // Operations on parameter or local variables. The parameter indices are |
349 // shifted by 1 (receiver is parameter index -1 but environment index 0). | 359 // shifted by 1 (receiver is parameter index -1 but environment index 0). |
Michael Starzinger
2015/03/02 10:56:34
nit: I think the second sentence in the comment ma
Jarin
2015/03/16 21:30:12
Done.
| |
350 void Bind(Variable* variable, Node* node) { | 360 void Bind(Variable* variable, Node* node); |
351 DCHECK(variable->IsStackAllocated()); | 361 Node* Lookup(Variable* variable); |
352 if (variable->IsParameter()) { | 362 void MakeAllLocalsLive(); |
353 values()->at(variable->index() + 1) = node; | |
354 } else { | |
355 DCHECK(variable->IsStackLocal()); | |
356 values()->at(variable->index() + parameters_count_) = node; | |
357 } | |
358 } | |
359 Node* Lookup(Variable* variable) { | |
360 DCHECK(variable->IsStackAllocated()); | |
361 if (variable->IsParameter()) { | |
362 return values()->at(variable->index() + 1); | |
363 } else { | |
364 DCHECK(variable->IsStackLocal()); | |
365 return values()->at(variable->index() + parameters_count_); | |
366 } | |
367 } | |
368 | 363 |
369 Node* Context() const { return contexts_.back(); } | 364 Node* Context() const { return contexts_.back(); } |
370 void PushContext(Node* context) { contexts()->push_back(context); } | 365 void PushContext(Node* context) { contexts()->push_back(context); } |
371 void PopContext() { contexts()->pop_back(); } | 366 void PopContext() { contexts()->pop_back(); } |
372 | 367 |
373 // Operations on the operand stack. | 368 // Operations on the operand stack. |
374 void Push(Node* node) { | 369 void Push(Node* node) { |
375 values()->push_back(node); | 370 values()->push_back(node); |
376 } | 371 } |
377 Node* Top() { | 372 Node* Top() { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 // Copies this environment to a potentially unreachable control-flow point. | 434 // Copies this environment to a potentially unreachable control-flow point. |
440 Environment* CopyAsUnreachable() { | 435 Environment* CopyAsUnreachable() { |
441 Environment* env = Copy(); | 436 Environment* env = Copy(); |
442 env->MarkAsUnreachable(); | 437 env->MarkAsUnreachable(); |
443 return env; | 438 return env; |
444 } | 439 } |
445 | 440 |
446 // Copies this environment at a loop header control-flow point. | 441 // Copies this environment at a loop header control-flow point. |
447 Environment* CopyForLoop(BitVector* assigned, bool is_osr = false) { | 442 Environment* CopyForLoop(BitVector* assigned, bool is_osr = false) { |
448 PrepareForLoop(assigned, is_osr); | 443 PrepareForLoop(assigned, is_osr); |
449 return Copy(); | 444 return Snapshot(); |
450 } | 445 } |
451 | 446 |
452 int ContextStackDepth() { return static_cast<int>(contexts_.size()); } | 447 int ContextStackDepth() { return static_cast<int>(contexts_.size()); } |
453 | 448 |
454 private: | 449 private: |
455 AstGraphBuilder* builder_; | 450 AstGraphBuilder* builder_; |
456 int parameters_count_; | 451 int parameters_count_; |
457 int locals_count_; | 452 int locals_count_; |
453 LivenessAnalyzerBlock* liveness_block_; | |
458 NodeVector values_; | 454 NodeVector values_; |
459 NodeVector contexts_; | 455 NodeVector contexts_; |
460 Node* control_dependency_; | 456 Node* control_dependency_; |
461 Node* effect_dependency_; | 457 Node* effect_dependency_; |
462 Node* parameters_node_; | 458 Node* parameters_node_; |
463 Node* locals_node_; | 459 Node* locals_node_; |
464 Node* stack_node_; | 460 Node* stack_node_; |
465 | 461 |
466 explicit Environment(const Environment* copy); | 462 explicit Environment(Environment* copy); |
467 Environment* Copy() { return new (zone()) Environment(this); } | 463 Environment* Copy() { return new (zone()) Environment(this); } |
464 Environment* Snapshot(); | |
468 void UpdateStateValues(Node** state_values, int offset, int count); | 465 void UpdateStateValues(Node** state_values, int offset, int count); |
469 Zone* zone() const { return builder_->local_zone(); } | 466 Zone* zone() const { return builder_->local_zone(); } |
470 Graph* graph() const { return builder_->graph(); } | 467 Graph* graph() const { return builder_->graph(); } |
471 AstGraphBuilder* builder() const { return builder_; } | 468 AstGraphBuilder* builder() const { return builder_; } |
472 CommonOperatorBuilder* common() { return builder_->common(); } | 469 CommonOperatorBuilder* common() { return builder_->common(); } |
473 NodeVector* values() { return &values_; } | 470 NodeVector* values() { return &values_; } |
474 NodeVector* contexts() { return &contexts_; } | 471 NodeVector* contexts() { return &contexts_; } |
472 LivenessAnalyzerBlock* liveness_block() { return liveness_block_; } | |
475 | 473 |
476 // Prepare environment to be used as loop header. | 474 // Prepare environment to be used as loop header. |
477 void PrepareForLoop(BitVector* assigned, bool is_osr = false); | 475 void PrepareForLoop(BitVector* assigned, bool is_osr = false); |
478 }; | 476 }; |
479 | 477 |
480 } // namespace compiler | 478 } // namespace compiler |
481 } // namespace internal | 479 } // namespace internal |
482 } // namespace v8 | 480 } // namespace v8 |
483 | 481 |
484 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ | 482 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ |
OLD | NEW |