| 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 |