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

Unified Diff: src/compiler/bytecode-graph-builder.cc

Issue 2188533002: [turbofan] Generate loop exits in the bytecode graph builder. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix translation of int32 constants to allow smis. Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: src/compiler/bytecode-graph-builder.cc
diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc
index 4ec83f85d8123e03bb52162444c7e59a77ada2fa..63f3d46a482bee493ea784942ff4e2dcfa423a2e 100644
--- a/src/compiler/bytecode-graph-builder.cc
+++ b/src/compiler/bytecode-graph-builder.cc
@@ -62,6 +62,8 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
void Merge(Environment* other);
void PrepareForOsr();
+ void PrepareForLoopExit(Node* loop);
+
private:
explicit Environment(const Environment* copy);
void PrepareForLoop();
@@ -465,6 +467,28 @@ bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
1, output_poke_start, output_poke_end);
}
+void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) {
Michael Starzinger 2016/07/29 08:54:46 nit: Can we move this up a few functions close to
Jarin 2016/07/29 11:36:46 Done.
+ DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
+
+ Node* control = GetControlDependency();
+
+ // Create the loop exit node.
+ Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
+ UpdateControlDependency(loop_exit);
+
+ // Rename the environmnent values.
Michael Starzinger 2016/07/29 08:58:21 Is it OK not to handle "context_" here?
Jarin 2016/07/29 11:36:46 Not ok, great catch! (Well, not ok if we want to a
+ for (size_t i = 0; i < values()->size(); i++) {
+ Node* rename =
+ graph()->NewNode(common()->LoopExitValue(), (*values())[i], loop_exit);
Michael Starzinger 2016/07/29 08:54:46 nit: Just "values_[i]".
Jarin 2016/07/29 11:36:46 Done.
+ (*values())[i] = rename;
Michael Starzinger 2016/07/29 08:54:45 nit: Just "values_[i]".
Jarin 2016/07/29 11:36:46 Done.
+ }
+
+ // Rename the effect.
Michael Starzinger 2016/07/29 08:54:46 nit: Can we handle the effect before the values, j
Jarin 2016/07/29 11:36:46 Done.
+ Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
+ GetEffectDependency(), loop_exit);
+ UpdateEffectDependency(effect_rename);
+}
+
BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
CompilationInfo* info,
JSGraph* jsgraph)
@@ -571,8 +595,11 @@ bool BytecodeGraphBuilder::CreateGraph() {
void BytecodeGraphBuilder::VisitBytecodes() {
BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
+ BytecodeLoopAnalysis loop_analysis(bytecode_array(), &analysis, local_zone());
analysis.Analyze();
+ loop_analysis.Analyze();
set_branch_analysis(&analysis);
+ set_loop_analysis(&loop_analysis);
interpreter::BytecodeArrayIterator iterator(bytecode_array());
set_bytecode_iterator(&iterator);
while (!iterator.done()) {
@@ -1115,6 +1142,7 @@ void BytecodeGraphBuilder::BuildThrow() {
}
void BytecodeGraphBuilder::VisitThrow() {
+ BuildLoopExitsForFunctionExit();
BuildThrow();
Node* call = environment()->LookupAccumulator();
Node* control = NewNode(common()->Throw(), call);
@@ -1122,6 +1150,7 @@ void BytecodeGraphBuilder::VisitThrow() {
}
void BytecodeGraphBuilder::VisitReThrow() {
+ BuildLoopExitsForFunctionExit();
Node* value = environment()->LookupAccumulator();
Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
Node* control = NewNode(common()->Throw(), call);
@@ -1438,6 +1467,7 @@ void BytecodeGraphBuilder::VisitOsrPoll() {
}
void BytecodeGraphBuilder::VisitReturn() {
+ BuildLoopExitsForFunctionExit();
Node* control =
NewNode(common()->Return(), environment()->LookupAccumulator());
MergeControlToLeaveFunction(control);
@@ -1583,6 +1613,7 @@ void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
}
void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
+ BuildLoopExitsForBranch(target_offset);
if (merge_environments_[target_offset] == nullptr) {
// Append merge nodes to the environment. We may merge here with another
// environment. So add a place holder for merge nodes. We may add redundant
@@ -1601,6 +1632,28 @@ void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
set_environment(nullptr);
}
+void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
+ int origin_offset = bytecode_iterator().current_offset();
+ // Only build loop exits for forward edges.
+ if (target_offset > origin_offset) {
+ BuildLoopExitsUntilLoop(loop_analysis()->GetLoopOffsetFor(target_offset));
+ }
+}
+
+void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) {
+ int origin_offset = bytecode_iterator().current_offset();
+ int current_loop = loop_analysis()->GetLoopOffsetFor(origin_offset);
+ while (loop_offset < current_loop) {
+ Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
+ environment()->PrepareForLoopExit(loop_node);
+ current_loop = loop_analysis()->GetParentLoopFor(current_loop);
+ }
+}
+
+void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() {
+ BuildLoopExitsUntilLoop(-1);
+}
+
void BytecodeGraphBuilder::BuildJump() {
MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
}

Powered by Google App Engine
This is Rietveld 408576698