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) {
return ReduceStoreElement(node);
case IrOpcode::kStoreTypedElement:
return ReduceStoreTypedElement(node);
case IrOpcode::kLookupHashStorageIndex:
return ReduceLookupHashStorageIndex(node);
case IrOpcode::kEffectPhi:
return ReduceEffectPhi(node);
case IrOpcode::kDead:
......@@ -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 {
for (auto pair : info_for_node_) {
if (MustAlias(object, pair.first)) return pair.second;
......@@ -434,6 +467,13 @@ void LoadElimination::AbstractState::Merge(AbstractState const* that,
if (this->maps_) {
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 {
......@@ -504,6 +544,26 @@ LoadElimination::AbstractState::AddElement(Node* object, Node* index,
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::KillElement(Node* object, Node* index,
Zone* zone) const {
......@@ -905,6 +965,25 @@ Reduction LoadElimination::ReduceStoreTypedElement(Node* node) {
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) {
Node* const effect0 = NodeProperties::GetEffectInput(node, 0);
Node* const control = NodeProperties::GetControlInput(node);
......
......@@ -123,6 +123,46 @@ class V8_EXPORT_PRIVATE LoadElimination final
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
// the effect paths through the graph.
class AbstractField final : public ZoneObject {
......@@ -240,6 +280,9 @@ class V8_EXPORT_PRIVATE LoadElimination final
Zone* zone) const;
Node* LookupElement(Node* object, Node* index,
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;
Node* LookupCheck(Node* node) const;
......@@ -251,6 +294,7 @@ class V8_EXPORT_PRIVATE LoadElimination final
AbstractElements const* elements_ = nullptr;
AbstractField const* fields_[kMaxTrackedFields];
AbstractMaps const* maps_ = nullptr;
AbstractHashIndexes const* hash_indexes_ = nullptr;
};
class AbstractStateForEffectNodes final : public ZoneObject {
......@@ -275,6 +319,7 @@ class V8_EXPORT_PRIVATE LoadElimination final
Reduction ReduceLoadElement(Node* node);
Reduction ReduceStoreElement(Node* node);
Reduction ReduceStoreTypedElement(Node* node);
Reduction ReduceLookupHashStorageIndex(Node* node);
Reduction ReduceEffectPhi(Node* node);
Reduction ReduceStart(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