OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/load-elimination.h" | 5 #include "src/compiler/load-elimination.h" |
6 | 6 |
7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
8 #include "src/compiler/simplified-operator.h" | 8 #include "src/compiler/simplified-operator.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 } | 44 } |
45 | 45 |
46 bool MayAlias(Node* a, Node* b) { return QueryAlias(a, b) != kNoAlias; } | 46 bool MayAlias(Node* a, Node* b) { return QueryAlias(a, b) != kNoAlias; } |
47 | 47 |
48 bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; } | 48 bool MustAlias(Node* a, Node* b) { return QueryAlias(a, b) == kMustAlias; } |
49 | 49 |
50 } // namespace | 50 } // namespace |
51 | 51 |
52 Reduction LoadElimination::Reduce(Node* node) { | 52 Reduction LoadElimination::Reduce(Node* node) { |
53 switch (node->opcode()) { | 53 switch (node->opcode()) { |
| 54 case IrOpcode::kCheckMaps: |
| 55 return ReduceCheckMaps(node); |
| 56 case IrOpcode::kTransitionElementsKind: |
| 57 return ReduceTransitionElementsKind(node); |
54 case IrOpcode::kLoadField: | 58 case IrOpcode::kLoadField: |
55 return ReduceLoadField(node); | 59 return ReduceLoadField(node); |
56 case IrOpcode::kStoreField: | 60 case IrOpcode::kStoreField: |
57 return ReduceStoreField(node); | 61 return ReduceStoreField(node); |
58 case IrOpcode::kLoadElement: | 62 case IrOpcode::kLoadElement: |
59 return ReduceLoadElement(node); | 63 return ReduceLoadElement(node); |
60 case IrOpcode::kStoreElement: | 64 case IrOpcode::kStoreElement: |
61 return ReduceStoreElement(node); | 65 return ReduceStoreElement(node); |
62 case IrOpcode::kEffectPhi: | 66 case IrOpcode::kEffectPhi: |
63 return ReduceEffectPhi(node); | 67 return ReduceEffectPhi(node); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 return nullptr; | 298 return nullptr; |
295 } | 299 } |
296 | 300 |
297 void LoadElimination::AbstractStateForEffectNodes::Set( | 301 void LoadElimination::AbstractStateForEffectNodes::Set( |
298 Node* node, AbstractState const* state) { | 302 Node* node, AbstractState const* state) { |
299 size_t const id = node->id(); | 303 size_t const id = node->id(); |
300 if (id >= info_for_node_.size()) info_for_node_.resize(id + 1, nullptr); | 304 if (id >= info_for_node_.size()) info_for_node_.resize(id + 1, nullptr); |
301 info_for_node_[id] = state; | 305 info_for_node_[id] = state; |
302 } | 306 } |
303 | 307 |
| 308 Reduction LoadElimination::ReduceCheckMaps(Node* node) { |
| 309 Node* const object = NodeProperties::GetValueInput(node, 0); |
| 310 Node* const effect = NodeProperties::GetEffectInput(node); |
| 311 AbstractState const* state = node_states_.Get(effect); |
| 312 if (state == nullptr) return NoChange(); |
| 313 int const map_input_count = node->op()->ValueInputCount() - 1; |
| 314 if (Node* const object_map = state->LookupField(object, 0)) { |
| 315 for (int i = 0; i < map_input_count; ++i) { |
| 316 Node* map = NodeProperties::GetValueInput(node, 1 + i); |
| 317 if (map == object_map) return Replace(effect); |
| 318 } |
| 319 } |
| 320 if (map_input_count == 1) { |
| 321 Node* const map0 = NodeProperties::GetValueInput(node, 1); |
| 322 state = state->AddField(object, 0, map0, zone()); |
| 323 } |
| 324 return UpdateState(node, state); |
| 325 } |
| 326 |
| 327 Reduction LoadElimination::ReduceTransitionElementsKind(Node* node) { |
| 328 Node* const object = NodeProperties::GetValueInput(node, 0); |
| 329 Node* const source_map = NodeProperties::GetValueInput(node, 1); |
| 330 Node* const target_map = NodeProperties::GetValueInput(node, 2); |
| 331 Node* const effect = NodeProperties::GetEffectInput(node); |
| 332 AbstractState const* state = node_states_.Get(effect); |
| 333 if (state == nullptr) return NoChange(); |
| 334 if (Node* const object_map = state->LookupField(object, 0)) { |
| 335 state = state->KillField(object, 0, zone()); |
| 336 if (source_map == object_map) { |
| 337 state = state->AddField(object, 0, target_map, zone()); |
| 338 } |
| 339 } else { |
| 340 state = state->KillField(object, 0, zone()); |
| 341 } |
| 342 ElementsTransition transition = ElementsTransitionOf(node->op()); |
| 343 switch (transition) { |
| 344 case ElementsTransition::kFastTransition: |
| 345 break; |
| 346 case ElementsTransition::kSlowTransition: |
| 347 // Kill the elements as well. |
| 348 state = state->KillField(object, 2, zone()); |
| 349 break; |
| 350 } |
| 351 return UpdateState(node, state); |
| 352 } |
| 353 |
304 Reduction LoadElimination::ReduceLoadField(Node* node) { | 354 Reduction LoadElimination::ReduceLoadField(Node* node) { |
305 FieldAccess const& access = FieldAccessOf(node->op()); | 355 FieldAccess const& access = FieldAccessOf(node->op()); |
306 Node* const object = NodeProperties::GetValueInput(node, 0); | 356 Node* const object = NodeProperties::GetValueInput(node, 0); |
307 Node* const effect = NodeProperties::GetEffectInput(node); | 357 Node* const effect = NodeProperties::GetEffectInput(node); |
308 AbstractState const* state = node_states_.Get(effect); | 358 AbstractState const* state = node_states_.Get(effect); |
309 if (state == nullptr) return NoChange(); | 359 if (state == nullptr) return NoChange(); |
310 int field_index = FieldIndexOf(access); | 360 int field_index = FieldIndexOf(access); |
311 if (field_index >= 0) { | 361 if (field_index >= 0) { |
312 if (Node* const replacement = state->LookupField(object, field_index)) { | 362 if (Node* const replacement = state->LookupField(object, field_index)) { |
313 // Make sure the {replacement} has at least as good type | 363 // Make sure the {replacement} has at least as good type |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 DCHECK_EQ(kTaggedBase, access.base_is_tagged); | 592 DCHECK_EQ(kTaggedBase, access.base_is_tagged); |
543 DCHECK_EQ(0, access.offset % kPointerSize); | 593 DCHECK_EQ(0, access.offset % kPointerSize); |
544 int field_index = access.offset / kPointerSize; | 594 int field_index = access.offset / kPointerSize; |
545 if (field_index >= static_cast<int>(kMaxTrackedFields)) return -1; | 595 if (field_index >= static_cast<int>(kMaxTrackedFields)) return -1; |
546 return field_index; | 596 return field_index; |
547 } | 597 } |
548 | 598 |
549 } // namespace compiler | 599 } // namespace compiler |
550 } // namespace internal | 600 } // namespace internal |
551 } // namespace v8 | 601 } // namespace v8 |
OLD | NEW |