OLD | NEW |
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/all-nodes.h" | 7 #include "src/compiler/all-nodes.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/counters.h" | 9 #include "src/counters.h" |
10 | 10 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 Type* const original_type = NodeProperties::GetType(original); | 114 Type* const original_type = NodeProperties::GetType(original); |
115 if (!replacement_type->Is(original_type)) { | 115 if (!replacement_type->Is(original_type)) { |
116 Node* const control = NodeProperties::GetControlInput(original); | 116 Node* const control = NodeProperties::GetControlInput(original); |
117 replacement = jsgraph->graph()->NewNode( | 117 replacement = jsgraph->graph()->NewNode( |
118 jsgraph->common()->TypeGuard(original_type), replacement, control); | 118 jsgraph->common()->TypeGuard(original_type), replacement, control); |
119 NodeProperties::SetType(replacement, original_type); | 119 NodeProperties::SetType(replacement, original_type); |
120 } | 120 } |
121 return replacement; | 121 return replacement; |
122 } | 122 } |
123 | 123 |
| 124 Node* SkipTypeGuards(Node* node) { |
| 125 while (node->opcode() == IrOpcode::kTypeGuard) { |
| 126 node = NodeProperties::GetValueInput(node, 0); |
| 127 } |
| 128 return node; |
| 129 } |
| 130 |
124 } // namespace | 131 } // namespace |
125 | 132 |
126 Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) { | 133 Reduction EscapeAnalysisReducer::ReduceLoad(Node* node) { |
127 DCHECK(node->opcode() == IrOpcode::kLoadField || | 134 DCHECK(node->opcode() == IrOpcode::kLoadField || |
128 node->opcode() == IrOpcode::kLoadElement); | 135 node->opcode() == IrOpcode::kLoadElement); |
129 if (node->id() < static_cast<NodeId>(fully_reduced_.length())) { | 136 if (node->id() < static_cast<NodeId>(fully_reduced_.length())) { |
130 fully_reduced_.Add(node->id()); | 137 fully_reduced_.Add(node->id()); |
131 } | 138 } |
132 if (escape_analysis()->IsVirtual(NodeProperties::GetValueInput(node, 0))) { | 139 if (escape_analysis()->IsVirtual( |
| 140 SkipTypeGuards(NodeProperties::GetValueInput(node, 0)))) { |
133 if (Node* rep = escape_analysis()->GetReplacement(node)) { | 141 if (Node* rep = escape_analysis()->GetReplacement(node)) { |
134 isolate()->counters()->turbo_escape_loads_replaced()->Increment(); | 142 isolate()->counters()->turbo_escape_loads_replaced()->Increment(); |
135 TRACE("Replaced #%d (%s) with #%d (%s)\n", node->id(), | 143 TRACE("Replaced #%d (%s) with #%d (%s)\n", node->id(), |
136 node->op()->mnemonic(), rep->id(), rep->op()->mnemonic()); | 144 node->op()->mnemonic(), rep->id(), rep->op()->mnemonic()); |
137 rep = MaybeGuard(jsgraph(), zone(), node, rep); | 145 rep = MaybeGuard(jsgraph(), zone(), node, rep); |
138 ReplaceWithValue(node, rep); | 146 ReplaceWithValue(node, rep); |
139 return Replace(rep); | 147 return Replace(rep); |
140 } | 148 } |
141 } | 149 } |
142 return NoChange(); | 150 return NoChange(); |
143 } | 151 } |
144 | 152 |
145 | 153 |
146 Reduction EscapeAnalysisReducer::ReduceStore(Node* node) { | 154 Reduction EscapeAnalysisReducer::ReduceStore(Node* node) { |
147 DCHECK(node->opcode() == IrOpcode::kStoreField || | 155 DCHECK(node->opcode() == IrOpcode::kStoreField || |
148 node->opcode() == IrOpcode::kStoreElement); | 156 node->opcode() == IrOpcode::kStoreElement); |
149 if (node->id() < static_cast<NodeId>(fully_reduced_.length())) { | 157 if (node->id() < static_cast<NodeId>(fully_reduced_.length())) { |
150 fully_reduced_.Add(node->id()); | 158 fully_reduced_.Add(node->id()); |
151 } | 159 } |
152 if (escape_analysis()->IsVirtual(NodeProperties::GetValueInput(node, 0))) { | 160 if (escape_analysis()->IsVirtual( |
| 161 SkipTypeGuards(NodeProperties::GetValueInput(node, 0)))) { |
153 TRACE("Removed #%d (%s) from effect chain\n", node->id(), | 162 TRACE("Removed #%d (%s) from effect chain\n", node->id(), |
154 node->op()->mnemonic()); | 163 node->op()->mnemonic()); |
155 RelaxEffectsAndControls(node); | 164 RelaxEffectsAndControls(node); |
156 return Changed(node); | 165 return Changed(node); |
157 } | 166 } |
158 return NoChange(); | 167 return NoChange(); |
159 } | 168 } |
160 | 169 |
161 | 170 |
162 Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) { | 171 Reduction EscapeAnalysisReducer::ReduceAllocate(Node* node) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } | 206 } |
198 #endif // DEBUG | 207 #endif // DEBUG |
199 return Changed(node); | 208 return Changed(node); |
200 } | 209 } |
201 return NoChange(); | 210 return NoChange(); |
202 } | 211 } |
203 | 212 |
204 | 213 |
205 Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) { | 214 Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) { |
206 DCHECK_EQ(node->opcode(), IrOpcode::kReferenceEqual); | 215 DCHECK_EQ(node->opcode(), IrOpcode::kReferenceEqual); |
207 Node* left = NodeProperties::GetValueInput(node, 0); | 216 Node* left = SkipTypeGuards(NodeProperties::GetValueInput(node, 0)); |
208 Node* right = NodeProperties::GetValueInput(node, 1); | 217 Node* right = SkipTypeGuards(NodeProperties::GetValueInput(node, 1)); |
209 if (escape_analysis()->IsVirtual(left)) { | 218 if (escape_analysis()->IsVirtual(left)) { |
210 if (escape_analysis()->IsVirtual(right) && | 219 if (escape_analysis()->IsVirtual(right) && |
211 escape_analysis()->CompareVirtualObjects(left, right)) { | 220 escape_analysis()->CompareVirtualObjects(left, right)) { |
212 ReplaceWithValue(node, jsgraph()->TrueConstant()); | 221 ReplaceWithValue(node, jsgraph()->TrueConstant()); |
213 TRACE("Replaced ref eq #%d with true\n", node->id()); | 222 TRACE("Replaced ref eq #%d with true\n", node->id()); |
214 return Replace(jsgraph()->TrueConstant()); | 223 return Replace(jsgraph()->TrueConstant()); |
215 } | 224 } |
216 // Right-hand side is not a virtual object, or a different one. | 225 // Right-hand side is not a virtual object, or a different one. |
217 ReplaceWithValue(node, jsgraph()->FalseConstant()); | 226 ReplaceWithValue(node, jsgraph()->FalseConstant()); |
218 TRACE("Replaced ref eq #%d with false\n", node->id()); | 227 TRACE("Replaced ref eq #%d with false\n", node->id()); |
219 return Replace(jsgraph()->FalseConstant()); | 228 return Replace(jsgraph()->FalseConstant()); |
220 } else if (escape_analysis()->IsVirtual(right)) { | 229 } else if (escape_analysis()->IsVirtual(right)) { |
221 // Left-hand side is not a virtual object. | 230 // Left-hand side is not a virtual object. |
222 ReplaceWithValue(node, jsgraph()->FalseConstant()); | 231 ReplaceWithValue(node, jsgraph()->FalseConstant()); |
223 TRACE("Replaced ref eq #%d with false\n", node->id()); | 232 TRACE("Replaced ref eq #%d with false\n", node->id()); |
224 return Replace(jsgraph()->FalseConstant()); | 233 return Replace(jsgraph()->FalseConstant()); |
225 } | 234 } |
226 return NoChange(); | 235 return NoChange(); |
227 } | 236 } |
228 | 237 |
229 | 238 |
230 Reduction EscapeAnalysisReducer::ReduceObjectIsSmi(Node* node) { | 239 Reduction EscapeAnalysisReducer::ReduceObjectIsSmi(Node* node) { |
231 DCHECK_EQ(node->opcode(), IrOpcode::kObjectIsSmi); | 240 DCHECK_EQ(node->opcode(), IrOpcode::kObjectIsSmi); |
232 Node* input = NodeProperties::GetValueInput(node, 0); | 241 Node* input = SkipTypeGuards(NodeProperties::GetValueInput(node, 0)); |
233 if (escape_analysis()->IsVirtual(input)) { | 242 if (escape_analysis()->IsVirtual(input)) { |
234 ReplaceWithValue(node, jsgraph()->FalseConstant()); | 243 ReplaceWithValue(node, jsgraph()->FalseConstant()); |
235 TRACE("Replaced ObjectIsSmi #%d with false\n", node->id()); | 244 TRACE("Replaced ObjectIsSmi #%d with false\n", node->id()); |
236 return Replace(jsgraph()->FalseConstant()); | 245 return Replace(jsgraph()->FalseConstant()); |
237 } | 246 } |
238 return NoChange(); | 247 return NoChange(); |
239 } | 248 } |
240 | 249 |
241 | 250 |
242 Reduction EscapeAnalysisReducer::ReduceFrameStateUses(Node* node) { | 251 Reduction EscapeAnalysisReducer::ReduceFrameStateUses(Node* node) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 return clone; | 324 return clone; |
316 } | 325 } |
317 | 326 |
318 | 327 |
319 // Returns the clone if it duplicated the node, and null otherwise. | 328 // Returns the clone if it duplicated the node, and null otherwise. |
320 Node* EscapeAnalysisReducer::ReduceStateValueInput(Node* node, int node_index, | 329 Node* EscapeAnalysisReducer::ReduceStateValueInput(Node* node, int node_index, |
321 Node* effect, | 330 Node* effect, |
322 bool node_multiused, | 331 bool node_multiused, |
323 bool already_cloned, | 332 bool already_cloned, |
324 bool multiple_users) { | 333 bool multiple_users) { |
325 Node* input = NodeProperties::GetValueInput(node, node_index); | 334 Node* input = SkipTypeGuards(NodeProperties::GetValueInput(node, node_index)); |
326 if (node->id() < static_cast<NodeId>(fully_reduced_.length()) && | 335 if (node->id() < static_cast<NodeId>(fully_reduced_.length()) && |
327 fully_reduced_.Contains(node->id())) { | 336 fully_reduced_.Contains(node->id())) { |
328 return nullptr; | 337 return nullptr; |
329 } | 338 } |
330 TRACE("Reducing State Input #%d (%s)\n", input->id(), | 339 TRACE("Reducing State Input #%d (%s)\n", input->id(), |
331 input->op()->mnemonic()); | 340 input->op()->mnemonic()); |
332 Node* clone = nullptr; | 341 Node* clone = nullptr; |
333 if (input->opcode() == IrOpcode::kFinishRegion || | 342 if (input->opcode() == IrOpcode::kFinishRegion || |
334 input->opcode() == IrOpcode::kAllocate) { | 343 input->opcode() == IrOpcode::kAllocate) { |
335 if (escape_analysis()->IsVirtual(input)) { | 344 if (escape_analysis()->IsVirtual(input)) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 } | 380 } |
372 } | 381 } |
373 #endif // DEBUG | 382 #endif // DEBUG |
374 } | 383 } |
375 | 384 |
376 Isolate* EscapeAnalysisReducer::isolate() const { return jsgraph_->isolate(); } | 385 Isolate* EscapeAnalysisReducer::isolate() const { return jsgraph_->isolate(); } |
377 | 386 |
378 } // namespace compiler | 387 } // namespace compiler |
379 } // namespace internal | 388 } // namespace internal |
380 } // namespace v8 | 389 } // namespace v8 |
OLD | NEW |