[turbofan] Handle collisions properly in value numbering.

R=svenpanne@chromium.org

Review URL: https://codereview.chromium.org/795433003

Cr-Commit-Position: refs/heads/master@{#25857}
This commit is contained in:
Benedikt Meurer 2014-12-17 09:05:17 +01:00
parent f9be562d61
commit 788411c334

View File

@ -88,8 +88,33 @@ Reduction ValueNumberingReducer::Reduce(Node* node) {
DCHECK(size_ * kCapacityToSizeRatio < capacity_);
return NoChange();
}
if (entry == node) {
return NoChange();
// We need to check for a certain class of collisions here. Imagine the
// following scenario:
//
// 1. We insert node1 with op1 and certain inputs at index i.
// 2. We insert node2 with op2 and certain inputs at index i+1.
// 3. Some other reducer changes node1 to op2 and the inputs from node2.
//
// Now we are called again to reduce node1, and we would return NoChange
// in this case because we find node1 first, but what we should actually
// do is return Replace(node2) instead.
for (size_t j = (i + 1) & mask;; j = (j + 1) & mask) {
Node* entry = entries_[j];
if (!entry) {
// No collision, {node} is fine.
return NoChange();
}
if (entry->IsDead()) {
continue;
}
if (Equals(entry, node)) {
// Overwrite the colliding entry with the actual entry.
entries_[i] = entry;
return Replace(entry);
}
}
}
// Skip dead entries, but remember their indices so we can reuse them.