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 #include "src/compiler/state-values-utils.h" | 10 #include "src/compiler/state-values-utils.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 class BitVector; | 15 class BitVector; |
16 | 16 |
17 namespace compiler { | 17 namespace compiler { |
18 | 18 |
19 class ControlBuilder; | 19 class ControlBuilder; |
20 class Graph; | 20 class Graph; |
21 class LivenessAnalyzer; | |
22 class LivenessAnalyzerBlock; | |
21 class LoopAssignmentAnalysis; | 23 class LoopAssignmentAnalysis; |
22 class LoopBuilder; | 24 class LoopBuilder; |
23 class Node; | 25 class Node; |
24 | 26 |
25 // The AstGraphBuilder produces a high-level IR graph, based on an | 27 // The AstGraphBuilder produces a high-level IR graph, based on an |
26 // underlying AST. The produced graph can either be compiled into a | 28 // underlying AST. The produced graph can either be compiled into a |
27 // stand-alone function or be wired into another graph for the purposes | 29 // stand-alone function or be wired into another graph for the purposes |
28 // of function inlining. | 30 // of function inlining. |
29 class AstGraphBuilder : public AstVisitor { | 31 class AstGraphBuilder : public AstVisitor { |
30 public: | 32 public: |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
94 | 96 |
95 // Merge of all control nodes that exit the function body. | 97 // Merge of all control nodes that exit the function body. |
96 Node* exit_control_; | 98 Node* exit_control_; |
97 | 99 |
98 // Result of loop assignment analysis performed before graph creation. | 100 // Result of loop assignment analysis performed before graph creation. |
99 LoopAssignmentAnalysis* loop_assignment_analysis_; | 101 LoopAssignmentAnalysis* loop_assignment_analysis_; |
100 | 102 |
101 // Cache for StateValues nodes for frame states. | 103 // Cache for StateValues nodes for frame states. |
102 StateValuesCache state_values_cache_; | 104 StateValuesCache state_values_cache_; |
103 | 105 |
106 // Analyzer of local variable liveness. | |
107 LivenessAnalyzer* liveness_analyzer_; | |
Benedikt Meurer
2015/03/17 05:12:03
Chromium style guide nit again: Don't turn into po
Jarin
2015/03/17 09:22:56
Done.
| |
108 | |
104 // Growth increment for the temporary buffer used to construct input lists to | 109 // Growth increment for the temporary buffer used to construct input lists to |
105 // new nodes. | 110 // new nodes. |
106 static const int kInputBufferSizeIncrement = 64; | 111 static const int kInputBufferSizeIncrement = 64; |
107 | 112 |
108 Zone* local_zone() const { return local_zone_; } | 113 Zone* local_zone() const { return local_zone_; } |
109 Environment* environment() const { return environment_; } | 114 Environment* environment() const { return environment_; } |
110 AstContext* ast_context() const { return ast_context_; } | 115 AstContext* ast_context() const { return ast_context_; } |
111 ControlScope* execution_control() const { return execution_control_; } | 116 ControlScope* execution_control() const { return execution_control_; } |
112 ContextScope* execution_context() const { return execution_context_; } | 117 ContextScope* execution_context() const { return execution_context_; } |
113 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 118 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
114 CompilationInfo* info() const { return info_; } | 119 CompilationInfo* info() const { return info_; } |
115 LanguageMode language_mode() const; | 120 LanguageMode language_mode() const; |
116 JSGraph* jsgraph() { return jsgraph_; } | 121 JSGraph* jsgraph() { return jsgraph_; } |
117 Graph* graph() { return jsgraph_->graph(); } | 122 Graph* graph() { return jsgraph_->graph(); } |
118 Zone* graph_zone() { return graph()->zone(); } | 123 Zone* graph_zone() { return graph()->zone(); } |
119 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } | 124 JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } |
120 ZoneVector<Handle<Object>>* globals() { return &globals_; } | 125 ZoneVector<Handle<Object>>* globals() { return &globals_; } |
121 Scope* current_scope() const; | 126 Scope* current_scope() const; |
122 Node* current_context() const; | 127 Node* current_context() const; |
123 Node* exit_control() const { return exit_control_; } | 128 Node* exit_control() const { return exit_control_; } |
129 LivenessAnalyzer* liveness_analyzer() { return liveness_analyzer_; } | |
124 | 130 |
125 void set_environment(Environment* env) { environment_ = env; } | 131 void set_environment(Environment* env) { environment_ = env; } |
126 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } | 132 void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } |
127 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } | 133 void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } |
128 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } | 134 void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } |
129 void set_exit_control(Node* exit) { exit_control_ = exit; } | 135 void set_exit_control(Node* exit) { exit_control_ = exit; } |
130 | 136 |
131 // Create the main graph body by visiting the AST. | 137 // Create the main graph body by visiting the AST. |
132 void CreateGraphBody(bool stack_check); | 138 void CreateGraphBody(bool stack_check); |
133 | 139 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 void PrepareFrameStateAfterAndBefore(Node* node, BailoutId ast_id, | 211 void PrepareFrameStateAfterAndBefore(Node* node, BailoutId ast_id, |
206 OutputFrameStateCombine combine, | 212 OutputFrameStateCombine combine, |
207 Node* frame_state_before); | 213 Node* frame_state_before); |
208 | 214 |
209 BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt); | 215 BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt); |
210 | 216 |
211 // Check if the given statement is an OSR entry. | 217 // Check if the given statement is an OSR entry. |
212 // If so, record the stack height into the compilation and return {true}. | 218 // If so, record the stack height into the compilation and return {true}. |
213 bool CheckOsrEntry(IterationStatement* stmt); | 219 bool CheckOsrEntry(IterationStatement* stmt); |
214 | 220 |
221 // Computes local variable liveness and replaces dead variables in | |
222 // frame states with the undefined values. | |
223 void ClearNonLiveSlotsInFrameStates(); | |
224 | |
215 // Helper to wrap a Handle<T> into a Unique<T>. | 225 // Helper to wrap a Handle<T> into a Unique<T>. |
216 template <class T> | 226 template <class T> |
217 Unique<T> MakeUnique(Handle<T> object) { | 227 Unique<T> MakeUnique(Handle<T> object) { |
218 return Unique<T>::CreateUninitialized(object); | 228 return Unique<T>::CreateUninitialized(object); |
219 } | 229 } |
220 | 230 |
221 Node** EnsureInputBufferSize(int size); | 231 Node** EnsureInputBufferSize(int size); |
222 | 232 |
223 // Named and keyed loads require a VectorSlotPair for successful lowering. | 233 // Named and keyed loads require a VectorSlotPair for successful lowering. |
224 VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const; | 234 VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 public: | 375 public: |
366 Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency); | 376 Environment(AstGraphBuilder* builder, Scope* scope, Node* control_dependency); |
367 | 377 |
368 int parameters_count() const { return parameters_count_; } | 378 int parameters_count() const { return parameters_count_; } |
369 int locals_count() const { return locals_count_; } | 379 int locals_count() const { return locals_count_; } |
370 int stack_height() { | 380 int stack_height() { |
371 return static_cast<int>(values()->size()) - parameters_count_ - | 381 return static_cast<int>(values()->size()) - parameters_count_ - |
372 locals_count_; | 382 locals_count_; |
373 } | 383 } |
374 | 384 |
375 // Operations on parameter or local variables. The parameter indices are | 385 // Operations on parameter or local variables. |
376 // shifted by 1 (receiver is parameter index -1 but environment index 0). | 386 void Bind(Variable* variable, Node* node); |
377 void Bind(Variable* variable, Node* node) { | 387 Node* Lookup(Variable* variable); |
378 DCHECK(variable->IsStackAllocated()); | 388 void MarkAllLocalsLive(); |
379 if (variable->IsParameter()) { | |
380 values()->at(variable->index() + 1) = node; | |
381 } else { | |
382 DCHECK(variable->IsStackLocal()); | |
383 values()->at(variable->index() + parameters_count_) = node; | |
384 } | |
385 } | |
386 Node* Lookup(Variable* variable) { | |
387 DCHECK(variable->IsStackAllocated()); | |
388 if (variable->IsParameter()) { | |
389 return values()->at(variable->index() + 1); | |
390 } else { | |
391 DCHECK(variable->IsStackLocal()); | |
392 return values()->at(variable->index() + parameters_count_); | |
393 } | |
394 } | |
395 | 389 |
396 Node* Context() const { return contexts_.back(); } | 390 Node* Context() const { return contexts_.back(); } |
397 void PushContext(Node* context) { contexts()->push_back(context); } | 391 void PushContext(Node* context) { contexts()->push_back(context); } |
398 void PopContext() { contexts()->pop_back(); } | 392 void PopContext() { contexts()->pop_back(); } |
399 | 393 |
400 // Operations on the operand stack. | 394 // Operations on the operand stack. |
401 void Push(Node* node) { | 395 void Push(Node* node) { |
402 values()->push_back(node); | 396 values()->push_back(node); |
403 } | 397 } |
404 Node* Top() { | 398 Node* Top() { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
467 // Copies this environment to a potentially unreachable control-flow point. | 461 // Copies this environment to a potentially unreachable control-flow point. |
468 Environment* CopyAsUnreachable() { | 462 Environment* CopyAsUnreachable() { |
469 Environment* env = Copy(); | 463 Environment* env = Copy(); |
470 env->MarkAsUnreachable(); | 464 env->MarkAsUnreachable(); |
471 return env; | 465 return env; |
472 } | 466 } |
473 | 467 |
474 // Copies this environment at a loop header control-flow point. | 468 // Copies this environment at a loop header control-flow point. |
475 Environment* CopyForLoop(BitVector* assigned, bool is_osr = false) { | 469 Environment* CopyForLoop(BitVector* assigned, bool is_osr = false) { |
476 PrepareForLoop(assigned, is_osr); | 470 PrepareForLoop(assigned, is_osr); |
477 return Copy(); | 471 return CopyAndShareLiveness(); |
478 } | 472 } |
479 | 473 |
480 int ContextStackDepth() { return static_cast<int>(contexts_.size()); } | 474 int ContextStackDepth() { return static_cast<int>(contexts_.size()); } |
481 | 475 |
482 private: | 476 private: |
483 AstGraphBuilder* builder_; | 477 AstGraphBuilder* builder_; |
484 int parameters_count_; | 478 int parameters_count_; |
485 int locals_count_; | 479 int locals_count_; |
480 LivenessAnalyzerBlock* liveness_block_; | |
486 NodeVector values_; | 481 NodeVector values_; |
487 NodeVector contexts_; | 482 NodeVector contexts_; |
488 Node* control_dependency_; | 483 Node* control_dependency_; |
489 Node* effect_dependency_; | 484 Node* effect_dependency_; |
490 Node* parameters_node_; | 485 Node* parameters_node_; |
491 Node* locals_node_; | 486 Node* locals_node_; |
492 Node* stack_node_; | 487 Node* stack_node_; |
493 | 488 |
494 explicit Environment(const Environment* copy); | 489 explicit Environment(Environment* copy); |
495 Environment* Copy() { return new (zone()) Environment(this); } | 490 Environment* Copy() { return new (zone()) Environment(this); } |
491 Environment* CopyAndShareLiveness(); | |
496 void UpdateStateValues(Node** state_values, int offset, int count); | 492 void UpdateStateValues(Node** state_values, int offset, int count); |
497 void UpdateStateValuesWithCache(Node** state_values, int offset, int count); | 493 void UpdateStateValuesWithCache(Node** state_values, int offset, int count); |
498 Zone* zone() const { return builder_->local_zone(); } | 494 Zone* zone() const { return builder_->local_zone(); } |
499 Graph* graph() const { return builder_->graph(); } | 495 Graph* graph() const { return builder_->graph(); } |
500 AstGraphBuilder* builder() const { return builder_; } | 496 AstGraphBuilder* builder() const { return builder_; } |
501 CommonOperatorBuilder* common() { return builder_->common(); } | 497 CommonOperatorBuilder* common() { return builder_->common(); } |
502 NodeVector* values() { return &values_; } | 498 NodeVector* values() { return &values_; } |
503 NodeVector* contexts() { return &contexts_; } | 499 NodeVector* contexts() { return &contexts_; } |
500 LivenessAnalyzerBlock* liveness_block() { return liveness_block_; } | |
504 | 501 |
505 // Prepare environment to be used as loop header. | 502 // Prepare environment to be used as loop header. |
506 void PrepareForLoop(BitVector* assigned, bool is_osr = false); | 503 void PrepareForLoop(BitVector* assigned, bool is_osr = false); |
507 }; | 504 }; |
508 | 505 |
509 } // namespace compiler | 506 } // namespace compiler |
510 } // namespace internal | 507 } // namespace internal |
511 } // namespace v8 | 508 } // namespace v8 |
512 | 509 |
513 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ | 510 #endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ |
OLD | NEW |