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

Side by Side 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: 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "src/compiler/escape-analysis-reducer.h"
6
7 #include "src/compiler/js-graph.h"
8 #include "src/compiler/js-operator.h"
9
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13
14 EscapeAnalysisReducer::EscapeAnalysisReducer(
15 Editor* editor, JSGraph* jsgraph, EscapeStatusAnalysis* escape_status,
16 EscapeObjectAnalysis* escape_analysis, Zone* zone)
17 : AdvancedReducer(editor),
18 jsgraph_(jsgraph),
19 escape_status_(escape_status),
20 escape_analysis_(escape_analysis),
21 zone_(zone) {}
22
23
24 Reduction EscapeAnalysisReducer::Reduce(Node* node) {
25 switch (node->opcode()) {
26 case IrOpcode::kLoadField:
27 return ReduceLoadField(node);
28 case IrOpcode::kStoreField:
29 return ReduceStoreField(node);
30 case IrOpcode::kAllocate:
31 return ReduceAllocate(node);
32 case IrOpcode::kFinishRegion:
33 return ReduceFinishRegion(node);
34 case IrOpcode::kReferenceEqual:
35 return ReduceReferenceEqual(node);
36 case IrOpcode::kStateValues:
37 case IrOpcode::kFrameState:
38 return ReplaceWithDeoptDummy(node);
39 default:
40 break;
41 }
42 return NoChange();
43 }
44
45
46 Reduction EscapeAnalysisReducer::ReduceLoadField(Node* node) {
47 DCHECK(node->opcode() == IrOpcode::kLoadField);
Michael Starzinger 2015/11/30 10:05:38 nit: DCHECK_EQ, here and throughout the file.
sigurds 2015/11/30 13:50:23 Done.
48 if (Node* rep = escape_analysis()->representation(node, node->id())) {
Michael Starzinger 2015/11/30 10:05:38 The term "representation" is already pretty overlo
sigurds 2015/11/30 13:50:23 Done.
49 if (FLAG_trace_turbo_escape) {
50 PrintF("Replaced #%d with #%d\n", node->id(), rep->id());
51 }
52 ReplaceWithValue(node, rep);
53 return Changed(rep);
54 }
55 return NoChange();
56 }
57
58
59 Reduction EscapeAnalysisReducer::ReduceStoreField(Node* node) {
60 DCHECK(node->opcode() == IrOpcode::kStoreField);
61 if (escape_status()->IsVirtual(NodeProperties::GetValueInput(node, 0))) {
62 if (FLAG_trace_turbo_escape) {
63 PrintF("Removed store field #%d from effect chain\n", node->id());
64 }
65 RemoveFromEffectChain(node);
66 return Changed(node);
67 }
68 return NoChange();
69 }
70
71
72 void EscapeAnalysisReducer::RemoveFromEffectChain(Node* node) {
Michael Starzinger 2015/11/30 10:05:38 This should be equivalent with calling AdvancedRed
sigurds 2015/11/30 13:50:23 Done.
73 Node* effect = NodeProperties::GetEffectInput(node);
74 for (Edge edge : node->use_edges()) {
75 if (NodeProperties::IsEffectEdge(edge)) {
76 DCHECK_NOT_NULL(effect);
77 edge.UpdateTo(effect);
78 Revisit(node);
79 }
80 }
81 }
82
83
84 Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) {
85 DCHECK(node->opcode() == IrOpcode::kAllocate);
86 if (escape_status()->IsVirtual(node)) {
87 RemoveFromEffectChain(node);
88 if (FLAG_trace_turbo_escape) {
89 PrintF("Removed allocate #%d from effect chain\n", node->id());
90 }
91 return Changed(node);
92 }
93 return NoChange();
94 }
95
96
97 Reduction EscapeAnalysisReducer::ReduceFinishRegion(Node* node) {
98 DCHECK(node->opcode() == IrOpcode::kFinishRegion);
99 Node* effect = NodeProperties::GetEffectInput(node, 0);
100 if (effect->opcode() == IrOpcode::kBeginRegion) {
101 RemoveFromEffectChain(effect);
102 Revisit(effect);
103 RemoveFromEffectChain(node);
104 Revisit(node);
105 if (FLAG_trace_turbo_escape) {
106 PrintF("Removed region #%d / #%d from effect chain,", effect->id(),
107 node->id());
108 PrintF("%d user(s) of #%d remain(s):", node->UseCount(), node->id());
109 for (Edge edge : node->use_edges()) {
110 PrintF(" #%d", edge.from()->id());
111 }
112 PrintF("\n");
113 }
114 return Changed(node);
115 }
116 return NoChange();
117 }
118
119
120 Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) {
121 DCHECK(node->opcode() == IrOpcode::kReferenceEqual);
122 Node* left = NodeProperties::GetValueInput(node, 0);
123 Node* right = NodeProperties::GetValueInput(node, 1);
124 if (escape_status()->IsVirtual(left)) {
125 if (escape_status()->IsVirtual(right)) {
126 if (Node* rep = escape_analysis()->representation(node, left->id())) {
127 left = rep;
128 }
129 if (Node* rep = escape_analysis()->representation(node, right->id())) {
130 right = rep;
131 }
132 // TODO(sigurds): What to do if either is a PHI?
133 if (left == right) {
134 ReplaceWithValue(node, jsgraph()->TrueConstant());
135 if (FLAG_trace_turbo_escape) {
136 PrintF("Replaced ref eq #%d with true\n", node->id());
137 }
138 return Replace(node);
139 }
140 }
141 // Right-hand side is either not virtual, or a different node.
142 ReplaceWithValue(node, jsgraph()->FalseConstant());
143 if (FLAG_trace_turbo_escape) {
144 PrintF("Replaced ref eq #%d with false\n", node->id());
145 }
146 return Replace(node);
147 } else if (escape_status()->IsVirtual(right)) {
148 // Left-hand side is not a virtual object.
149 ReplaceWithValue(node, jsgraph()->FalseConstant());
150 if (FLAG_trace_turbo_escape) {
151 PrintF("Replaced ref eq #%d with false\n", node->id());
152 }
153 }
154 return NoChange();
155 }
156
157
158 Reduction EscapeAnalysisReducer::ReplaceWithDeoptDummy(Node* node) {
Michael Starzinger 2015/11/30 10:05:38 nit: Let's add a TODO comment here, saying that th
sigurds 2015/11/30 13:50:23 Done.
159 DCHECK(node->opcode() == IrOpcode::kStateValues ||
160 node->opcode() == IrOpcode::kFrameState);
161 Reduction r = NoChange();
162 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
163 Node* input = NodeProperties::GetValueInput(node, i);
164 if (input->opcode() == IrOpcode::kFinishRegion ||
165 input->opcode() == IrOpcode::kAllocate ||
166 input->opcode() == IrOpcode::kPhi) {
167 if (escape_status()->IsVirtual(input)) {
168 NodeProperties::ReplaceValueInput(node, jsgraph()->UndefinedConstant(),
169 i);
170 if (FLAG_trace_turbo_escape) {
171 PrintF("Replaced state value (#%d) input with dummy\n", node->id());
172 }
173 r = Changed(node);
174 }
175 }
176 }
177 return r;
178 }
179
180
181 Graph* EscapeAnalysisReducer::graph() const { return jsgraph()->graph(); }
Michael Starzinger 2015/11/30 10:05:38 nit: Method seems to be unused, can we drop it?
sigurds 2015/11/30 13:50:23 Done.
182
183
184 } // namespace compiler
185 } // namespace internal
186 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698