5 #include "src/compiler/value-numbering-reducer.h" 9 #include "src/base/functional.h" 10 #include "src/compiler/node-properties.h" 11 #include "src/compiler/node.h" 17 ValueNumberingReducer::ValueNumberingReducer(Zone* temp_zone, Zone* graph_zone)
21 temp_zone_(temp_zone),
22 graph_zone_(graph_zone) {}
24 ValueNumberingReducer::~ValueNumberingReducer() =
default;
27 Reduction ValueNumberingReducer::Reduce(Node* node) {
28 if (!node->op()->HasProperty(Operator::kIdempotent))
return NoChange();
30 const size_t hash = NodeProperties::HashCode(node);
33 DCHECK_EQ(0, capacity_);
35 capacity_ = kInitialCapacity;
36 entries_ = temp_zone()->NewArray<Node*>(kInitialCapacity);
37 memset(entries_, 0,
sizeof(*entries_) * kInitialCapacity);
38 entries_[hash & (kInitialCapacity - 1)] = node;
43 DCHECK(size_ < capacity_);
44 DCHECK(size_ + size_ / 4 < capacity_);
46 const size_t mask = capacity_ - 1;
47 size_t dead = capacity_;
49 for (
size_t i = hash & mask;;
i = (
i + 1) & mask) {
50 Node* entry = entries_[
i];
52 if (dead != capacity_) {
54 entries_[dead] = node;
61 if (size_ + size_ / 4 >= capacity_) Grow();
63 DCHECK(size_ + size_ / 4 < capacity_);
78 for (
size_t j = (
i + 1) & mask;; j = (j + 1) & mask) {
79 Node* entry = entries_[j];
84 if (entry->IsDead()) {
91 if (!entries_[(j + 1) & mask]) {
92 entries_[j] =
nullptr;
99 if (NodeProperties::Equals(entry, node)) {
100 Reduction reduction = ReplaceIfTypesMatch(node, entry);
101 if (reduction.Changed()) {
106 if (!entries_[(j + 1) & mask]) {
107 entries_[j] =
nullptr;
117 if (entry->IsDead()) {
121 if (NodeProperties::Equals(entry, node)) {
122 return ReplaceIfTypesMatch(node, entry);
127 Reduction ValueNumberingReducer::ReplaceIfTypesMatch(Node* node,
130 if (NodeProperties::IsTyped(replacement) && NodeProperties::IsTyped(node)) {
131 Type replacement_type = NodeProperties::GetType(replacement);
132 Type node_type = NodeProperties::GetType(node);
133 if (!replacement_type.Is(node_type)) {
139 if (node_type.Is(replacement_type)) {
140 NodeProperties::SetType(replacement, node_type);
147 return Replace(replacement);
151 void ValueNumberingReducer::Grow() {
153 Node**
const old_entries = entries_;
154 size_t const old_capacity = capacity_;
156 entries_ = temp_zone()->NewArray<Node*>(capacity_);
157 memset(entries_, 0,
sizeof(*entries_) * capacity_);
159 size_t const mask = capacity_ - 1;
162 for (
size_t i = 0;
i < old_capacity; ++
i) {
163 Node*
const old_entry = old_entries[
i];
164 if (!old_entry || old_entry->IsDead())
continue;
165 for (
size_t j = NodeProperties::HashCode(old_entry) & mask;;
166 j = (j + 1) & mask) {
167 Node*
const entry = entries_[j];
168 if (entry == old_entry) {
173 entries_[j] = old_entry;