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

Unified Diff: src/compiler/escape-analysis-reducer.cc

Issue 1485183002: [turbofan] Deopt support for escape analysis (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@ea-local
Patch Set: Improve Unittest and guard printf behind --trace-turbo-escape Created 4 years, 12 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/escape-analysis-reducer.cc
diff --git a/src/compiler/escape-analysis-reducer.cc b/src/compiler/escape-analysis-reducer.cc
index 4cf8f9279e99deff88970af2f2fb8522e384c46c..c11b5dbfad9fa852d0e1cbd0686ac53f2b542743 100644
--- a/src/compiler/escape-analysis-reducer.cc
+++ b/src/compiler/escape-analysis-reducer.cc
@@ -36,10 +36,10 @@ Reduction EscapeAnalysisReducer::Reduce(Node* node) {
return ReduceReferenceEqual(node);
case IrOpcode::kObjectIsSmi:
return ReduceObjectIsSmi(node);
- case IrOpcode::kStateValues:
- case IrOpcode::kFrameState:
- return ReplaceWithDeoptDummy(node);
default:
+ if (node->op()->EffectInputCount() > 0) {
Jarin 2016/01/05 12:51:19 As discussed offline, this serves as an over-appro
sigurds 2016/01/05 13:08:57 Done.
+ return ReduceFrameStateUses(node);
+ }
break;
}
return NoChange();
@@ -125,23 +125,14 @@ Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) {
Node* left = NodeProperties::GetValueInput(node, 0);
Node* right = NodeProperties::GetValueInput(node, 1);
if (escape_analysis()->IsVirtual(left)) {
- if (escape_analysis()->IsVirtual(right)) {
- if (Node* rep = escape_analysis()->GetReplacement(left)) {
- left = rep;
- }
- if (Node* rep = escape_analysis()->GetReplacement(right)) {
- right = rep;
- }
- // TODO(sigurds): What to do if either is a PHI?
- if (left == right) {
- ReplaceWithValue(node, jsgraph()->TrueConstant());
- if (FLAG_trace_turbo_escape) {
- PrintF("Replaced ref eq #%d with true\n", node->id());
- }
- return Replace(node);
+ if (escape_analysis()->IsVirtual(right) &&
+ escape_analysis()->CompareVirtualObjects(left, right)) {
+ ReplaceWithValue(node, jsgraph()->TrueConstant());
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Replaced ref eq #%d with true\n", node->id());
}
}
- // Right-hand side is either not virtual, or a different node.
+ // Right-hand side is not a virtual object, or a different one.
ReplaceWithValue(node, jsgraph()->FalseConstant());
if (FLAG_trace_turbo_escape) {
PrintF("Replaced ref eq #%d with false\n", node->id());
@@ -172,31 +163,132 @@ Reduction EscapeAnalysisReducer::ReduceObjectIsSmi(Node* node) {
}
-// TODO(sigurds): This is a temporary solution until escape analysis
-// supports deoptimization.
-Reduction EscapeAnalysisReducer::ReplaceWithDeoptDummy(Node* node) {
- DCHECK(node->opcode() == IrOpcode::kStateValues ||
- node->opcode() == IrOpcode::kFrameState);
- Reduction r = NoChange();
+Reduction EscapeAnalysisReducer::ReduceFrameStateUses(Node* node) {
+ DCHECK_GE(node->op()->EffectInputCount(), 1);
+ bool changed = false;
+ for (int i = 0; i < node->InputCount(); ++i) {
+ Node* input = node->InputAt(i);
+ if (input->opcode() == IrOpcode::kFrameState) {
+ if (Node* ret = ReduceFrameState(input, node, false)) {
+ node->ReplaceInput(i, ret);
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ return Changed(node);
+ }
+ return NoChange();
+}
+
+
+Node* EscapeAnalysisReducer::ReduceFrameState(Node* node, Node* effect,
+ bool multiple_users) {
+ DCHECK(node->opcode() == IrOpcode::kFrameState);
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Reducing FrameState %d\n", node->id());
+ }
+ Node* clone = nullptr;
for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
Node* input = NodeProperties::GetValueInput(node, i);
- if (input->opcode() == IrOpcode::kFinishRegion ||
- input->opcode() == IrOpcode::kAllocate ||
- input->opcode() == IrOpcode::kPhi) {
- if (escape_analysis()->IsVirtual(input)) {
- NodeProperties::ReplaceValueInput(node, jsgraph()->UndefinedConstant(),
- i);
+ Node* ret =
+ input->opcode() == IrOpcode::kStateValues
+ ? ReduceStateValueInputs(input, effect, node->UseCount() > 1)
+ : ReduceStateValueInput(node, i, effect, node->UseCount() > 1);
+ if (ret) {
+ if (node->UseCount() > 1 || multiple_users) {
+ if (FLAG_trace_turbo_escape) {
+ PrintF(" Cloning #%d", node->id());
+ }
+ node = clone = jsgraph()->graph()->CloneNode(node);
+ if (FLAG_trace_turbo_escape) {
+ PrintF(" to #%d\n", node->id());
+ }
+ multiple_users = false; // Don't clone anymore.
+ }
+ NodeProperties::ReplaceValueInput(node, ret, i);
+ }
+ }
+ Node* outer_frame_state = NodeProperties::GetFrameStateInput(node, 0);
+ if (outer_frame_state->opcode() == IrOpcode::kFrameState) {
+ if (Node* ret =
+ ReduceFrameState(outer_frame_state, effect, node->UseCount() > 1)) {
+ if (node->UseCount() > 1 || multiple_users) {
+ if (FLAG_trace_turbo_escape) {
+ PrintF(" Cloning #%d", node->id());
+ }
+ node = clone = jsgraph()->graph()->CloneNode(node);
if (FLAG_trace_turbo_escape) {
- PrintF("Replaced state value (#%d) input with dummy\n", node->id());
+ PrintF(" to #%d\n", node->id());
}
- r = Changed(node);
+ multiple_users = false;
}
+ NodeProperties::ReplaceFrameStateInput(node, 0, ret);
}
}
- return r;
+ return clone;
}
+Node* EscapeAnalysisReducer::ReduceStateValueInputs(Node* node, Node* effect,
+ bool multiple_users) {
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Reducing StateValue #%d\n", node->id());
+ }
+ DCHECK(node->opcode() == IrOpcode::kStateValues);
+ DCHECK_NOT_NULL(effect);
+ Node* clone = nullptr;
+ for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
+ if (Node* ret = ReduceStateValueInput(node, i, effect, multiple_users)) {
+ node = ret;
+ DCHECK_NULL(clone);
+ clone = ret;
+ multiple_users = false;
+ }
+ }
+ return clone;
+}
+
+
+// Return the clone if it duplicated the node, and null otherwise.
Jarin 2016/01/05 12:51:19 Maybe you want to add the same comment to the meth
sigurds 2016/01/05 13:08:57 Done.
+Node* EscapeAnalysisReducer::ReduceStateValueInput(Node* node, int node_index,
+ Node* effect,
+ bool multiple_users) {
+ Node* input = NodeProperties::GetValueInput(node, node_index);
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Reducing State Input #%d (%s)\n", input->id(),
+ input->op()->mnemonic());
+ }
+ Node* clone = nullptr;
+ if (input->opcode() == IrOpcode::kFinishRegion ||
+ input->opcode() == IrOpcode::kAllocate) {
+ if (escape_analysis()->IsVirtual(input)) {
+ if (Node* object_state =
+ escape_analysis()->GetOrCreateObjectState(effect, input)) {
+ if (node->UseCount() > 1 || multiple_users) {
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Cloning #%d", node->id());
+ }
+ node = clone = jsgraph()->graph()->CloneNode(node);
+ if (FLAG_trace_turbo_escape) {
+ PrintF(" to #%d\n", node->id());
+ }
+ }
+ NodeProperties::ReplaceValueInput(node, object_state, node_index);
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Replaced state #%d input #%d with object state #%d\n",
+ node->id(), input->id(), object_state->id());
+ }
+ } else {
+ if (FLAG_trace_turbo_escape) {
+ PrintF("No object state replacement available.\n");
+ }
+ }
+ }
+ }
+ return clone;
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698