Commit 1c1a884d authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Merge PropertyAccessInfo for compatible field loads.

For polymorphic loads that refer to the same underlying field, but
differ in either representation or field maps, try harder to merge
them into a simple field load by going to Tagged representation or
throwing away the field maps (this is essentially what Crankshaft
is doing).

R=jarin@chromium.org
BUG=v8:5267

Review-Url: https://codereview.chromium.org/2836893002
Cr-Commit-Position: refs/heads/master@{#44831}
parent d081a6f6
......@@ -133,7 +133,8 @@ PropertyAccessInfo::PropertyAccessInfo(
field_type_(field_type),
field_map_(field_map) {}
bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) {
bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that,
AccessMode access_mode, Zone* zone) {
if (this->kind_ != that->kind_) return false;
if (this->holder_.address() != that->holder_.address()) return false;
......@@ -145,12 +146,40 @@ bool PropertyAccessInfo::Merge(PropertyAccessInfo const* that) {
case kDataConstantField: {
// Check if we actually access the same field.
if (this->kind_ == that->kind_ &&
this->transition_map_.address() == that->transition_map_.address() &&
this->field_index_ == that->field_index_ &&
this->field_map_.address() == that->field_map_.address() &&
this->field_type_->Is(that->field_type_) &&
that->field_type_->Is(this->field_type_) &&
this->field_representation_ == that->field_representation_) {
this->field_index_ == that->field_index_) {
switch (access_mode) {
case AccessMode::kLoad: {
if (this->field_representation_ != that->field_representation_) {
if (!IsAnyTagged(this->field_representation_) ||
!IsAnyTagged(that->field_representation_)) {
return false;
}
this->field_representation_ = MachineRepresentation::kTagged;
}
if (this->field_map_.address() != that->field_map_.address()) {
this->field_map_ = MaybeHandle<Map>();
}
break;
}
case AccessMode::kStore:
case AccessMode::kStoreInLiteral: {
// For stores, the field map and field representation information
// must match exactly, otherwise we cannot merge the stores. We
// also need to make sure that in case of transitioning stores,
// the transition targets match.
if (this->field_map_.address() != that->field_map_.address() ||
this->field_representation_ != that->field_representation_ ||
this->transition_map_.address() !=
that->transition_map_.address()) {
return false;
}
break;
}
}
// Merge the field type.
this->field_type_ =
Type::Union(this->field_type_, that->field_type_, zone);
// Merge the receiver maps.
this->receiver_maps_.insert(this->receiver_maps_.end(),
that->receiver_maps_.begin(),
that->receiver_maps_.end());
......@@ -468,7 +497,7 @@ bool AccessInfoFactory::ComputePropertyAccessInfos(
// Try to merge the {access_info} with an existing one.
bool merged = false;
for (PropertyAccessInfo& other_info : *access_infos) {
if (other_info.Merge(&access_info)) {
if (other_info.Merge(&access_info, access_mode, zone())) {
merged = true;
break;
}
......
......@@ -83,7 +83,8 @@ class PropertyAccessInfo final {
PropertyAccessInfo();
bool Merge(PropertyAccessInfo const* that) WARN_UNUSED_RESULT;
bool Merge(PropertyAccessInfo const* that, AccessMode access_mode,
Zone* zone) WARN_UNUSED_RESULT;
bool IsNotFound() const { return kind() == kNotFound; }
bool IsDataConstant() const { return kind() == kDataConstant; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment