Commit 3ca64085 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Load elimination for Map.prototype.(has|get).

BUG=v8:6410

Change-Id: I140eb9c79a7bf22b71c175fe152473d8bb8e7a76
Reviewed-on: https://chromium-review.googlesource.com/563694Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46549}
parent 39bfd315
...@@ -116,6 +116,8 @@ Reduction LoadElimination::Reduce(Node* node) { ...@@ -116,6 +116,8 @@ Reduction LoadElimination::Reduce(Node* node) {
return ReduceStoreElement(node); return ReduceStoreElement(node);
case IrOpcode::kStoreTypedElement: case IrOpcode::kStoreTypedElement:
return ReduceStoreTypedElement(node); return ReduceStoreTypedElement(node);
case IrOpcode::kLookupHashStorageIndex:
return ReduceLookupHashStorageIndex(node);
case IrOpcode::kEffectPhi: case IrOpcode::kEffectPhi:
return ReduceEffectPhi(node); return ReduceEffectPhi(node);
case IrOpcode::kDead: case IrOpcode::kDead:
...@@ -305,6 +307,37 @@ void LoadElimination::AbstractElements::Print() const { ...@@ -305,6 +307,37 @@ void LoadElimination::AbstractElements::Print() const {
} }
} }
Node* LoadElimination::AbstractHashIndexes::Lookup(Node* table,
Node* key) const {
if (entry_.table == nullptr) return nullptr;
if (MustAlias(table, entry_.table) && MustAlias(key, entry_.key)) {
return entry_.index;
}
return nullptr;
}
bool LoadElimination::AbstractHashIndexes::Equals(
AbstractHashIndexes const* that) const {
return entry_.table == that->entry_.table && entry_.key == that->entry_.key &&
entry_.index == that->entry_.index;
}
LoadElimination::AbstractHashIndexes const*
LoadElimination::AbstractHashIndexes::Merge(AbstractHashIndexes const* that,
Zone* zone) const {
if (this->Equals(that)) return this;
return nullptr;
}
void LoadElimination::AbstractHashIndexes::Print() const {
if (entry_.table) {
PrintF(" #%d:%s @ #%d:%s -> #%d:%s\n", entry_.table->id(),
entry_.table->op()->mnemonic(), entry_.key->id(),
entry_.key->op()->mnemonic(), entry_.index->id(),
entry_.index->op()->mnemonic());
}
}
Node* LoadElimination::AbstractField::Lookup(Node* object) const { Node* LoadElimination::AbstractField::Lookup(Node* object) const {
for (auto pair : info_for_node_) { for (auto pair : info_for_node_) {
if (MustAlias(object, pair.first)) return pair.second; if (MustAlias(object, pair.first)) return pair.second;
...@@ -434,6 +467,13 @@ void LoadElimination::AbstractState::Merge(AbstractState const* that, ...@@ -434,6 +467,13 @@ void LoadElimination::AbstractState::Merge(AbstractState const* that,
if (this->maps_) { if (this->maps_) {
this->maps_ = that->maps_ ? that->maps_->Merge(this->maps_, zone) : nullptr; this->maps_ = that->maps_ ? that->maps_->Merge(this->maps_, zone) : nullptr;
} }
// Merge the information about hash maps.
if (this->hash_indexes_) {
this->hash_indexes_ = that->hash_indexes_ ? that->hash_indexes_->Merge(
this->hash_indexes_, zone)
: nullptr;
}
} }
Node* LoadElimination::AbstractState::LookupCheck(Node* node) const { Node* LoadElimination::AbstractState::LookupCheck(Node* node) const {
...@@ -504,6 +544,26 @@ LoadElimination::AbstractState::AddElement(Node* object, Node* index, ...@@ -504,6 +544,26 @@ LoadElimination::AbstractState::AddElement(Node* object, Node* index,
return that; return that;
} }
Node* LoadElimination::AbstractState::LookupHashIndex(Node* table,
Node* key) const {
if (this->hash_indexes_) {
return this->hash_indexes_->Lookup(table, key);
}
return nullptr;
}
LoadElimination::AbstractState const*
LoadElimination::AbstractState::AddHashIndex(Node* table, Node* key,
Node* index, Zone* zone) const {
AbstractState* that = new (zone) AbstractState(*this);
if (that->hash_indexes_) {
that->hash_indexes_ = that->hash_indexes_->Extend(table, key, index, zone);
} else {
that->hash_indexes_ = new (zone) AbstractHashIndexes(table, key, index);
}
return that;
}
LoadElimination::AbstractState const* LoadElimination::AbstractState const*
LoadElimination::AbstractState::KillElement(Node* object, Node* index, LoadElimination::AbstractState::KillElement(Node* object, Node* index,
Zone* zone) const { Zone* zone) const {
...@@ -905,6 +965,25 @@ Reduction LoadElimination::ReduceStoreTypedElement(Node* node) { ...@@ -905,6 +965,25 @@ Reduction LoadElimination::ReduceStoreTypedElement(Node* node) {
return UpdateState(node, state); return UpdateState(node, state);
} }
Reduction LoadElimination::ReduceLookupHashStorageIndex(Node* node) {
Node* table = node->InputAt(0);
Node* key = node->InputAt(1);
Node* effect = NodeProperties::GetEffectInput(node);
AbstractState const* state = node_states_.Get(effect);
if (state == nullptr) return NoChange();
if (Node* replacement = state->LookupHashIndex(table, key)) {
// Make sure we don't resurrect dead {replacement} nodes.
if (!replacement->IsDead()) {
ReplaceWithValue(node, replacement, effect);
return Replace(replacement);
}
}
state = state->AddHashIndex(table, key, node, zone());
return UpdateState(node, state);
}
Reduction LoadElimination::ReduceEffectPhi(Node* node) { Reduction LoadElimination::ReduceEffectPhi(Node* node) {
Node* const effect0 = NodeProperties::GetEffectInput(node, 0); Node* const effect0 = NodeProperties::GetEffectInput(node, 0);
Node* const control = NodeProperties::GetControlInput(node); Node* const control = NodeProperties::GetControlInput(node);
......
...@@ -123,6 +123,46 @@ class V8_EXPORT_PRIVATE LoadElimination final ...@@ -123,6 +123,46 @@ class V8_EXPORT_PRIVATE LoadElimination final
size_t next_index_ = 0; size_t next_index_ = 0;
}; };
// Abstract state to approximate the current state of a hash map along the
// effect paths through the graph.
class AbstractHashIndexes final : public ZoneObject {
public:
AbstractHashIndexes() {}
AbstractHashIndexes(Node* table, Node* key, Node* index)
: AbstractHashIndexes() {
entry_ = Entry(table, key, index);
}
AbstractHashIndexes const* Extend(Node* table, Node* key, Node* index,
Zone* zone) const {
// Currently, we do only hold one entry, so we just create a new
// state with the one entry.
AbstractHashIndexes* that =
new (zone) AbstractHashIndexes(table, key, index);
return that;
}
Node* Lookup(Node* table, Node* key) const;
bool Equals(AbstractHashIndexes const* that) const;
AbstractHashIndexes const* Merge(AbstractHashIndexes const* that,
Zone* zone) const;
void Print() const;
private:
struct Entry {
Entry() {}
Entry(Node* table, Node* key, Node* index)
: table(table), key(key), index(index) {}
Node* table = nullptr;
Node* key = nullptr;
Node* index = nullptr;
};
Entry entry_;
};
// Abstract state to approximate the current state of a certain field along // Abstract state to approximate the current state of a certain field along
// the effect paths through the graph. // the effect paths through the graph.
class AbstractField final : public ZoneObject { class AbstractField final : public ZoneObject {
...@@ -240,6 +280,9 @@ class V8_EXPORT_PRIVATE LoadElimination final ...@@ -240,6 +280,9 @@ class V8_EXPORT_PRIVATE LoadElimination final
Zone* zone) const; Zone* zone) const;
Node* LookupElement(Node* object, Node* index, Node* LookupElement(Node* object, Node* index,
MachineRepresentation representation) const; MachineRepresentation representation) const;
AbstractState const* AddHashIndex(Node* table, Node* key, Node* index,
Zone* zone) const;
Node* LookupHashIndex(Node* table, Node* key) const;
AbstractState const* AddCheck(Node* node, Zone* zone) const; AbstractState const* AddCheck(Node* node, Zone* zone) const;
Node* LookupCheck(Node* node) const; Node* LookupCheck(Node* node) const;
...@@ -251,6 +294,7 @@ class V8_EXPORT_PRIVATE LoadElimination final ...@@ -251,6 +294,7 @@ class V8_EXPORT_PRIVATE LoadElimination final
AbstractElements const* elements_ = nullptr; AbstractElements const* elements_ = nullptr;
AbstractField const* fields_[kMaxTrackedFields]; AbstractField const* fields_[kMaxTrackedFields];
AbstractMaps const* maps_ = nullptr; AbstractMaps const* maps_ = nullptr;
AbstractHashIndexes const* hash_indexes_ = nullptr;
}; };
class AbstractStateForEffectNodes final : public ZoneObject { class AbstractStateForEffectNodes final : public ZoneObject {
...@@ -275,6 +319,7 @@ class V8_EXPORT_PRIVATE LoadElimination final ...@@ -275,6 +319,7 @@ class V8_EXPORT_PRIVATE LoadElimination final
Reduction ReduceLoadElement(Node* node); Reduction ReduceLoadElement(Node* node);
Reduction ReduceStoreElement(Node* node); Reduction ReduceStoreElement(Node* node);
Reduction ReduceStoreTypedElement(Node* node); Reduction ReduceStoreTypedElement(Node* node);
Reduction ReduceLookupHashStorageIndex(Node* node);
Reduction ReduceEffectPhi(Node* node); Reduction ReduceEffectPhi(Node* node);
Reduction ReduceStart(Node* node); Reduction ReduceStart(Node* node);
Reduction ReduceOtherNode(Node* node); Reduction ReduceOtherNode(Node* node);
......
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