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

Side by Side Diff: src/compiler/bytecode-graph-builder.cc

Issue 2377343002: [turbofan] Explicit OSR environment merge for bytecode graph builder. (Closed)
Patch Set: Address comment Created 4 years, 2 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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 #include "src/compiler/bytecode-graph-builder.h" 5 #include "src/compiler/bytecode-graph-builder.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler/bytecode-branch-analysis.h" 10 #include "src/compiler/bytecode-branch-analysis.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 Node* GetControlDependency() const { return control_dependency_; } 58 Node* GetControlDependency() const { return control_dependency_; }
59 void UpdateControlDependency(Node* dependency) { 59 void UpdateControlDependency(Node* dependency) {
60 control_dependency_ = dependency; 60 control_dependency_ = dependency;
61 } 61 }
62 62
63 Node* Context() const { return context_; } 63 Node* Context() const { return context_; }
64 void SetContext(Node* new_context) { context_ = new_context; } 64 void SetContext(Node* new_context) { context_ = new_context; }
65 65
66 Environment* CopyForConditional(); 66 Environment* CopyForConditional();
67 Environment* CopyForLoop(); 67 Environment* CopyForLoop();
68 Environment* CopyForOsrEntry();
68 void Merge(Environment* other); 69 void Merge(Environment* other);
69 void PrepareForOsr(); 70 void PrepareForOsrEntry();
70 71
71 void PrepareForLoopExit(Node* loop); 72 void PrepareForLoopExit(Node* loop);
72 73
73 private: 74 private:
74 Environment(const Environment* copy, LivenessAnalyzerBlock* liveness_block); 75 Environment(const Environment* copy, LivenessAnalyzerBlock* liveness_block);
75 void PrepareForLoop(); 76 void PrepareForLoop();
76 77
77 enum { kNotCached, kCached }; 78 enum { kNotCached, kCached };
78 79
79 bool StateValuesAreUpToDate(Node** state_values, int offset, int count, 80 bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 BytecodeGraphBuilder::Environment::CopyForLoop() { 340 BytecodeGraphBuilder::Environment::CopyForLoop() {
340 PrepareForLoop(); 341 PrepareForLoop();
341 if (liveness_block() != nullptr) { 342 if (liveness_block() != nullptr) {
342 // Finish the current block before copying. 343 // Finish the current block before copying.
343 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); 344 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
344 } 345 }
345 return new (zone()) Environment(this, liveness_block()); 346 return new (zone()) Environment(this, liveness_block());
346 } 347 }
347 348
348 BytecodeGraphBuilder::Environment* 349 BytecodeGraphBuilder::Environment*
350 BytecodeGraphBuilder::Environment::CopyForOsrEntry() {
351 return new (zone())
352 Environment(this, builder_->liveness_analyzer()->NewBlock());
353 }
354
355 BytecodeGraphBuilder::Environment*
349 BytecodeGraphBuilder::Environment::CopyForConditional() { 356 BytecodeGraphBuilder::Environment::CopyForConditional() {
350 LivenessAnalyzerBlock* copy_liveness_block = nullptr; 357 LivenessAnalyzerBlock* copy_liveness_block = nullptr;
351 if (liveness_block() != nullptr) { 358 if (liveness_block() != nullptr) {
352 copy_liveness_block = 359 copy_liveness_block =
353 builder_->liveness_analyzer()->NewBlock(liveness_block()); 360 builder_->liveness_analyzer()->NewBlock(liveness_block());
354 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block()); 361 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
355 } 362 }
356 return new (zone()) Environment(this, copy_liveness_block); 363 return new (zone()) Environment(this, copy_liveness_block);
357 } 364 }
358 365
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 for (int i = 0; i < size; i++) { 409 for (int i = 0; i < size; i++) {
403 values()->at(i) = builder()->NewPhi(1, values()->at(i), control); 410 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
404 } 411 }
405 412
406 // Connect to the loop end. 413 // Connect to the loop end.
407 Node* terminate = builder()->graph()->NewNode( 414 Node* terminate = builder()->graph()->NewNode(
408 builder()->common()->Terminate(), effect, control); 415 builder()->common()->Terminate(), effect, control);
409 builder()->exit_controls_.push_back(terminate); 416 builder()->exit_controls_.push_back(terminate);
410 } 417 }
411 418
412 void BytecodeGraphBuilder::Environment::PrepareForOsr() { 419 void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() {
413 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode()); 420 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode());
414 DCHECK_EQ(1, GetControlDependency()->InputCount()); 421 DCHECK_EQ(1, GetControlDependency()->InputCount());
422
415 Node* start = graph()->start(); 423 Node* start = graph()->start();
416 424
417 // Create a control node for the OSR entry point and merge it into the loop 425 // Create a control node for the OSR entry point and update the current
418 // header. Update the current environment's control dependency accordingly. 426 // environment's dependencies accordingly.
419 Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start); 427 Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start);
420 Node* control = builder()->MergeControl(GetControlDependency(), entry); 428 UpdateControlDependency(entry);
421 UpdateControlDependency(control); 429 UpdateEffectDependency(entry);
422 430
423 // Create a merge of the effect from the OSR entry and the existing effect 431 // Create OSR values for each environment value.
424 // dependency. Update the current environment's effect dependency accordingly. 432 SetContext(graph()->NewNode(
425 Node* effect = builder()->MergeEffect(GetEffectDependency(), entry, control); 433 common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry));
426 UpdateEffectDependency(effect);
427
428 // Rename all values in the environment which will extend or introduce Phi
429 // nodes to contain the OSR values available at the entry point.
430 Node* osr_context = graph()->NewNode(
431 common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry);
432 context_ = builder()->MergeValue(context_, osr_context, control);
433 int size = static_cast<int>(values()->size()); 434 int size = static_cast<int>(values()->size());
434 for (int i = 0; i < size; i++) { 435 for (int i = 0; i < size; i++) {
435 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly. 436 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly.
436 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount; 437 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
437 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex; 438 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
438 Node* osr_value = graph()->NewNode(common()->OsrValue(idx), entry); 439 values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry);
439 values_[i] = builder()->MergeValue(values_[i], osr_value, control);
440 } 440 }
441 } 441 }
442 442
443 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( 443 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
444 Node** state_values, int offset, int count) { 444 Node** state_values, int offset, int count) {
445 if (*state_values == nullptr) { 445 if (*state_values == nullptr) {
446 return true; 446 return true;
447 } 447 }
448 DCHECK_EQ((*state_values)->InputCount(), count); 448 DCHECK_EQ((*state_values)->InputCount(), count);
449 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); 449 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
(...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 1905
1906 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) { 1906 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1907 exit_controls_.push_back(exit); 1907 exit_controls_.push_back(exit);
1908 set_environment(nullptr); 1908 set_environment(nullptr);
1909 } 1909 }
1910 1910
1911 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) { 1911 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) {
1912 if (!osr_ast_id_.IsNone() && osr_ast_id_.ToInt() == current_offset) { 1912 if (!osr_ast_id_.IsNone() && osr_ast_id_.ToInt() == current_offset) {
1913 // For OSR add a special {OsrLoopEntry} node into the current loop header. 1913 // For OSR add a special {OsrLoopEntry} node into the current loop header.
1914 // It will be turned into a usable entry by the OSR deconstruction. 1914 // It will be turned into a usable entry by the OSR deconstruction.
1915 environment()->PrepareForOsr(); 1915 Environment* loop_env = merge_environments_[current_offset];
1916 Environment* osr_env = loop_env->CopyForOsrEntry();
1917 osr_env->PrepareForOsrEntry();
1918 loop_env->Merge(osr_env);
1916 } 1919 }
1917 } 1920 }
1918 1921
1919 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() { 1922 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() {
1920 if (!osr_ast_id_.IsNone()) { 1923 if (!osr_ast_id_.IsNone()) {
1921 // For OSR add an {OsrNormalEntry} as the the top-level environment start. 1924 // For OSR add an {OsrNormalEntry} as the the top-level environment start.
1922 // It will be replaced with {Dead} by the OSR deconstruction. 1925 // It will be replaced with {Dead} by the OSR deconstruction.
1923 NewNode(common()->OsrNormalEntry()); 1926 NewNode(common()->OsrNormalEntry());
1924 // Note that the requested OSR entry point must be the target of a backward 1927 // Note that the requested OSR entry point must be the target of a backward
1925 // branch, otherwise there will not be a proper loop header available. 1928 // branch, otherwise there will not be a proper loop header available.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 // Phi does not exist yet, introduce one. 2194 // Phi does not exist yet, introduce one.
2192 value = NewPhi(inputs, value, control); 2195 value = NewPhi(inputs, value, control);
2193 value->ReplaceInput(inputs - 1, other); 2196 value->ReplaceInput(inputs - 1, other);
2194 } 2197 }
2195 return value; 2198 return value;
2196 } 2199 }
2197 2200
2198 } // namespace compiler 2201 } // namespace compiler
2199 } // namespace internal 2202 } // namespace internal
2200 } // namespace v8 2203 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698