Chromium Code Reviews| 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 |