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

Side by Side Diff: src/compiler/escape-analysis-reducer.cc

Issue 1608073003: [turbofan] Add TRACE macro for escape analysis. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 11 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 | « src/compiler/escape-analysis.cc ('k') | 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/escape-analysis-reducer.h" 5 #include "src/compiler/escape-analysis-reducer.h"
6 6
7 #include "src/compiler/js-graph.h" 7 #include "src/compiler/js-graph.h"
8 #include "src/counters.h" 8 #include "src/counters.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 namespace internal { 11 namespace internal {
12 namespace compiler { 12 namespace compiler {
13 13
14 #ifdef DEBUG
15 #define TRACE(...) \
16 do { \
17 if (FLAG_trace_turbo_escape) PrintF(__VA_ARGS__); \
18 } while (false)
19 #else
20 #define TRACE(...)
21 #endif // DEBUG
22
14 EscapeAnalysisReducer::EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph, 23 EscapeAnalysisReducer::EscapeAnalysisReducer(Editor* editor, JSGraph* jsgraph,
15 EscapeAnalysis* escape_analysis, 24 EscapeAnalysis* escape_analysis,
16 Zone* zone) 25 Zone* zone)
17 : AdvancedReducer(editor), 26 : AdvancedReducer(editor),
18 jsgraph_(jsgraph), 27 jsgraph_(jsgraph),
19 escape_analysis_(escape_analysis), 28 escape_analysis_(escape_analysis),
20 zone_(zone), 29 zone_(zone),
21 visited_(static_cast<int>(jsgraph->graph()->NodeCount() * 2), zone), 30 visited_(static_cast<int>(jsgraph->graph()->NodeCount() * 2), zone),
22 exists_virtual_allocate_(true) {} 31 exists_virtual_allocate_(true) {}
23 32
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 91
83 92
84 Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) { 93 Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) {
85 DCHECK(node->opcode() == IrOpcode::kLoadField || 94 DCHECK(node->opcode() == IrOpcode::kLoadField ||
86 node->opcode() == IrOpcode::kLoadElement); 95 node->opcode() == IrOpcode::kLoadElement);
87 if (visited_.Contains(node->id())) return NoChange(); 96 if (visited_.Contains(node->id())) return NoChange();
88 visited_.Add(node->id()); 97 visited_.Add(node->id());
89 if (Node* rep = escape_analysis()->GetReplacement(node)) { 98 if (Node* rep = escape_analysis()->GetReplacement(node)) {
90 visited_.Add(node->id()); 99 visited_.Add(node->id());
91 counters()->turbo_escape_loads_replaced()->Increment(); 100 counters()->turbo_escape_loads_replaced()->Increment();
92 if (FLAG_trace_turbo_escape) { 101 TRACE("Replaced #%d (%s) with #%d (%s)\n", node->id(),
93 PrintF("Replaced #%d (%s) with #%d (%s)\n", node->id(), 102 node->op()->mnemonic(), rep->id(), rep->op()->mnemonic());
94 node->op()->mnemonic(), rep->id(), rep->op()->mnemonic());
95 }
96 ReplaceWithValue(node, rep); 103 ReplaceWithValue(node, rep);
97 return Changed(rep); 104 return Changed(rep);
98 } 105 }
99 return NoChange(); 106 return NoChange();
100 } 107 }
101 108
102 109
103 Reduction EscapeAnalysisReducer::ReduceStore(Node* node) { 110 Reduction EscapeAnalysisReducer::ReduceStore(Node* node) {
104 DCHECK(node->opcode() == IrOpcode::kStoreField || 111 DCHECK(node->opcode() == IrOpcode::kStoreField ||
105 node->opcode() == IrOpcode::kStoreElement); 112 node->opcode() == IrOpcode::kStoreElement);
106 if (visited_.Contains(node->id())) return NoChange(); 113 if (visited_.Contains(node->id())) return NoChange();
107 visited_.Add(node->id()); 114 visited_.Add(node->id());
108 if (escape_analysis()->IsVirtual(NodeProperties::GetValueInput(node, 0))) { 115 if (escape_analysis()->IsVirtual(NodeProperties::GetValueInput(node, 0))) {
109 if (FLAG_trace_turbo_escape) { 116 TRACE("Removed #%d (%s) from effect chain\n", node->id(),
110 PrintF("Removed #%d (%s) from effect chain\n", node->id(), 117 node->op()->mnemonic());
111 node->op()->mnemonic());
112 }
113 RelaxEffectsAndControls(node); 118 RelaxEffectsAndControls(node);
114 return Changed(node); 119 return Changed(node);
115 } 120 }
116 return NoChange(); 121 return NoChange();
117 } 122 }
118 123
119 124
120 Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) { 125 Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) {
121 DCHECK_EQ(node->opcode(), IrOpcode::kAllocate); 126 DCHECK_EQ(node->opcode(), IrOpcode::kAllocate);
122 if (visited_.Contains(node->id())) return NoChange(); 127 if (visited_.Contains(node->id())) return NoChange();
123 visited_.Add(node->id()); 128 visited_.Add(node->id());
124 if (escape_analysis()->IsVirtual(node)) { 129 if (escape_analysis()->IsVirtual(node)) {
125 RelaxEffectsAndControls(node); 130 RelaxEffectsAndControls(node);
126 counters()->turbo_escape_allocs_replaced()->Increment(); 131 counters()->turbo_escape_allocs_replaced()->Increment();
127 if (FLAG_trace_turbo_escape) { 132 TRACE("Removed allocate #%d from effect chain\n", node->id());
128 PrintF("Removed allocate #%d from effect chain\n", node->id());
129 }
130 return Changed(node); 133 return Changed(node);
131 } 134 }
132 return NoChange(); 135 return NoChange();
133 } 136 }
134 137
135 138
136 Reduction EscapeAnalysisReducer::ReduceFinishRegion(Node* node) { 139 Reduction EscapeAnalysisReducer::ReduceFinishRegion(Node* node) {
137 DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion); 140 DCHECK_EQ(node->opcode(), IrOpcode::kFinishRegion);
138 Node* effect = NodeProperties::GetEffectInput(node, 0); 141 Node* effect = NodeProperties::GetEffectInput(node, 0);
139 if (effect->opcode() == IrOpcode::kBeginRegion) { 142 if (effect->opcode() == IrOpcode::kBeginRegion) {
140 RelaxEffectsAndControls(effect); 143 RelaxEffectsAndControls(effect);
141 RelaxEffectsAndControls(node); 144 RelaxEffectsAndControls(node);
145 #ifdef DEBUG
142 if (FLAG_trace_turbo_escape) { 146 if (FLAG_trace_turbo_escape) {
143 PrintF("Removed region #%d / #%d from effect chain,", effect->id(), 147 PrintF("Removed region #%d / #%d from effect chain,", effect->id(),
144 node->id()); 148 node->id());
145 PrintF(" %d user(s) of #%d remain(s):", node->UseCount(), node->id()); 149 PrintF(" %d user(s) of #%d remain(s):", node->UseCount(), node->id());
146 for (Edge edge : node->use_edges()) { 150 for (Edge edge : node->use_edges()) {
147 PrintF(" #%d", edge.from()->id()); 151 PrintF(" #%d", edge.from()->id());
148 } 152 }
149 PrintF("\n"); 153 PrintF("\n");
150 } 154 }
155 #endif // DEBUG
151 return Changed(node); 156 return Changed(node);
152 } 157 }
153 return NoChange(); 158 return NoChange();
154 } 159 }
155 160
156 161
157 Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) { 162 Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) {
158 DCHECK_EQ(node->opcode(), IrOpcode::kReferenceEqual); 163 DCHECK_EQ(node->opcode(), IrOpcode::kReferenceEqual);
159 Node* left = NodeProperties::GetValueInput(node, 0); 164 Node* left = NodeProperties::GetValueInput(node, 0);
160 Node* right = NodeProperties::GetValueInput(node, 1); 165 Node* right = NodeProperties::GetValueInput(node, 1);
161 if (escape_analysis()->IsVirtual(left)) { 166 if (escape_analysis()->IsVirtual(left)) {
162 if (escape_analysis()->IsVirtual(right) && 167 if (escape_analysis()->IsVirtual(right) &&
163 escape_analysis()->CompareVirtualObjects(left, right)) { 168 escape_analysis()->CompareVirtualObjects(left, right)) {
164 ReplaceWithValue(node, jsgraph()->TrueConstant()); 169 ReplaceWithValue(node, jsgraph()->TrueConstant());
165 if (FLAG_trace_turbo_escape) { 170 TRACE("Replaced ref eq #%d with true\n", node->id());
166 PrintF("Replaced ref eq #%d with true\n", node->id());
167 }
168 } 171 }
169 // Right-hand side is not a virtual object, or a different one. 172 // Right-hand side is not a virtual object, or a different one.
170 ReplaceWithValue(node, jsgraph()->FalseConstant()); 173 ReplaceWithValue(node, jsgraph()->FalseConstant());
171 if (FLAG_trace_turbo_escape) { 174 TRACE("Replaced ref eq #%d with false\n", node->id());
172 PrintF("Replaced ref eq #%d with false\n", node->id());
173 }
174 return Replace(node); 175 return Replace(node);
175 } else if (escape_analysis()->IsVirtual(right)) { 176 } else if (escape_analysis()->IsVirtual(right)) {
176 // Left-hand side is not a virtual object. 177 // Left-hand side is not a virtual object.
177 ReplaceWithValue(node, jsgraph()->FalseConstant()); 178 ReplaceWithValue(node, jsgraph()->FalseConstant());
178 if (FLAG_trace_turbo_escape) { 179 TRACE("Replaced ref eq #%d with false\n", node->id());
179 PrintF("Replaced ref eq #%d with false\n", node->id());
180 }
181 } 180 }
182 return NoChange(); 181 return NoChange();
183 } 182 }
184 183
185 184
186 Reduction EscapeAnalysisReducer::ReduceObjectIsSmi(Node* node) { 185 Reduction EscapeAnalysisReducer::ReduceObjectIsSmi(Node* node) {
187 DCHECK_EQ(node->opcode(), IrOpcode::kObjectIsSmi); 186 DCHECK_EQ(node->opcode(), IrOpcode::kObjectIsSmi);
188 Node* input = NodeProperties::GetValueInput(node, 0); 187 Node* input = NodeProperties::GetValueInput(node, 0);
189 if (escape_analysis()->IsVirtual(input)) { 188 if (escape_analysis()->IsVirtual(input)) {
190 ReplaceWithValue(node, jsgraph()->FalseConstant()); 189 ReplaceWithValue(node, jsgraph()->FalseConstant());
191 if (FLAG_trace_turbo_escape) { 190 TRACE("Replaced ObjectIsSmi #%d with false\n", node->id());
192 PrintF("Replaced ObjectIsSmi #%d with false\n", node->id());
193 }
194 return Replace(node); 191 return Replace(node);
195 } 192 }
196 return NoChange(); 193 return NoChange();
197 } 194 }
198 195
199 196
200 Reduction EscapeAnalysisReducer::ReduceFrameStateUses(Node* node) { 197 Reduction EscapeAnalysisReducer::ReduceFrameStateUses(Node* node) {
201 if (visited_.Contains(node->id())) return NoChange(); 198 if (visited_.Contains(node->id())) return NoChange();
202 visited_.Add(node->id()); 199 visited_.Add(node->id());
203 DCHECK_GE(node->op()->EffectInputCount(), 1); 200 DCHECK_GE(node->op()->EffectInputCount(), 1);
(...skipping 16 matching lines...) Expand all
220 217
221 // Returns the clone if it duplicated the node, and null otherwise. 218 // Returns the clone if it duplicated the node, and null otherwise.
222 Node* EscapeAnalysisReducer::ReduceDeoptState(Node* node, Node* effect, 219 Node* EscapeAnalysisReducer::ReduceDeoptState(Node* node, Node* effect,
223 bool multiple_users) { 220 bool multiple_users) {
224 DCHECK(node->opcode() == IrOpcode::kFrameState || 221 DCHECK(node->opcode() == IrOpcode::kFrameState ||
225 node->opcode() == IrOpcode::kStateValues); 222 node->opcode() == IrOpcode::kStateValues);
226 if (node->id() < static_cast<NodeId>(visited_.length()) && 223 if (node->id() < static_cast<NodeId>(visited_.length()) &&
227 visited_.Contains(node->id())) { 224 visited_.Contains(node->id())) {
228 return nullptr; 225 return nullptr;
229 } 226 }
230 if (FLAG_trace_turbo_escape) { 227 TRACE("Reducing %s %d\n", node->op()->mnemonic(), node->id());
231 PrintF("Reducing %s %d\n", node->op()->mnemonic(), node->id());
232 }
233 Node* clone = nullptr; 228 Node* clone = nullptr;
234 bool node_multiused = node->UseCount() > 1; 229 bool node_multiused = node->UseCount() > 1;
235 bool multiple_users_rec = multiple_users || node_multiused; 230 bool multiple_users_rec = multiple_users || node_multiused;
236 for (int i = 0; i < node->op()->ValueInputCount(); ++i) { 231 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
237 Node* input = NodeProperties::GetValueInput(node, i); 232 Node* input = NodeProperties::GetValueInput(node, i);
238 if (input->opcode() == IrOpcode::kStateValues) { 233 if (input->opcode() == IrOpcode::kStateValues) {
239 if (Node* ret = ReduceDeoptState(input, effect, multiple_users_rec)) { 234 if (Node* ret = ReduceDeoptState(input, effect, multiple_users_rec)) {
240 if (node_multiused || (multiple_users && !clone)) { 235 if (node_multiused || (multiple_users && !clone)) {
241 if (FLAG_trace_turbo_escape) { 236 TRACE(" Cloning #%d", node->id());
242 PrintF(" Cloning #%d", node->id());
243 }
244 node = clone = jsgraph()->graph()->CloneNode(node); 237 node = clone = jsgraph()->graph()->CloneNode(node);
245 if (FLAG_trace_turbo_escape) { 238 TRACE(" to #%d\n", node->id());
246 PrintF(" to #%d\n", node->id());
247 }
248 node_multiused = false; 239 node_multiused = false;
249 } 240 }
250 NodeProperties::ReplaceValueInput(node, ret, i); 241 NodeProperties::ReplaceValueInput(node, ret, i);
251 } 242 }
252 } else { 243 } else {
253 if (Node* ret = ReduceStateValueInput(node, i, effect, node_multiused, 244 if (Node* ret = ReduceStateValueInput(node, i, effect, node_multiused,
254 clone, multiple_users)) { 245 clone, multiple_users)) {
255 DCHECK_NULL(clone); 246 DCHECK_NULL(clone);
256 node_multiused = false; // Don't clone anymore. 247 node_multiused = false; // Don't clone anymore.
257 node = clone = ret; 248 node = clone = ret;
258 } 249 }
259 } 250 }
260 } 251 }
261 if (node->opcode() == IrOpcode::kFrameState) { 252 if (node->opcode() == IrOpcode::kFrameState) {
262 Node* outer_frame_state = NodeProperties::GetFrameStateInput(node, 0); 253 Node* outer_frame_state = NodeProperties::GetFrameStateInput(node, 0);
263 if (outer_frame_state->opcode() == IrOpcode::kFrameState) { 254 if (outer_frame_state->opcode() == IrOpcode::kFrameState) {
264 if (Node* ret = 255 if (Node* ret =
265 ReduceDeoptState(outer_frame_state, effect, multiple_users_rec)) { 256 ReduceDeoptState(outer_frame_state, effect, multiple_users_rec)) {
266 if (node_multiused || (multiple_users && !clone)) { 257 if (node_multiused || (multiple_users && !clone)) {
267 if (FLAG_trace_turbo_escape) { 258 TRACE(" Cloning #%d", node->id());
268 PrintF(" Cloning #%d", node->id());
269 }
270 node = clone = jsgraph()->graph()->CloneNode(node); 259 node = clone = jsgraph()->graph()->CloneNode(node);
271 if (FLAG_trace_turbo_escape) { 260 TRACE(" to #%d\n", node->id());
272 PrintF(" to #%d\n", node->id());
273 }
274 } 261 }
275 NodeProperties::ReplaceFrameStateInput(node, 0, ret); 262 NodeProperties::ReplaceFrameStateInput(node, 0, ret);
276 } 263 }
277 } 264 }
278 } 265 }
279 return clone; 266 return clone;
280 } 267 }
281 268
282 269
283 // Returns the clone if it duplicated the node, and null otherwise. 270 // Returns the clone if it duplicated the node, and null otherwise.
284 Node* EscapeAnalysisReducer::ReduceStateValueInput(Node* node, int node_index, 271 Node* EscapeAnalysisReducer::ReduceStateValueInput(Node* node, int node_index,
285 Node* effect, 272 Node* effect,
286 bool node_multiused, 273 bool node_multiused,
287 bool already_cloned, 274 bool already_cloned,
288 bool multiple_users) { 275 bool multiple_users) {
289 Node* input = NodeProperties::GetValueInput(node, node_index); 276 Node* input = NodeProperties::GetValueInput(node, node_index);
290 if (FLAG_trace_turbo_escape) { 277 TRACE("Reducing State Input #%d (%s)\n", input->id(),
291 PrintF("Reducing State Input #%d (%s)\n", input->id(), 278 input->op()->mnemonic());
292 input->op()->mnemonic());
293 }
294 Node* clone = nullptr; 279 Node* clone = nullptr;
295 if (input->opcode() == IrOpcode::kFinishRegion || 280 if (input->opcode() == IrOpcode::kFinishRegion ||
296 input->opcode() == IrOpcode::kAllocate) { 281 input->opcode() == IrOpcode::kAllocate) {
297 if (escape_analysis()->IsVirtual(input)) { 282 if (escape_analysis()->IsVirtual(input)) {
298 if (Node* object_state = 283 if (Node* object_state =
299 escape_analysis()->GetOrCreateObjectState(effect, input)) { 284 escape_analysis()->GetOrCreateObjectState(effect, input)) {
300 if (node_multiused || (multiple_users && !already_cloned)) { 285 if (node_multiused || (multiple_users && !already_cloned)) {
301 if (FLAG_trace_turbo_escape) { 286 TRACE("Cloning #%d", node->id());
302 PrintF("Cloning #%d", node->id());
303 }
304 node = clone = jsgraph()->graph()->CloneNode(node); 287 node = clone = jsgraph()->graph()->CloneNode(node);
305 if (FLAG_trace_turbo_escape) { 288 TRACE(" to #%d\n", node->id());
306 PrintF(" to #%d\n", node->id());
307 }
308 node_multiused = false; 289 node_multiused = false;
309 already_cloned = true; 290 already_cloned = true;
310 } 291 }
311 NodeProperties::ReplaceValueInput(node, object_state, node_index); 292 NodeProperties::ReplaceValueInput(node, object_state, node_index);
312 if (FLAG_trace_turbo_escape) { 293 TRACE("Replaced state #%d input #%d with object state #%d\n",
313 PrintF("Replaced state #%d input #%d with object state #%d\n", 294 node->id(), input->id(), object_state->id());
314 node->id(), input->id(), object_state->id());
315 }
316 } else { 295 } else {
317 if (FLAG_trace_turbo_escape) { 296 TRACE("No object state replacement for #%d at effect #%d available.\n",
318 PrintF("No object state replacement available.\n"); 297 input->id(), effect->id());
319 } 298 UNREACHABLE();
320 } 299 }
321 } 300 }
322 } 301 }
323 return clone; 302 return clone;
324 } 303 }
325 304
326 305
327 Counters* EscapeAnalysisReducer::counters() const { 306 Counters* EscapeAnalysisReducer::counters() const {
328 return jsgraph_->isolate()->counters(); 307 return jsgraph_->isolate()->counters();
329 } 308 }
330 309
331 } // namespace compiler 310 } // namespace compiler
332 } // namespace internal 311 } // namespace internal
333 } // namespace v8 312 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/escape-analysis.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698