Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Unified Diff: src/compiler/value-numbering-reducer.cc

Issue 630423002: [turbofan] Reenable value numbering. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Win fix. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/value-numbering-reducer.h ('k') | test/unittests/compiler/value-numbering-reducer-unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/value-numbering-reducer.cc
diff --git a/src/compiler/value-numbering-reducer.cc b/src/compiler/value-numbering-reducer.cc
index 595a4f30171904aa33fd3b6b3d19cf88816a335e..f4cf1d486266c2331fe95e39deb4dbc9130b4c74 100644
--- a/src/compiler/value-numbering-reducer.cc
+++ b/src/compiler/value-numbering-reducer.cc
@@ -4,6 +4,9 @@
#include "src/compiler/value-numbering-reducer.h"
+#include <cstring>
+
+#include "src/base/functional.h"
#include "src/compiler/node.h"
namespace v8 {
@@ -12,7 +15,13 @@ namespace compiler {
namespace {
-size_t HashCode(Node* node) { return node->op()->HashCode(); }
+size_t HashCode(Node* node) {
+ size_t h = base::hash_combine(node->op()->HashCode(), node->InputCount());
+ for (int j = 0; j < node->InputCount(); ++j) {
+ h = base::hash_combine(h, node->InputAt(j)->id());
+ }
+ return h;
+}
bool Equals(Node* a, Node* b) {
@@ -33,40 +42,96 @@ bool Equals(Node* a, Node* b) {
} // namespace
-class ValueNumberingReducer::Entry FINAL : public ZoneObject {
- public:
- Entry(Node* node, Entry* next) : node_(node), next_(next) {}
+ValueNumberingReducer::ValueNumberingReducer(Zone* zone)
+ : entries_(nullptr), capacity_(0), size_(0), zone_(zone) {}
- Node* node() const { return node_; }
- Entry* next() const { return next_; }
- private:
- Node* node_;
- Entry* next_;
-};
+ValueNumberingReducer::~ValueNumberingReducer() {}
-ValueNumberingReducer::ValueNumberingReducer(Zone* zone) : zone_(zone) {
- for (size_t i = 0; i < arraysize(buckets_); ++i) {
- buckets_[i] = NULL;
+Reduction ValueNumberingReducer::Reduce(Node* node) {
+ if (!node->op()->HasProperty(Operator::kEliminatable)) return NoChange();
+
+ const size_t hash = HashCode(node);
+ if (!entries_) {
+ DCHECK(size_ == 0);
+ DCHECK(capacity_ == 0);
+ // Allocate the initial entries and insert the first entry.
+ capacity_ = kInitialCapacity;
+ entries_ = zone()->NewArray<Node*>(kInitialCapacity);
+ memset(entries_, 0, sizeof(*entries_) * kInitialCapacity);
+ entries_[hash & (kInitialCapacity - 1)] = node;
+ size_ = 1;
+ return NoChange();
}
-}
+ DCHECK(size_ < capacity_);
+ DCHECK(size_ * kCapacityToSizeRatio < capacity_);
+
+ const size_t mask = capacity_ - 1;
+ size_t dead = capacity_;
+
+ for (size_t i = hash & mask;; i = (i + 1) & mask) {
+ Node* entry = entries_[i];
+ if (!entry) {
+ if (dead != capacity_) {
+ // Reuse dead entry that we discovered on the way.
+ entries_[dead] = node;
+ } else {
+ // Have to insert a new entry.
+ entries_[i] = node;
+ size_++;
+
+ // Resize to keep load factor below 1/kCapacityToSizeRatio.
+ if (size_ * kCapacityToSizeRatio >= capacity_) Grow();
+ }
+ DCHECK(size_ * kCapacityToSizeRatio < capacity_);
+ return NoChange();
+ }
+ if (entry == node) {
+ return NoChange();
+ }
-ValueNumberingReducer::~ValueNumberingReducer() {}
+ // Skip dead entries, but remember their indices so we can reuse them.
+ if (entry->IsDead()) {
+ dead = i;
+ continue;
+ }
+ if (Equals(entry, node)) {
+ return Replace(entry);
+ }
+ }
+}
-Reduction ValueNumberingReducer::Reduce(Node* node) {
- Entry** head = &buckets_[HashCode(node) % arraysize(buckets_)];
- for (Entry* entry = *head; entry; entry = entry->next()) {
- if (entry->node()->IsDead()) continue;
- if (entry->node() == node) return NoChange();
- if (Equals(node, entry->node())) {
- return Replace(entry->node());
+void ValueNumberingReducer::Grow() {
+ // Allocate a new block of entries kCapacityToSizeRatio times the previous
+ // capacity.
+ Node** const old_entries = entries_;
+ size_t const old_capacity = capacity_;
+ capacity_ *= kCapacityToSizeRatio;
+ entries_ = zone()->NewArray<Node*>(static_cast<int>(capacity_));
+ memset(entries_, 0, sizeof(*entries_) * capacity_);
+ size_ = 0;
+ size_t const mask = capacity_ - 1;
+
+ // Insert the old entries into the new block (skipping dead nodes).
+ for (size_t i = 0; i < old_capacity; ++i) {
+ Node* const old_entry = old_entries[i];
+ if (!old_entry || old_entry->IsDead()) continue;
+ for (size_t j = HashCode(old_entry) & mask;; j = (j + 1) & mask) {
+ Node* const entry = entries_[j];
+ if (entry == old_entry) {
+ // Skip duplicate of the old entry.
+ break;
+ }
+ if (!entry) {
+ entries_[j] = old_entry;
+ size_++;
+ break;
+ }
}
}
- *head = new (zone()) Entry(node, *head);
- return NoChange();
}
} // namespace compiler
« no previous file with comments | « src/compiler/value-numbering-reducer.h ('k') | test/unittests/compiler/value-numbering-reducer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698