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

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

Issue 2377343002: [turbofan] Explicit OSR environment merge for bytecode graph builder. (Closed)
Patch Set: 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());
414 DCHECK_EQ(1, GetControlDependency()->InputCount());
Michael Starzinger 2016/09/29 14:29:32 Please preserve these two asserts inside {BuildOSR
Jarin 2016/09/29 14:32:54 Done.
415 Node* start = graph()->start(); 420 Node* start = graph()->start();
416 421
417 // Create a control node for the OSR entry point and merge it into the loop 422 // Create a control node for the OSR entry point and update the current
418 // header. Update the current environment's control dependency accordingly. 423 // environment's dependencies accordingly.
419 Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start); 424 Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start);
420 Node* control = builder()->MergeControl(GetControlDependency(), entry); 425 UpdateControlDependency(entry);
421 UpdateControlDependency(control); 426 UpdateEffectDependency(entry);
422 427
423 // Create a merge of the effect from the OSR entry and the existing effect 428 // Create OSR values for each environment value.
424 // dependency. Update the current environment's effect dependency accordingly. 429 SetContext(graph()->NewNode(
425 Node* effect = builder()->MergeEffect(GetEffectDependency(), entry, control); 430 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()); 431 int size = static_cast<int>(values()->size());
434 for (int i = 0; i < size; i++) { 432 for (int i = 0; i < size; i++) {
435 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly. 433 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly.
436 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount; 434 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
437 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex; 435 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
438 Node* osr_value = graph()->NewNode(common()->OsrValue(idx), entry); 436 values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry);
439 values_[i] = builder()->MergeValue(values_[i], osr_value, control);
440 } 437 }
441 } 438 }
442 439
443 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( 440 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
444 Node** state_values, int offset, int count) { 441 Node** state_values, int offset, int count) {
445 if (*state_values == nullptr) { 442 if (*state_values == nullptr) {
446 return true; 443 return true;
447 } 444 }
448 DCHECK_EQ((*state_values)->InputCount(), count); 445 DCHECK_EQ((*state_values)->InputCount(), count);
449 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); 446 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
(...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 1902
1906 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) { 1903 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1907 exit_controls_.push_back(exit); 1904 exit_controls_.push_back(exit);
1908 set_environment(nullptr); 1905 set_environment(nullptr);
1909 } 1906 }
1910 1907
1911 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) { 1908 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) {
1912 if (!osr_ast_id_.IsNone() && osr_ast_id_.ToInt() == current_offset) { 1909 if (!osr_ast_id_.IsNone() && osr_ast_id_.ToInt() == current_offset) {
1913 // For OSR add a special {OsrLoopEntry} node into the current loop header. 1910 // 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. 1911 // It will be turned into a usable entry by the OSR deconstruction.
1915 environment()->PrepareForOsr(); 1912 Environment* loop_env = merge_environments_[current_offset];
1913 Environment* osr_env = loop_env->CopyForOsrEntry();
1914 osr_env->PrepareForOsrEntry();
1915 loop_env->Merge(osr_env);
1916 } 1916 }
1917 } 1917 }
1918 1918
1919 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() { 1919 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() {
1920 if (!osr_ast_id_.IsNone()) { 1920 if (!osr_ast_id_.IsNone()) {
1921 // For OSR add an {OsrNormalEntry} as the the top-level environment start. 1921 // For OSR add an {OsrNormalEntry} as the the top-level environment start.
1922 // It will be replaced with {Dead} by the OSR deconstruction. 1922 // It will be replaced with {Dead} by the OSR deconstruction.
1923 NewNode(common()->OsrNormalEntry()); 1923 NewNode(common()->OsrNormalEntry());
1924 // Note that the requested OSR entry point must be the target of a backward 1924 // 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. 1925 // 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. 2191 // Phi does not exist yet, introduce one.
2192 value = NewPhi(inputs, value, control); 2192 value = NewPhi(inputs, value, control);
2193 value->ReplaceInput(inputs - 1, other); 2193 value->ReplaceInput(inputs - 1, other);
2194 } 2194 }
2195 return value; 2195 return value;
2196 } 2196 }
2197 2197
2198 } // namespace compiler 2198 } // namespace compiler
2199 } // namespace internal 2199 } // namespace internal
2200 } // namespace v8 2200 } // 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