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

Side by Side Diff: src/compiler/load-elimination.cc

Issue 2866233002: [turbofan] Don't mix element accesses with incompatible representations. (Closed)
Patch Set: Created 3 years, 7 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/load-elimination.h ('k') | test/mjsunit/regress/regress-crbug-719479.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/common-operator.h" 7 #include "src/compiler/common-operator.h"
8 #include "src/compiler/js-graph.h" 8 #include "src/compiler/js-graph.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 #include "src/compiler/simplified-operator.h" 10 #include "src/compiler/simplified-operator.h"
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 } 188 }
189 189
190 void LoadElimination::AbstractChecks::Print() const { 190 void LoadElimination::AbstractChecks::Print() const {
191 for (Node* const node : nodes_) { 191 for (Node* const node : nodes_) {
192 if (node != nullptr) { 192 if (node != nullptr) {
193 PrintF(" #%d:%s\n", node->id(), node->op()->mnemonic()); 193 PrintF(" #%d:%s\n", node->id(), node->op()->mnemonic());
194 } 194 }
195 } 195 }
196 } 196 }
197 197
198 Node* LoadElimination::AbstractElements::Lookup(Node* object, 198 namespace {
199 Node* index) const { 199
200 bool IsCompatible(MachineRepresentation r1, MachineRepresentation r2) {
201 if (r1 == r2) return true;
202 return IsAnyTagged(r1) && IsAnyTagged(r2);
203 }
204
205 } // namespace
206
207 Node* LoadElimination::AbstractElements::Lookup(
208 Node* object, Node* index, MachineRepresentation representation) const {
200 for (Element const element : elements_) { 209 for (Element const element : elements_) {
201 if (element.object == nullptr) continue; 210 if (element.object == nullptr) continue;
202 DCHECK_NOT_NULL(element.index); 211 DCHECK_NOT_NULL(element.index);
203 DCHECK_NOT_NULL(element.value); 212 DCHECK_NOT_NULL(element.value);
204 if (MustAlias(object, element.object) && MustAlias(index, element.index)) { 213 if (MustAlias(object, element.object) && MustAlias(index, element.index) &&
214 IsCompatible(representation, element.representation)) {
205 return element.value; 215 return element.value;
206 } 216 }
207 } 217 }
208 return nullptr; 218 return nullptr;
209 } 219 }
210 220
211 LoadElimination::AbstractElements const* 221 LoadElimination::AbstractElements const*
212 LoadElimination::AbstractElements::Kill(Node* object, Node* index, 222 LoadElimination::AbstractElements::Kill(Node* object, Node* index,
213 Zone* zone) const { 223 Zone* zone) const {
214 for (Element const element : this->elements_) { 224 for (Element const element : this->elements_) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 AbstractMaps const* that_maps = this->maps_->Kill(object, zone); 473 AbstractMaps const* that_maps = this->maps_->Kill(object, zone);
464 if (this->maps_ != that_maps) { 474 if (this->maps_ != that_maps) {
465 AbstractState* that = new (zone) AbstractState(*this); 475 AbstractState* that = new (zone) AbstractState(*this);
466 that->maps_ = that_maps; 476 that->maps_ = that_maps;
467 return that; 477 return that;
468 } 478 }
469 } 479 }
470 return this; 480 return this;
471 } 481 }
472 482
473 Node* LoadElimination::AbstractState::LookupElement(Node* object, 483 Node* LoadElimination::AbstractState::LookupElement(
474 Node* index) const { 484 Node* object, Node* index, MachineRepresentation representation) const {
475 if (this->elements_) { 485 if (this->elements_) {
476 return this->elements_->Lookup(object, index); 486 return this->elements_->Lookup(object, index, representation);
477 } 487 }
478 return nullptr; 488 return nullptr;
479 } 489 }
480 490
481 LoadElimination::AbstractState const* 491 LoadElimination::AbstractState const*
482 LoadElimination::AbstractState::AddElement(Node* object, Node* index, 492 LoadElimination::AbstractState::AddElement(Node* object, Node* index,
483 Node* value, Zone* zone) const { 493 Node* value,
494 MachineRepresentation representation,
495 Zone* zone) const {
484 AbstractState* that = new (zone) AbstractState(*this); 496 AbstractState* that = new (zone) AbstractState(*this);
485 if (that->elements_) { 497 if (that->elements_) {
486 that->elements_ = that->elements_->Extend(object, index, value, zone); 498 that->elements_ =
499 that->elements_->Extend(object, index, value, representation, zone);
487 } else { 500 } else {
488 that->elements_ = new (zone) AbstractElements(object, index, value, zone); 501 that->elements_ =
502 new (zone) AbstractElements(object, index, value, representation, zone);
489 } 503 }
490 return that; 504 return that;
491 } 505 }
492 506
493 LoadElimination::AbstractState const* 507 LoadElimination::AbstractState const*
494 LoadElimination::AbstractState::KillElement(Node* object, Node* index, 508 LoadElimination::AbstractState::KillElement(Node* object, Node* index,
495 Zone* zone) const { 509 Zone* zone) const {
496 if (this->elements_) { 510 if (this->elements_) {
497 AbstractElements const* that_elements = 511 AbstractElements const* that_elements =
498 this->elements_->Kill(object, index, zone); 512 this->elements_->Kill(object, index, zone);
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 case MachineRepresentation::kWord32: 830 case MachineRepresentation::kWord32:
817 case MachineRepresentation::kWord64: 831 case MachineRepresentation::kWord64:
818 case MachineRepresentation::kFloat32: 832 case MachineRepresentation::kFloat32:
819 // TODO(turbofan): Add support for doing the truncations. 833 // TODO(turbofan): Add support for doing the truncations.
820 break; 834 break;
821 case MachineRepresentation::kFloat64: 835 case MachineRepresentation::kFloat64:
822 case MachineRepresentation::kSimd128: 836 case MachineRepresentation::kSimd128:
823 case MachineRepresentation::kTaggedSigned: 837 case MachineRepresentation::kTaggedSigned:
824 case MachineRepresentation::kTaggedPointer: 838 case MachineRepresentation::kTaggedPointer:
825 case MachineRepresentation::kTagged: 839 case MachineRepresentation::kTagged:
826 if (Node* replacement = state->LookupElement(object, index)) { 840 if (Node* replacement = state->LookupElement(
841 object, index, access.machine_type.representation())) {
827 // Make sure we don't resurrect dead {replacement} nodes. 842 // Make sure we don't resurrect dead {replacement} nodes.
828 if (!replacement->IsDead()) { 843 if (!replacement->IsDead()) {
829 // We might need to guard the {replacement} if the type of the 844 // We might need to guard the {replacement} if the type of the
830 // {node} is more precise than the type of the {replacement}. 845 // {node} is more precise than the type of the {replacement}.
831 Type* const node_type = NodeProperties::GetType(node); 846 Type* const node_type = NodeProperties::GetType(node);
832 if (!NodeProperties::GetType(replacement)->Is(node_type)) { 847 if (!NodeProperties::GetType(replacement)->Is(node_type)) {
833 replacement = graph()->NewNode(common()->TypeGuard(node_type), 848 replacement = graph()->NewNode(common()->TypeGuard(node_type),
834 replacement, control); 849 replacement, control);
835 NodeProperties::SetType(replacement, node_type); 850 NodeProperties::SetType(replacement, node_type);
836 } 851 }
837 ReplaceWithValue(node, replacement, effect); 852 ReplaceWithValue(node, replacement, effect);
838 return Replace(replacement); 853 return Replace(replacement);
839 } 854 }
840 } 855 }
841 state = state->AddElement(object, index, node, zone()); 856 state = state->AddElement(object, index, node,
857 access.machine_type.representation(), zone());
842 return UpdateState(node, state); 858 return UpdateState(node, state);
843 } 859 }
844 return NoChange(); 860 return NoChange();
845 } 861 }
846 862
847 Reduction LoadElimination::ReduceStoreElement(Node* node) { 863 Reduction LoadElimination::ReduceStoreElement(Node* node) {
848 ElementAccess const& access = ElementAccessOf(node->op()); 864 ElementAccess const& access = ElementAccessOf(node->op());
849 Node* const object = NodeProperties::GetValueInput(node, 0); 865 Node* const object = NodeProperties::GetValueInput(node, 0);
850 Node* const index = NodeProperties::GetValueInput(node, 1); 866 Node* const index = NodeProperties::GetValueInput(node, 1);
851 Node* const new_value = NodeProperties::GetValueInput(node, 2); 867 Node* const new_value = NodeProperties::GetValueInput(node, 2);
852 Node* const effect = NodeProperties::GetEffectInput(node); 868 Node* const effect = NodeProperties::GetEffectInput(node);
853 AbstractState const* state = node_states_.Get(effect); 869 AbstractState const* state = node_states_.Get(effect);
854 if (state == nullptr) return NoChange(); 870 if (state == nullptr) return NoChange();
855 Node* const old_value = state->LookupElement(object, index); 871 Node* const old_value =
872 state->LookupElement(object, index, access.machine_type.representation());
856 if (old_value == new_value) { 873 if (old_value == new_value) {
857 // This store is fully redundant. 874 // This store is fully redundant.
858 return Replace(effect); 875 return Replace(effect);
859 } 876 }
860 // Kill all potentially aliasing elements. 877 // Kill all potentially aliasing elements.
861 state = state->KillElement(object, index, zone()); 878 state = state->KillElement(object, index, zone());
862 // Only record the new value if the store doesn't have an implicit truncation. 879 // Only record the new value if the store doesn't have an implicit truncation.
863 switch (access.machine_type.representation()) { 880 switch (access.machine_type.representation()) {
864 case MachineRepresentation::kNone: 881 case MachineRepresentation::kNone:
865 case MachineRepresentation::kSimd1x4: 882 case MachineRepresentation::kSimd1x4:
866 case MachineRepresentation::kSimd1x8: 883 case MachineRepresentation::kSimd1x8:
867 case MachineRepresentation::kSimd1x16: 884 case MachineRepresentation::kSimd1x16:
868 case MachineRepresentation::kBit: 885 case MachineRepresentation::kBit:
869 UNREACHABLE(); 886 UNREACHABLE();
870 break; 887 break;
871 case MachineRepresentation::kWord8: 888 case MachineRepresentation::kWord8:
872 case MachineRepresentation::kWord16: 889 case MachineRepresentation::kWord16:
873 case MachineRepresentation::kWord32: 890 case MachineRepresentation::kWord32:
874 case MachineRepresentation::kWord64: 891 case MachineRepresentation::kWord64:
875 case MachineRepresentation::kFloat32: 892 case MachineRepresentation::kFloat32:
876 // TODO(turbofan): Add support for doing the truncations. 893 // TODO(turbofan): Add support for doing the truncations.
877 break; 894 break;
878 case MachineRepresentation::kFloat64: 895 case MachineRepresentation::kFloat64:
879 case MachineRepresentation::kSimd128: 896 case MachineRepresentation::kSimd128:
880 case MachineRepresentation::kTaggedSigned: 897 case MachineRepresentation::kTaggedSigned:
881 case MachineRepresentation::kTaggedPointer: 898 case MachineRepresentation::kTaggedPointer:
882 case MachineRepresentation::kTagged: 899 case MachineRepresentation::kTagged:
883 state = state->AddElement(object, index, new_value, zone()); 900 state = state->AddElement(object, index, new_value,
901 access.machine_type.representation(), zone());
884 break; 902 break;
885 } 903 }
886 return UpdateState(node, state); 904 return UpdateState(node, state);
887 } 905 }
888 906
889 Reduction LoadElimination::ReduceStoreTypedElement(Node* node) { 907 Reduction LoadElimination::ReduceStoreTypedElement(Node* node) {
890 Node* const effect = NodeProperties::GetEffectInput(node); 908 Node* const effect = NodeProperties::GetEffectInput(node);
891 AbstractState const* state = node_states_.Get(effect); 909 AbstractState const* state = node_states_.Get(effect);
892 if (state == nullptr) return NoChange(); 910 if (state == nullptr) return NoChange();
893 return UpdateState(node, state); 911 return UpdateState(node, state);
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 return jsgraph()->common(); 1129 return jsgraph()->common();
1112 } 1130 }
1113 1131
1114 Graph* LoadElimination::graph() const { return jsgraph()->graph(); } 1132 Graph* LoadElimination::graph() const { return jsgraph()->graph(); }
1115 1133
1116 Factory* LoadElimination::factory() const { return jsgraph()->factory(); } 1134 Factory* LoadElimination::factory() const { return jsgraph()->factory(); }
1117 1135
1118 } // namespace compiler 1136 } // namespace compiler
1119 } // namespace internal 1137 } // namespace internal
1120 } // namespace v8 1138 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/load-elimination.h ('k') | test/mjsunit/regress/regress-crbug-719479.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698