Revision: 24632
Author: [email protected]
Date: Wed Oct 15 12:29:39 2014 UTC
Log: Add JSGraph::GetCachedNodes and NodeCache::GetCachedNodes. These
routines are necessary in the dead code elimination phase to trim away uses
from unreachable nodes.
[email protected]
BUG=
Review URL: https://codereview.chromium.org/656103002
https://code.google.com/p/v8/source/detail?r=24632
Modified:
/branches/bleeding_edge/src/compiler/common-node-cache.h
/branches/bleeding_edge/src/compiler/js-graph.cc
/branches/bleeding_edge/src/compiler/js-graph.h
/branches/bleeding_edge/src/compiler/node-cache.cc
/branches/bleeding_edge/src/compiler/node-cache.h
/branches/bleeding_edge/test/cctest/compiler/test-js-constant-cache.cc
/branches/bleeding_edge/test/cctest/compiler/test-node-cache.cc
=======================================
--- /branches/bleeding_edge/src/compiler/common-node-cache.h Mon Oct 13
09:17:33 2014 UTC
+++ /branches/bleeding_edge/src/compiler/common-node-cache.h Wed Oct 15
12:29:39 2014 UTC
@@ -40,6 +40,14 @@
}
Zone* zone() const { return zone_; }
+
+ void GetCachedNodes(NodeVector* nodes) {
+ int32_constants_.GetCachedNodes(nodes);
+ int64_constants_.GetCachedNodes(nodes);
+ float64_constants_.GetCachedNodes(nodes);
+ external_constants_.GetCachedNodes(nodes);
+ number_constants_.GetCachedNodes(nodes);
+ }
private:
Int32NodeCache int32_constants_;
=======================================
--- /branches/bleeding_edge/src/compiler/js-graph.cc Wed Oct 15 11:38:04
2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-graph.cc Wed Oct 15 12:29:39
2014 UTC
@@ -190,6 +190,18 @@
}
return *loc;
}
+
+
+void JSGraph::GetCachedNodes(NodeVector* nodes) {
+ cache_.GetCachedNodes(nodes);
+ SetOncePointer<Node>* ptrs[] = {
+ &c_entry_stub_constant_, &undefined_constant_, &the_hole_constant_,
+ &true_constant_, &false_constant_, &null_constant_,
+ &zero_constant_, &one_constant_, &nan_constant_};
+ for (size_t i = 0; i < arraysize(ptrs); i++) {
+ if (ptrs[i]->is_set()) nodes->push_back(ptrs[i]->get());
+ }
+}
} // namespace compiler
} // namespace internal
=======================================
--- /branches/bleeding_edge/src/compiler/js-graph.h Wed Oct 15 11:38:04
2014 UTC
+++ /branches/bleeding_edge/src/compiler/js-graph.h Wed Oct 15 12:29:39
2014 UTC
@@ -102,6 +102,8 @@
Graph* graph() { return graph_; }
Zone* zone() { return graph()->zone(); }
Isolate* isolate() { return zone()->isolate(); }
+
+ void GetCachedNodes(NodeVector* nodes);
private:
Graph* graph_;
@@ -109,6 +111,7 @@
JSOperatorBuilder* javascript_;
MachineOperatorBuilder* machine_;
+ // TODO(titzer): make this into a simple array.
SetOncePointer<Node> c_entry_stub_constant_;
SetOncePointer<Node> undefined_constant_;
SetOncePointer<Node> the_hole_constant_;
=======================================
--- /branches/bleeding_edge/src/compiler/node-cache.cc Mon Oct 6 12:27:24
2014 UTC
+++ /branches/bleeding_edge/src/compiler/node-cache.cc Wed Oct 15 12:29:39
2014 UTC
@@ -7,6 +7,7 @@
#include <cstring>
#include "src/zone.h"
+#include "src/zone-containers.h"
namespace v8 {
namespace internal {
@@ -89,6 +90,15 @@
return &entry->value_;
}
+
+template <typename Key, typename Hash, typename Pred>
+void NodeCache<Key, Hash, Pred>::GetCachedNodes(NodeVector* nodes) {
+ if (entries_) {
+ for (size_t i = 0; i < size_; i++) {
+ if (entries_[i].value_ != NULL) nodes->push_back(entries_[i].value_);
+ }
+ }
+}
template class NodeCache<int64_t>;
template class NodeCache<int32_t>;
=======================================
--- /branches/bleeding_edge/src/compiler/node-cache.h Mon Oct 6 12:27:24
2014 UTC
+++ /branches/bleeding_edge/src/compiler/node-cache.h Wed Oct 15 12:29:39
2014 UTC
@@ -7,20 +7,12 @@
#include "src/base/functional.h"
#include "src/base/macros.h"
+#include "src/compiler/node.h"
namespace v8 {
namespace internal {
-
-// Forward declarations.
-class Zone;
-
-
namespace compiler {
-// Forward declarations.
-class Node;
-
-
// A cache for nodes based on a key. Useful for implementing
canonicalization of
// nodes such as constants, parameters, etc.
template <typename Key, typename Hash = base::hash<Key>,
@@ -39,6 +31,8 @@
// too full or encounters too many hash collisions.
Node** Find(Zone* zone, Key key);
+ void GetCachedNodes(NodeVector* nodes);
+
private:
enum { kInitialSize = 16u, kLinearProbe = 5u };
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-js-constant-cache.cc
Wed Oct 15 11:38:04 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-js-constant-cache.cc
Wed Oct 15 12:29:39 2014 UTC
@@ -4,6 +4,7 @@
#include "src/v8.h"
+#include "src/assembler.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node-properties-inl.h"
#include "src/compiler/typer.h"
@@ -30,6 +31,7 @@
};
+// TODO(dcarney): JSConstantCacheTester inherits from JSGraph???
class JSConstantCacheTester : public HandleAndZoneScope,
public JSCacheTesterHelper,
public JSGraph {
@@ -293,3 +295,177 @@
TEST(ExternalReferences) {
// TODO(titzer): test canonicalization of external references.
}
+
+
+static bool Contains(NodeVector* nodes, Node* n) {
+ for (size_t i = 0; i < nodes->size(); i++) {
+ if (nodes->at(i) == n) return true;
+ }
+ return false;
+}
+
+
+static void CheckGetCachedNodesContains(JSConstantCacheTester* T, Node* n)
{
+ NodeVector nodes(T->main_zone());
+ T->GetCachedNodes(&nodes);
+ CHECK(Contains(&nodes, n));
+}
+
+
+TEST(JSGraph_GetCachedNodes1) {
+ JSConstantCacheTester T;
+ CheckGetCachedNodesContains(&T, T.TrueConstant());
+ CheckGetCachedNodesContains(&T, T.UndefinedConstant());
+ CheckGetCachedNodesContains(&T, T.TheHoleConstant());
+ CheckGetCachedNodesContains(&T, T.TrueConstant());
+ CheckGetCachedNodesContains(&T, T.FalseConstant());
+ CheckGetCachedNodesContains(&T, T.NullConstant());
+ CheckGetCachedNodesContains(&T, T.ZeroConstant());
+ CheckGetCachedNodesContains(&T, T.OneConstant());
+ CheckGetCachedNodesContains(&T, T.NaNConstant());
+}
+
+
+TEST(JSGraph_GetCachedNodes_int32) {
+ JSConstantCacheTester T;
+
+ int32_t constants[] = {0, 11, 12, 13, 14, 55, -55, -44, -33, -22, -11,
+ 0, 11, 11, 12, 12, 11, 11, -33, -33, -22, -11};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int count_before = T.graph()->NodeCount();
+ NodeVector nodes_before(T.main_zone());
+ T.GetCachedNodes(&nodes_before);
+ Node* n = T.Int32Constant(constants[i]);
+ if (n->id() < count_before) {
+ // An old ID indicates a cached node. It should have been in the set.
+ CHECK(Contains(&nodes_before, n));
+ }
+ // Old or new, it should be in the cached set afterwards.
+ CheckGetCachedNodesContains(&T, n);
+ }
+}
+
+
+TEST(JSGraph_GetCachedNodes_float64) {
+ JSConstantCacheTester T;
+
+ double constants[] = {0, 11.1, 12.2, 13, 14, 55.5, -55.5, -44.4,
+ -33, -22, -11, 0, 11.1, 11.1, 12.3, 12.3,
+ 11, 11, -33.3, -33.3, -22, -11};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int count_before = T.graph()->NodeCount();
+ NodeVector nodes_before(T.main_zone());
+ T.GetCachedNodes(&nodes_before);
+ Node* n = T.Float64Constant(constants[i]);
+ if (n->id() < count_before) {
+ // An old ID indicates a cached node. It should have been in the set.
+ CHECK(Contains(&nodes_before, n));
+ }
+ // Old or new, it should be in the cached set afterwards.
+ CheckGetCachedNodesContains(&T, n);
+ }
+}
+
+
+TEST(JSGraph_GetCachedNodes_int64) {
+ JSConstantCacheTester T;
+
+ int32_t constants[] = {0, 11, 12, 13, 14, 55, -55, -44, -33, -22, -11,
+ 0, 11, 11, 12, 12, 11, 11, -33, -33, -22, -11};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int count_before = T.graph()->NodeCount();
+ NodeVector nodes_before(T.main_zone());
+ T.GetCachedNodes(&nodes_before);
+ Node* n = T.Int64Constant(constants[i]);
+ if (n->id() < count_before) {
+ // An old ID indicates a cached node. It should have been in the set.
+ CHECK(Contains(&nodes_before, n));
+ }
+ // Old or new, it should be in the cached set afterwards.
+ CheckGetCachedNodesContains(&T, n);
+ }
+}
+
+
+TEST(JSGraph_GetCachedNodes_number) {
+ JSConstantCacheTester T;
+
+ double constants[] = {0, 11.1, 12.2, 13, 14, 55.5, -55.5, -44.4,
+ -33, -22, -11, 0, 11.1, 11.1, 12.3, 12.3,
+ 11, 11, -33.3, -33.3, -22, -11};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int count_before = T.graph()->NodeCount();
+ NodeVector nodes_before(T.main_zone());
+ T.GetCachedNodes(&nodes_before);
+ Node* n = T.Constant(constants[i]);
+ if (n->id() < count_before) {
+ // An old ID indicates a cached node. It should have been in the set.
+ CHECK(Contains(&nodes_before, n));
+ }
+ // Old or new, it should be in the cached set afterwards.
+ CheckGetCachedNodesContains(&T, n);
+ }
+}
+
+
+TEST(JSGraph_GetCachedNodes_external) {
+ JSConstantCacheTester T;
+
+ ExternalReference constants[] = {ExternalReference::address_of_min_int(),
+ ExternalReference::address_of_min_int(),
+ ExternalReference::address_of_min_int(),
+
ExternalReference::address_of_one_half(),
+
ExternalReference::address_of_one_half(),
+ ExternalReference::address_of_min_int(),
+
ExternalReference::address_of_the_hole_nan(),
+
ExternalReference::address_of_one_half()};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int count_before = T.graph()->NodeCount();
+ NodeVector nodes_before(T.main_zone());
+ T.GetCachedNodes(&nodes_before);
+ Node* n = T.ExternalConstant(constants[i]);
+ if (n->id() < count_before) {
+ // An old ID indicates a cached node. It should have been in the set.
+ CHECK(Contains(&nodes_before, n));
+ }
+ // Old or new, it should be in the cached set afterwards.
+ CheckGetCachedNodesContains(&T, n);
+ }
+}
+
+
+TEST(JSGraph_GetCachedNodes_together) {
+ JSConstantCacheTester T;
+
+ Node* constants[] = {
+ T.TrueConstant(),
+ T.UndefinedConstant(),
+ T.TheHoleConstant(),
+ T.TrueConstant(),
+ T.FalseConstant(),
+ T.NullConstant(),
+ T.ZeroConstant(),
+ T.OneConstant(),
+ T.NaNConstant(),
+ T.Int32Constant(0),
+ T.Int32Constant(1),
+ T.Int64Constant(-2),
+ T.Int64Constant(-4),
+ T.Float64Constant(0.9),
+ T.Float64Constant(V8_INFINITY),
+ T.Constant(0.99),
+ T.Constant(1.11),
+ T.ExternalConstant(ExternalReference::address_of_one_half())};
+
+ NodeVector nodes(T.main_zone());
+ T.GetCachedNodes(&nodes);
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ CHECK(Contains(&nodes, constants[i]));
+ }
+}
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-node-cache.cc Tue Aug
26 09:19:24 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-node-cache.cc Wed Oct
15 12:29:39 2014 UTC
@@ -158,3 +158,63 @@
}
CHECK_LT(4, hits);
}
+
+
+static bool Contains(NodeVector* nodes, Node* n) {
+ for (size_t i = 0; i < nodes->size(); i++) {
+ if (nodes->at(i) == n) return true;
+ }
+ return false;
+}
+
+
+TEST(NodeCache_GetCachedNodes_int32) {
+ GraphTester graph;
+ Int32NodeCache cache;
+ CommonOperatorBuilder common(graph.zone());
+
+ int32_t constants[] = {0, 311, 12, 13, 14, 555, -555, -44, -33, -22,
-11,
+ 0, 311, 311, 412, 412, 11, 11, -33, -33, -22,
-11};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int32_t k = constants[i];
+ Node** pos = cache.Find(graph.zone(), k);
+ if (*pos != NULL) {
+ NodeVector nodes(graph.zone());
+ cache.GetCachedNodes(&nodes);
+ CHECK(Contains(&nodes, *pos));
+ } else {
+ NodeVector nodes(graph.zone());
+ Node* n = graph.NewNode(common.Int32Constant(k));
+ *pos = n;
+ cache.GetCachedNodes(&nodes);
+ CHECK(Contains(&nodes, n));
+ }
+ }
+}
+
+
+TEST(NodeCache_GetCachedNodes_int64) {
+ GraphTester graph;
+ Int64NodeCache cache;
+ CommonOperatorBuilder common(graph.zone());
+
+ int64_t constants[] = {0, 311, 12, 13, 14, 555, -555, -44, -33, -22,
-11,
+ 0, 311, 311, 412, 412, 11, 11, -33, -33, -22,
-11};
+
+ for (size_t i = 0; i < arraysize(constants); i++) {
+ int64_t k = constants[i];
+ Node** pos = cache.Find(graph.zone(), k);
+ if (*pos != NULL) {
+ NodeVector nodes(graph.zone());
+ cache.GetCachedNodes(&nodes);
+ CHECK(Contains(&nodes, *pos));
+ } else {
+ NodeVector nodes(graph.zone());
+ Node* n = graph.NewNode(common.Int64Constant(k));
+ *pos = n;
+ cache.GetCachedNodes(&nodes);
+ CHECK(Contains(&nodes, n));
+ }
+ }
+}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.