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

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

Issue 1457683003: [turbofan] Initial support for escape analysis. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years 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
« no previous file with comments | « src/compiler/escape-analysis-reducer.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/escape-analysis-reducer.cc
diff --git a/src/compiler/escape-analysis-reducer.cc b/src/compiler/escape-analysis-reducer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1f53582bae98386d9fcd89108f813b61909dcf19
--- /dev/null
+++ b/src/compiler/escape-analysis-reducer.cc
@@ -0,0 +1,171 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/escape-analysis-reducer.h"
+
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+EscapeAnalysisReducer::EscapeAnalysisReducer(
+ Editor* editor, JSGraph* jsgraph, EscapeStatusAnalysis* escape_status,
+ EscapeObjectAnalysis* escape_analysis, Zone* zone)
+ : AdvancedReducer(editor),
+ jsgraph_(jsgraph),
+ escape_status_(escape_status),
+ escape_analysis_(escape_analysis),
+ zone_(zone) {}
+
+
+Reduction EscapeAnalysisReducer::Reduce(Node* node) {
+ switch (node->opcode()) {
+ case IrOpcode::kLoadField:
+ return ReduceLoadField(node);
+ case IrOpcode::kStoreField:
+ return ReduceStoreField(node);
+ case IrOpcode::kAllocate:
+ return ReduceAllocate(node);
+ case IrOpcode::kFinishRegion:
+ return ReduceFinishRegion(node);
+ case IrOpcode::kReferenceEqual:
+ return ReduceReferenceEqual(node);
+ case IrOpcode::kStateValues:
+ case IrOpcode::kFrameState:
+ return ReplaceWithDeoptDummy(node);
+ default:
+ break;
+ }
+ return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceLoadField(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kLoadField);
+ if (Node* rep = escape_analysis()->GetReplacement(node, node->id())) {
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Replaced #%d with #%d\n", node->id(), rep->id());
+ }
+ ReplaceWithValue(node, rep);
+ return Changed(rep);
+ }
+ return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceStoreField(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kStoreField);
+ if (escape_status()->IsVirtual(NodeProperties::GetValueInput(node, 0))) {
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Removed store field #%d from effect chain\n", node->id());
+ }
+ RelaxEffectsAndControls(node);
+ return Changed(node);
+ }
+ return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
+ if (escape_status()->IsVirtual(node)) {
+ RelaxEffectsAndControls(node);
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Removed allocate #%d from effect chain\n", node->id());
+ }
+ return Changed(node);
+ }
+ return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceFinishRegion(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
+ Node* effect = NodeProperties::GetEffectInput(node, 0);
+ if (effect->opcode() == IrOpcode::kBeginRegion) {
+ RelaxEffectsAndControls(effect);
+ RelaxEffectsAndControls(node);
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Removed region #%d / #%d from effect chain,", effect->id(),
+ node->id());
+ PrintF("%d user(s) of #%d remain(s):", node->UseCount(), node->id());
+ for (Edge edge : node->use_edges()) {
+ PrintF(" #%d", edge.from()->id());
+ }
+ PrintF("\n");
+ }
+ return Changed(node);
+ }
+ return NoChange();
+}
+
+
+Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kReferenceEqual);
+ Node* left = NodeProperties::GetValueInput(node, 0);
+ Node* right = NodeProperties::GetValueInput(node, 1);
+ if (escape_status()->IsVirtual(left)) {
+ if (escape_status()->IsVirtual(right)) {
+ if (Node* rep = escape_analysis()->GetReplacement(node, left->id())) {
+ left = rep;
+ }
+ if (Node* rep = escape_analysis()->GetReplacement(node, right->id())) {
+ 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);
+ }
+ }
+ // Right-hand side is either not virtual, or a different node.
+ ReplaceWithValue(node, jsgraph()->FalseConstant());
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Replaced ref eq #%d with false\n", node->id());
+ }
+ return Replace(node);
+ } else if (escape_status()->IsVirtual(right)) {
+ // Left-hand side is not a virtual object.
+ ReplaceWithValue(node, jsgraph()->FalseConstant());
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Replaced ref eq #%d with false\n", node->id());
+ }
+ }
+ return NoChange();
+}
+
+
+// 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();
+ 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_status()->IsVirtual(input)) {
+ NodeProperties::ReplaceValueInput(node, jsgraph()->UndefinedConstant(),
+ i);
+ if (FLAG_trace_turbo_escape) {
+ PrintF("Replaced state value (#%d) input with dummy\n", node->id());
+ }
+ r = Changed(node);
+ }
+ }
+ }
+ return r;
+}
+
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
« no previous file with comments | « src/compiler/escape-analysis-reducer.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698