Revision: 23140
Author:   [email protected]
Date:     Mon Aug 18 06:54:07 2014 UTC
Log:      Refactor ChangeLowering class to avoid template specialization.

Also refactor the unit tests and add support to easily
match DAGs using CaptureEq() matcher.

TEST=compiler-unittests
BUG=v8:3489
LOG=n
[email protected]

Review URL: https://codereview.chromium.org/480863002
http://code.google.com/p/v8/source/detail?r=23140

Added:
 /branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.h
 /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h
 /branches/bleeding_edge/testing/gmock-support.h
Deleted:
 /branches/bleeding_edge/test/compiler-unittests/node-matchers.cc
 /branches/bleeding_edge/test/compiler-unittests/node-matchers.h
Modified:
 /branches/bleeding_edge/src/compiler/change-lowering.cc
 /branches/bleeding_edge/src/compiler/change-lowering.h
 /branches/bleeding_edge/src/compiler/js-graph.cc
 /branches/bleeding_edge/src/compiler/js-graph.h
 /branches/bleeding_edge/test/compiler-unittests/DEPS
 /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.cc
 /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.gyp
 /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h
/branches/bleeding_edge/test/compiler-unittests/machine-operator-reducer-unittest.cc
 /branches/bleeding_edge/testing/gmock.gyp

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.cc Mon Aug 18 06:54:07 2014 UTC
@@ -0,0 +1,20 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/compiler-unittests/common-operator-unittest.h"
+
+#include "src/compiler/operator-properties-inl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+CommonOperatorTest::CommonOperatorTest() : common_(zone()) {}
+
+
+CommonOperatorTest::~CommonOperatorTest() {}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.h Mon Aug 18 06:54:07 2014 UTC
@@ -0,0 +1,31 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_UNITTESTS_COMMON_OPERATOR_UNITTEST_H_
+#define V8_COMPILER_UNITTESTS_COMMON_OPERATOR_UNITTEST_H_
+
+#include "src/compiler/common-operator.h"
+#include "test/compiler-unittests/compiler-unittests.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class CommonOperatorTest : public CompilerTest {
+ public:
+  CommonOperatorTest();
+  virtual ~CommonOperatorTest();
+
+ protected:
+  CommonOperatorBuilder* common() { return &common_; }
+
+ private:
+  CommonOperatorBuilder common_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_UNITTESTS_COMMON_OPERATOR_UNITTEST_H_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc Mon Aug 18 06:54:07 2014 UTC
@@ -0,0 +1,559 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/compiler-unittests/graph-unittest.h"
+
+#include <ostream>  // NOLINT(readability/streams)
+
+#include "src/compiler/node-properties-inl.h"
+
+using testing::MakeMatcher;
+using testing::MatcherInterface;
+using testing::MatchResultListener;
+using testing::StringMatchResultListener;
+
+namespace v8 {
+namespace internal {
+
+// TODO(bmeurer): Find a new home for these functions.
+template <typename T>
+inline std::ostream& operator<<(std::ostream& os,
+                                const PrintableUnique<T>& value) {
+  return os << value.string();
+}
+
+namespace compiler {
+
+GraphTest::GraphTest(int num_parameters) : graph_(zone()) {
+  graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
+}
+
+
+GraphTest::~GraphTest() {}
+
+
+namespace {
+
+template <typename T>
+bool PrintMatchAndExplain(const T& value, const char* value_name,
+                          const Matcher<T>& value_matcher,
+                          MatchResultListener* listener) {
+  StringMatchResultListener value_listener;
+  if (!value_matcher.MatchAndExplain(value, &value_listener)) {
+ *listener << "whose " << value_name << " " << value << " doesn't match";
+    if (value_listener.str() != "") {
+      *listener << ", " << value_listener.str();
+    }
+    return false;
+  }
+  return true;
+}
+
+
+class NodeMatcher : public MatcherInterface<Node*> {
+ public:
+  explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    if (node == NULL) {
+      *listener << "which is NULL";
+      return false;
+    }
+    if (node->opcode() != opcode_) {
+ *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode());
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  const IrOpcode::Value opcode_;
+};
+
+
+class IsBranchMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsBranchMatcher(const Matcher<Node*>& value_matcher,
+                  const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kBranch),
+        value_matcher_(value_matcher),
+        control_matcher_(control_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value (";
+    value_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsMergeMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsMergeMatcher(const Matcher<Node*>& control0_matcher,
+                 const Matcher<Node*>& control1_matcher)
+      : NodeMatcher(IrOpcode::kMerge),
+        control0_matcher_(control0_matcher),
+        control1_matcher_(control1_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose control0 (";
+    control0_matcher_.DescribeTo(os);
+    *os << ") and control1 (";
+    control1_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
+ "control0", control0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
+                                 "control1", control1_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> control0_matcher_;
+  const Matcher<Node*> control1_matcher_;
+};
+
+
+class IsIfTrueMatcher V8_FINAL : public NodeMatcher {
+ public:
+  explicit IsIfTrueMatcher(const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kIfTrue), control_matcher_(control_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsIfFalseMatcher V8_FINAL : public NodeMatcher {
+ public:
+  explicit IsIfFalseMatcher(const Matcher<Node*>& control_matcher)
+ : NodeMatcher(IrOpcode::kIfFalse), control_matcher_(control_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> control_matcher_;
+};
+
+
+template <typename T>
+class IsConstantMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
+      : NodeMatcher(opcode), value_matcher_(value_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value (";
+    value_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
+                                 listener));
+  }
+
+ private:
+  const Matcher<T> value_matcher_;
+};
+
+
+class IsPhiMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsPhiMatcher(const Matcher<Node*>& value0_matcher,
+               const Matcher<Node*>& value1_matcher,
+               const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kPhi),
+        value0_matcher_(value0_matcher),
+        value1_matcher_(value1_matcher),
+        control_matcher_(control_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value0 (";
+    value0_matcher_.DescribeTo(os);
+    *os << "), value1 (";
+    value1_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value0", value0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "value1", value1_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> value0_matcher_;
+  const Matcher<Node*> value1_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsProjectionMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsProjectionMatcher(const Matcher<int32_t>& index_matcher,
+                      const Matcher<Node*>& base_matcher)
+      : NodeMatcher(IrOpcode::kProjection),
+        index_matcher_(index_matcher),
+        base_matcher_(base_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose index (";
+    index_matcher_.DescribeTo(os);
+    *os << ") and base (";
+    base_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<int32_t>(node), "index",
+                                 index_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener));
+  }
+
+ private:
+  const Matcher<int32_t> index_matcher_;
+  const Matcher<Node*> base_matcher_;
+};
+
+
+class IsLoadMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsLoadMatcher(const Matcher<MachineType>& type_matcher,
+                const Matcher<Node*>& base_matcher,
+                const Matcher<Node*>& index_matcher,
+                const Matcher<Node*>& effect_matcher)
+      : NodeMatcher(IrOpcode::kLoad),
+        type_matcher_(type_matcher),
+        base_matcher_(base_matcher),
+        index_matcher_(index_matcher),
+        effect_matcher_(effect_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose type (";
+    type_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), index (";
+    index_matcher_.DescribeTo(os);
+    *os << ") and effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
+                                 type_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "index", index_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener));
+  }
+
+ private:
+  const Matcher<MachineType> type_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> index_matcher_;
+  const Matcher<Node*> effect_matcher_;
+};
+
+
+class IsStoreMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsStoreMatcher(const Matcher<MachineType>& type_matcher,
+                 const Matcher<WriteBarrierKind> write_barrier_matcher,
+                 const Matcher<Node*>& base_matcher,
+                 const Matcher<Node*>& index_matcher,
+                 const Matcher<Node*>& value_matcher,
+                 const Matcher<Node*>& effect_matcher,
+                 const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kStore),
+        type_matcher_(type_matcher),
+        write_barrier_matcher_(write_barrier_matcher),
+        base_matcher_(base_matcher),
+        index_matcher_(index_matcher),
+        value_matcher_(value_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose type (";
+    type_matcher_.DescribeTo(os);
+    *os << "), write barrier (";
+    write_barrier_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), index (";
+    index_matcher_.DescribeTo(os);
+    *os << "), value (";
+    value_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(
+ OpParameter<StoreRepresentation>(node).machine_type, "type",
+                type_matcher_, listener) &&
+            PrintMatchAndExplain(
+                OpParameter<StoreRepresentation>(node).write_barrier_kind,
+                "write barrier", write_barrier_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "index", index_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "value", value_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<MachineType> type_matcher_;
+  const Matcher<WriteBarrierKind> write_barrier_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> index_matcher_;
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsBinopMatcher V8_FINAL : public NodeMatcher {
+ public:
+  IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
+                 const Matcher<Node*>& rhs_matcher)
+      : NodeMatcher(opcode),
+        lhs_matcher_(lhs_matcher),
+        rhs_matcher_(rhs_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose lhs (";
+    lhs_matcher_.DescribeTo(os);
+    *os << ") and rhs (";
+    rhs_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
+                                 lhs_matcher_, listener) &&
+ PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
+                                 rhs_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> lhs_matcher_;
+  const Matcher<Node*> rhs_matcher_;
+};
+
+
+class IsUnopMatcher V8_FINAL : public NodeMatcher {
+ public:
+ IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
+      : NodeMatcher(opcode), input_matcher_(input_matcher) {}
+
+  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose input (";
+    input_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+ virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
+      V8_OVERRIDE {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "input", input_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> input_matcher_;
+};
+}
+
+
+Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
+                       const Matcher<Node*>& control1_matcher) {
+ return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher));
+}
+
+
+Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsIfTrueMatcher(control_matcher));
+}
+
+
+Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsIfFalseMatcher(control_matcher));
+}
+
+
+Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
+  return MakeMatcher(
+ new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
+}
+
+
+Matcher<Node*> IsHeapConstant(
+    const Matcher<PrintableUnique<HeapObject> >& value_matcher) {
+  return MakeMatcher(new IsConstantMatcher<PrintableUnique<HeapObject> >(
+      IrOpcode::kHeapConstant, value_matcher));
+}
+
+
+Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher,
+                     const Matcher<Node*>& value1_matcher,
+                     const Matcher<Node*>& merge_matcher) {
+  return MakeMatcher(
+      new IsPhiMatcher(value0_matcher, value1_matcher, merge_matcher));
+}
+
+
+Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher,
+                            const Matcher<Node*>& base_matcher) {
+  return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
+}
+
+
+Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
+                      const Matcher<Node*>& base_matcher,
+                      const Matcher<Node*>& index_matcher,
+                      const Matcher<Node*>& effect_matcher) {
+  return MakeMatcher(new IsLoadMatcher(type_matcher, base_matcher,
+                                       index_matcher, effect_matcher));
+}
+
+
+Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
+ const Matcher<WriteBarrierKind>& write_barrier_matcher,
+                       const Matcher<Node*>& base_matcher,
+                       const Matcher<Node*>& index_matcher,
+                       const Matcher<Node*>& value_matcher,
+                       const Matcher<Node*>& effect_matcher,
+                       const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsStoreMatcher(
+      type_matcher, write_barrier_matcher, base_matcher, index_matcher,
+      value_matcher, effect_matcher, control_matcher));
+}
+
+
+#define IS_BINOP_MATCHER(Name)                                            \
+  Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
+                          const Matcher<Node*>& rhs_matcher) {            \
+    return MakeMatcher(                                                   \
+        new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
+  }
+IS_BINOP_MATCHER(Word32And)
+IS_BINOP_MATCHER(Word32Sar)
+IS_BINOP_MATCHER(Word32Ror)
+IS_BINOP_MATCHER(Word32Equal)
+IS_BINOP_MATCHER(Word64And)
+IS_BINOP_MATCHER(Word64Sar)
+IS_BINOP_MATCHER(Word64Shl)
+IS_BINOP_MATCHER(Word64Equal)
+IS_BINOP_MATCHER(Int32AddWithOverflow)
+#undef IS_BINOP_MATCHER
+
+
+#define IS_UNOP_MATCHER(Name) \ + Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ + return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
+  }
+IS_UNOP_MATCHER(ConvertInt64ToInt32)
+IS_UNOP_MATCHER(ChangeInt32ToFloat64)
+#undef IS_UNOP_MATCHER
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h Mon Aug 18 06:54:07 2014 UTC
@@ -0,0 +1,89 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_UNITTESTS_GRAPH_UNITTEST_H_
+#define V8_COMPILER_UNITTESTS_GRAPH_UNITTEST_H_
+
+#include "src/compiler/graph.h"
+#include "src/compiler/machine-operator.h"
+#include "test/compiler-unittests/common-operator-unittest.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class HeapObject;
+template <class T>
+class PrintableUnique;
+
+namespace compiler {
+
+class GraphTest : public CommonOperatorTest {
+ public:
+  explicit GraphTest(int parameters = 1);
+  virtual ~GraphTest();
+
+ protected:
+  Graph* graph() { return &graph_; }
+
+ private:
+  Graph graph_;
+};
+
+
+using ::testing::Matcher;
+
+Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
+                       const Matcher<Node*>& control1_matcher);
+Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsHeapConstant(
+    const Matcher<PrintableUnique<HeapObject> >& value_matcher);
+Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher);
+Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher,
+                     const Matcher<Node*>& value1_matcher,
+                     const Matcher<Node*>& merge_matcher);
+Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher,
+                            const Matcher<Node*>& base_matcher);
+
+Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
+                      const Matcher<Node*>& base_matcher,
+                      const Matcher<Node*>& index_matcher,
+                      const Matcher<Node*>& effect_matcher);
+Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
+ const Matcher<WriteBarrierKind>& write_barrier_matcher,
+                       const Matcher<Node*>& base_matcher,
+                       const Matcher<Node*>& index_matcher,
+                       const Matcher<Node*>& value_matcher,
+                       const Matcher<Node*>& effect_matcher,
+                       const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
+                             const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
+                             const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
+                                      const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsConvertInt64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
+
+}  //  namespace compiler
+}  //  namespace internal
+}  //  namespace v8
+
+#endif  // V8_COMPILER_UNITTESTS_GRAPH_UNITTEST_H_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/testing/gmock-support.h Mon Aug 18 06:54:07 2014 UTC
@@ -0,0 +1,72 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_TESTING_GMOCK_SUPPORT_H_
+#define V8_TESTING_GMOCK_SUPPORT_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace testing {
+
+template <typename T>
+class Capture {
+ public:
+  Capture() : value_(), has_value_(false) {}
+
+  const T& value() const { return value_; }
+  bool has_value() const { return has_value_; }
+
+  void SetValue(const T& value) {
+    DCHECK(!has_value());
+    value_ = value;
+    has_value_ = true;
+  }
+
+ private:
+  T value_;
+  bool has_value_;
+};
+
+
+namespace internal {
+
+template <typename T>
+class CaptureEqMatcher : public MatcherInterface<T> {
+ public:
+  explicit CaptureEqMatcher(Capture<T>* capture) : capture_(capture) {}
+
+  virtual void DescribeTo(std::ostream* os) const {
+    *os << "captured by " << static_cast<const void*>(capture_);
+ if (capture_->has_value()) *os << " which has value " << capture_->value();
+  }
+
+ virtual bool MatchAndExplain(T value, MatchResultListener* listener) const {
+    if (!capture_->has_value()) {
+      capture_->SetValue(value);
+      return true;
+    }
+    if (value != capture_->value()) {
+      *listener << "which is not equal to " << capture_->value();
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  Capture<T>* capture_;
+};
+
+}  // namespace internal
+
+
+// CaptureEq(capture) captures the value passed in during matching as long as it +// is unset, and once set, compares the value for equality with the argument.
+template <typename T>
+Matcher<T> CaptureEq(Capture<T>* capture) {
+  return MakeMatcher(new internal::CaptureEqMatcher<T>(capture));
+}
+
+}  // namespace testing
+
+#endif  // V8_TESTING_GMOCK_SUPPORT_H_
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/node-matchers.cc Thu Aug 14 09:19:54 2014 UTC
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "test/compiler-unittests/node-matchers.h"
-
-#include <ostream>  // NOLINT(readability/streams)
-
-#include "src/compiler/node-properties-inl.h"
-
-using testing::MakeMatcher;
-using testing::MatcherInterface;
-using testing::MatchResultListener;
-using testing::StringMatchResultListener;
-
-namespace v8 {
-namespace internal {
-
-// TODO(bmeurer): Find a new home for these functions.
-template <typename T>
-inline std::ostream& operator<<(std::ostream& os,
-                                const PrintableUnique<T>& value) {
-  return os << value.string();
-}
-
-namespace compiler {
-
-namespace {
-
-template <typename T>
-bool PrintMatchAndExplain(const T& value, const char* value_name,
-                          const Matcher<T>& value_matcher,
-                          MatchResultListener* listener) {
-  StringMatchResultListener value_listener;
-  if (!value_matcher.MatchAndExplain(value, &value_listener)) {
- *listener << "whose " << value_name << " " << value << " doesn't match";
-    if (value_listener.str() != "") {
-      *listener << ", " << value_listener.str();
-    }
-    return false;
-  }
-  return true;
-}
-
-
-class NodeMatcher : public MatcherInterface<Node*> {
- public:
-  explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    if (node == NULL) {
-      *listener << "which is NULL";
-      return false;
-    }
-    if (node->opcode() != opcode_) {
- *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode());
-      return false;
-    }
-    return true;
-  }
-
- private:
-  const IrOpcode::Value opcode_;
-};
-
-
-class IsBranchMatcher V8_FINAL : public NodeMatcher {
- public:
-  IsBranchMatcher(const Matcher<Node*>& value_matcher,
-                  const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kBranch),
-        value_matcher_(value_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value (";
-    value_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "value", value_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> value_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-template <typename T>
-class IsConstantMatcher V8_FINAL : public NodeMatcher {
- public:
- IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
-      : NodeMatcher(opcode), value_matcher_(value_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value (";
-    value_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
- PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
-                                 listener));
-  }
-
- private:
-  const Matcher<T> value_matcher_;
-};
-
-
-class IsPhiMatcher V8_FINAL : public NodeMatcher {
- public:
-  IsPhiMatcher(const Matcher<Node*>& value0_matcher,
-               const Matcher<Node*>& value1_matcher,
-               const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kPhi),
-        value0_matcher_(value0_matcher),
-        value1_matcher_(value1_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value0 (";
-    value0_matcher_.DescribeTo(os);
-    *os << "), value1 (";
-    value1_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "value0", value0_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "value1", value1_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> value0_matcher_;
-  const Matcher<Node*> value1_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsProjectionMatcher V8_FINAL : public NodeMatcher {
- public:
-  IsProjectionMatcher(const Matcher<int32_t>& index_matcher,
-                      const Matcher<Node*>& base_matcher)
-      : NodeMatcher(IrOpcode::kProjection),
-        index_matcher_(index_matcher),
-        base_matcher_(base_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose index (";
-    index_matcher_.DescribeTo(os);
-    *os << ") and base (";
-    base_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<int32_t>(node), "index",
-                                 index_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
-                                 base_matcher_, listener));
-  }
-
- private:
-  const Matcher<int32_t> index_matcher_;
-  const Matcher<Node*> base_matcher_;
-};
-
-
-class IsLoadMatcher V8_FINAL : public NodeMatcher {
- public:
-  IsLoadMatcher(const Matcher<MachineType>& type_matcher,
-                const Matcher<Node*>& base_matcher,
-                const Matcher<Node*>& index_matcher,
-                const Matcher<Node*>& effect_matcher)
-      : NodeMatcher(IrOpcode::kLoad),
-        type_matcher_(type_matcher),
-        base_matcher_(base_matcher),
-        index_matcher_(index_matcher),
-        effect_matcher_(effect_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose type (";
-    type_matcher_.DescribeTo(os);
-    *os << "), base (";
-    base_matcher_.DescribeTo(os);
-    *os << "), index (";
-    index_matcher_.DescribeTo(os);
-    *os << ") and effect (";
-    effect_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
-                                 type_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
-                                 base_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "index", index_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
-                                 effect_matcher_, listener));
-  }
-
- private:
-  const Matcher<MachineType> type_matcher_;
-  const Matcher<Node*> base_matcher_;
-  const Matcher<Node*> index_matcher_;
-  const Matcher<Node*> effect_matcher_;
-};
-
-
-class IsStoreMatcher V8_FINAL : public NodeMatcher {
- public:
-  IsStoreMatcher(const Matcher<MachineType>& type_matcher,
-                 const Matcher<WriteBarrierKind> write_barrier_matcher,
-                 const Matcher<Node*>& base_matcher,
-                 const Matcher<Node*>& index_matcher,
-                 const Matcher<Node*>& value_matcher,
-                 const Matcher<Node*>& effect_matcher,
-                 const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kStore),
-        type_matcher_(type_matcher),
-        write_barrier_matcher_(write_barrier_matcher),
-        base_matcher_(base_matcher),
-        index_matcher_(index_matcher),
-        value_matcher_(value_matcher),
-        effect_matcher_(effect_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose type (";
-    type_matcher_.DescribeTo(os);
-    *os << "), write barrier (";
-    write_barrier_matcher_.DescribeTo(os);
-    *os << "), base (";
-    base_matcher_.DescribeTo(os);
-    *os << "), index (";
-    index_matcher_.DescribeTo(os);
-    *os << "), value (";
-    value_matcher_.DescribeTo(os);
-    *os << "), effect (";
-    effect_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(
- OpParameter<StoreRepresentation>(node).machine_type, "type",
-                type_matcher_, listener) &&
-            PrintMatchAndExplain(
-                OpParameter<StoreRepresentation>(node).write_barrier_kind,
-                "write barrier", write_barrier_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
-                                 base_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "index", index_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
-                                 "value", value_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
-                                 effect_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<MachineType> type_matcher_;
-  const Matcher<WriteBarrierKind> write_barrier_matcher_;
-  const Matcher<Node*> base_matcher_;
-  const Matcher<Node*> index_matcher_;
-  const Matcher<Node*> value_matcher_;
-  const Matcher<Node*> effect_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsBinopMatcher V8_FINAL : public NodeMatcher {
- public:
-  IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
-                 const Matcher<Node*>& rhs_matcher)
-      : NodeMatcher(opcode),
-        lhs_matcher_(lhs_matcher),
-        rhs_matcher_(rhs_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose lhs (";
-    lhs_matcher_.DescribeTo(os);
-    *os << ") and rhs (";
-    rhs_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
- PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
-                                 lhs_matcher_, listener) &&
- PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
-                                 rhs_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> lhs_matcher_;
-  const Matcher<Node*> rhs_matcher_;
-};
-
-
-class IsUnopMatcher V8_FINAL : public NodeMatcher {
- public:
- IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
-      : NodeMatcher(opcode), input_matcher_(input_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const V8_OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose input (";
-    input_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
- virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      V8_OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "input", input_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> input_matcher_;
-};
-
-}
-
-
-Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
-                        const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
-}
-
-
-Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
-  return MakeMatcher(
- new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
-}
-
-
-Matcher<Node*> IsHeapConstant(
-    const Matcher<PrintableUnique<HeapObject> >& value_matcher) {
-  return MakeMatcher(new IsConstantMatcher<PrintableUnique<HeapObject> >(
-      IrOpcode::kHeapConstant, value_matcher));
-}
-
-
-Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher,
-                     const Matcher<Node*>& value1_matcher,
-                     const Matcher<Node*>& merge_matcher) {
-  return MakeMatcher(
-      new IsPhiMatcher(value0_matcher, value1_matcher, merge_matcher));
-}
-
-
-Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher,
-                            const Matcher<Node*>& base_matcher) {
-  return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
-}
-
-
-Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
-                      const Matcher<Node*>& base_matcher,
-                      const Matcher<Node*>& index_matcher,
-                      const Matcher<Node*>& effect_matcher) {
-  return MakeMatcher(new IsLoadMatcher(type_matcher, base_matcher,
-                                       index_matcher, effect_matcher));
-}
-
-
-Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
- const Matcher<WriteBarrierKind>& write_barrier_matcher,
-                       const Matcher<Node*>& base_matcher,
-                       const Matcher<Node*>& index_matcher,
-                       const Matcher<Node*>& value_matcher,
-                       const Matcher<Node*>& effect_matcher,
-                       const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(new IsStoreMatcher(
-      type_matcher, write_barrier_matcher, base_matcher, index_matcher,
-      value_matcher, effect_matcher, control_matcher));
-}
-
-
-#define IS_BINOP_MATCHER(Name)                                            \
-  Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
-                          const Matcher<Node*>& rhs_matcher) {            \
-    return MakeMatcher(                                                   \
-        new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
-  }
-IS_BINOP_MATCHER(Word32And)
-IS_BINOP_MATCHER(Word32Sar)
-IS_BINOP_MATCHER(Word32Ror)
-IS_BINOP_MATCHER(Word32Equal)
-IS_BINOP_MATCHER(Word64And)
-IS_BINOP_MATCHER(Word64Sar)
-IS_BINOP_MATCHER(Word64Shl)
-IS_BINOP_MATCHER(Word64Equal)
-IS_BINOP_MATCHER(Int32AddWithOverflow)
-#undef IS_BINOP_MATCHER
-
-
-#define IS_UNOP_MATCHER(Name) \ - Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) { \ - return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
-  }
-IS_UNOP_MATCHER(ConvertInt64ToInt32)
-IS_UNOP_MATCHER(ChangeInt32ToFloat64)
-#undef IS_UNOP_MATCHER
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/node-matchers.h Thu Aug 14 09:07:58 2014 UTC
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_UNITTESTS_NODE_MATCHERS_H_
-#define V8_COMPILER_UNITTESTS_NODE_MATCHERS_H_
-
-#include "src/compiler/machine-operator.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace v8 {
-namespace internal {
-
-// Forward declarations.
-class HeapObject;
-template <class T>
-class PrintableUnique;
-
-namespace compiler {
-
-// Forward declarations.
-class Node;
-
-using testing::Matcher;
-
-Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
-                        const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsHeapConstant(
-    const Matcher<PrintableUnique<HeapObject> >& value_matcher);
-Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher);
-Matcher<Node*> IsPhi(const Matcher<Node*>& value0_matcher,
-                     const Matcher<Node*>& value1_matcher,
-                     const Matcher<Node*>& merge_matcher);
-Matcher<Node*> IsProjection(const Matcher<int32_t>& index_matcher,
-                            const Matcher<Node*>& base_matcher);
-
-Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
-                      const Matcher<Node*>& base_matcher,
-                      const Matcher<Node*>& index_matcher,
-                      const Matcher<Node*>& effect_matcher);
-Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
- const Matcher<WriteBarrierKind>& write_barrier_matcher,
-                       const Matcher<Node*>& base_matcher,
-                       const Matcher<Node*>& index_matcher,
-                       const Matcher<Node*>& value_matcher,
-                       const Matcher<Node*>& effect_matcher,
-                       const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
-                             const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
-                             const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
-                                      const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsConvertInt64ToInt32(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
-
-}  //  namespace compiler
-}  //  namespace internal
-}  //  namespace v8
-
-#endif  // V8_COMPILER_UNITTESTS_NODE_MATCHERS_H_
=======================================
--- /branches/bleeding_edge/src/compiler/change-lowering.cc Thu Aug 14 09:19:54 2014 UTC +++ /branches/bleeding_edge/src/compiler/change-lowering.cc Mon Aug 18 06:54:07 2014 UTC
@@ -4,100 +4,58 @@

 #include "src/compiler/change-lowering.h"

-#include "src/compiler/common-node-cache.h"
-#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"

 namespace v8 {
 namespace internal {
 namespace compiler {

-ChangeLoweringBase::ChangeLoweringBase(Graph* graph, Linkage* linkage,
-                                       CommonNodeCache* cache)
-    : graph_(graph),
-      isolate_(graph->zone()->isolate()),
-      linkage_(linkage),
-      cache_(cache),
-      common_(graph->zone()),
-      machine_(graph->zone()) {}
+ChangeLowering::~ChangeLowering() {}


-ChangeLoweringBase::~ChangeLoweringBase() {}
-
-
-Node* ChangeLoweringBase::ExternalConstant(ExternalReference reference) {
-  Node** loc = cache()->FindExternalConstant(reference);
-  if (*loc == NULL) {
-    *loc = graph()->NewNode(common()->ExternalConstant(reference));
+Reduction ChangeLowering::Reduce(Node* node) {
+  Node* control = graph()->start();
+  Node* effect = control;
+  switch (node->opcode()) {
+    case IrOpcode::kChangeBitToBool:
+      return ChangeBitToBool(node->InputAt(0), control);
+    case IrOpcode::kChangeBoolToBit:
+      return ChangeBoolToBit(node->InputAt(0));
+    case IrOpcode::kChangeInt32ToTagged:
+      return ChangeInt32ToTagged(node->InputAt(0), effect, control);
+    case IrOpcode::kChangeTaggedToFloat64:
+      return ChangeTaggedToFloat64(node->InputAt(0), effect, control);
+    default:
+      return NoChange();
   }
-  return *loc;
+  UNREACHABLE();
+  return NoChange();
 }


-Node* ChangeLoweringBase::HeapConstant(PrintableUnique<HeapObject> value) {
-  // TODO(bmeurer): Use common node cache.
-  return graph()->NewNode(common()->HeapConstant(value));
+Node* ChangeLowering::HeapNumberValueIndexConstant() {
+  STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0);
+  const int heap_number_value_offset =
+ ((HeapNumber::kValueOffset / kPointerSize) * (machine()->is64() ? 8 : 4)); + return jsgraph()->Int32Constant(heap_number_value_offset - kHeapObjectTag);
 }


-Node* ChangeLoweringBase::ImmovableHeapConstant(Handle<HeapObject> value) {
-  return HeapConstant(
- PrintableUnique<HeapObject>::CreateImmovable(graph()->zone(), value));
+Node* ChangeLowering::SmiShiftBitsConstant() {
+ const int smi_shift_size = (machine()->is64() ? SmiTagging<8>::kSmiShiftSize + : SmiTagging<4>::kSmiShiftSize);
+  return jsgraph()->Int32Constant(smi_shift_size + kSmiTagSize);
 }


-Node* ChangeLoweringBase::Int32Constant(int32_t value) {
-  Node** loc = cache()->FindInt32Constant(value);
-  if (*loc == NULL) {
-    *loc = graph()->NewNode(common()->Int32Constant(value));
-  }
-  return *loc;
-}
-
-
-Node* ChangeLoweringBase::NumberConstant(double value) {
-  Node** loc = cache()->FindNumberConstant(value);
-  if (*loc == NULL) {
-    *loc = graph()->NewNode(common()->NumberConstant(value));
-  }
-  return *loc;
-}
-
-
-Node* ChangeLoweringBase::CEntryStubConstant() {
-  if (!c_entry_stub_constant_.is_set()) {
-    c_entry_stub_constant_.set(
-        ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode()));
-  }
-  return c_entry_stub_constant_.get();
-}
-
-
-Node* ChangeLoweringBase::TrueConstant() {
-  if (!true_constant_.is_set()) {
-    true_constant_.set(
-        ImmovableHeapConstant(isolate()->factory()->true_value()));
-  }
-  return true_constant_.get();
-}
-
-
-Node* ChangeLoweringBase::FalseConstant() {
-  if (!false_constant_.is_set()) {
-    false_constant_.set(
-        ImmovableHeapConstant(isolate()->factory()->false_value()));
-  }
-  return false_constant_.get();
-}
-
-
-Reduction ChangeLoweringBase::ChangeBitToBool(Node* val, Node* control) {
+Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
   Node* branch = graph()->NewNode(common()->Branch(), val, control);

   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* true_value = TrueConstant();
+  Node* true_value = jsgraph()->TrueConstant();

   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* false_value = FalseConstant();
+  Node* false_value = jsgraph()->FalseConstant();

   Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
   Node* phi =
@@ -107,51 +65,20 @@
 }


-template <size_t kPointerSize>
-ChangeLowering<kPointerSize>::ChangeLowering(Graph* graph, Linkage* linkage)
-    : ChangeLoweringBase(graph, linkage,
- new (graph->zone()) CommonNodeCache(graph->zone())) {}
-
-
-template <size_t kPointerSize>
-Reduction ChangeLowering<kPointerSize>::Reduce(Node* node) {
-  Node* control = graph()->start();
-  Node* effect = control;
-  switch (node->opcode()) {
-    case IrOpcode::kChangeBitToBool:
-      return ChangeBitToBool(node->InputAt(0), control);
-    case IrOpcode::kChangeBoolToBit:
-      return ChangeBoolToBit(node->InputAt(0));
-    case IrOpcode::kChangeInt32ToTagged:
-      return ChangeInt32ToTagged(node->InputAt(0), effect, control);
-    case IrOpcode::kChangeTaggedToFloat64:
-      return ChangeTaggedToFloat64(node->InputAt(0), effect, control);
-    default:
-      return NoChange();
-  }
-  UNREACHABLE();
-  return NoChange();
-}
-
-
-template <>
-Reduction ChangeLowering<4>::ChangeBoolToBit(Node* val) {
+Reduction ChangeLowering::ChangeBoolToBit(Node* val) {
   return Replace(
-      graph()->NewNode(machine()->Word32Equal(), val, TrueConstant()));
+ graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant()));
 }

-
-template <>
-Reduction ChangeLowering<8>::ChangeBoolToBit(Node* val) {
-  return Replace(
-      graph()->NewNode(machine()->Word64Equal(), val, TrueConstant()));
-}

+Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* effect,
+                                              Node* control) {
+  if (machine()->is64()) {
+    return Replace(
+ graph()->NewNode(machine()->WordShl(), val, SmiShiftBitsConstant()));
+  }

-template <>
-Reduction ChangeLowering<4>::ChangeInt32ToTagged(Node* val, Node* effect,
-                                                 Node* control) {
-  Node* context = NumberConstant(0);
+  Node* context = jsgraph()->SmiConstant(0);

Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val, val);
   Node* ovf = graph()->NewNode(common()->Projection(1), add);
@@ -167,15 +94,14 @@
   DCHECK_EQ(0, fn->nargs);
   CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
       fn->function_id, 0, Operator::kNoProperties);
-  Node* heap_number =
-      graph()->NewNode(common()->Call(desc), CEntryStubConstant(),
-                       ExternalConstant(ExternalReference(fn, isolate())),
-                       Int32Constant(0), context, effect, if_true);
+  Node* heap_number = graph()->NewNode(
+      common()->Call(desc), jsgraph()->CEntryStubConstant(),
+      jsgraph()->ExternalConstant(ExternalReference(fn, isolate())),
+      jsgraph()->ZeroConstant(), context, effect, if_true);

   Node* store = graph()->NewNode(
       machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number,
- Int32Constant(HeapNumber::kValueOffset - kHeapObjectTag), number, effect,
-      heap_number);
+      HeapNumberValueIndexConstant(), number, effect, heap_number);

   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   Node* smi = graph()->NewNode(common()->Projection(0), add);
@@ -186,35 +112,27 @@
   return Replace(phi);
 }

-
-template <>
-Reduction ChangeLowering<8>::ChangeInt32ToTagged(Node* val, Node* effect,
-                                                 Node* control) {
-  return Replace(graph()->NewNode(
-      machine()->Word64Shl(), val,
-      Int32Constant(SmiTagging<8>::kSmiShiftSize + kSmiTagSize)));
-}

+Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* effect,
+                                                Node* control) {
+  STATIC_ASSERT(kSmiTagMask == 1);

-template <>
-Reduction ChangeLowering<4>::ChangeTaggedToFloat64(Node* val, Node* effect,
-                                                   Node* control) {
-  Node* branch = graph()->NewNode(
-      common()->Branch(),
- graph()->NewNode(machine()->Word32And(), val, Int32Constant(kSmiTagMask)),
-      control);
+  Node* tag = graph()->NewNode(machine()->WordAnd(), val,
+                               jsgraph()->Int32Constant(kSmiTagMask));
+  Node* branch = graph()->NewNode(common()->Branch(), tag, control);

   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* load = graph()->NewNode(
-      machine()->Load(kMachFloat64), val,
-      Int32Constant(HeapNumber::kValueOffset - kHeapObjectTag), if_true);
+  Node* load = graph()->NewNode(machine()->Load(kMachFloat64), val,
+                                HeapNumberValueIndexConstant(), if_true);

   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* integer =
+      graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant());
   Node* number = graph()->NewNode(
       machine()->ChangeInt32ToFloat64(),
-      graph()->NewNode(
-          machine()->Word32Sar(), val,
-          Int32Constant(SmiTagging<4>::kSmiShiftSize + kSmiTagSize)));
+      machine()->is64()
+          ? graph()->NewNode(machine()->ConvertInt64ToInt32(), integer)
+          : integer);

   Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
   Node* phi = graph()->NewNode(common()->Phi(2), load, number, merge);
@@ -223,37 +141,15 @@
 }


-template <>
-Reduction ChangeLowering<8>::ChangeTaggedToFloat64(Node* val, Node* effect,
-                                                   Node* control) {
-  Node* branch = graph()->NewNode(
-      common()->Branch(),
- graph()->NewNode(machine()->Word64And(), val, Int32Constant(kSmiTagMask)),
-      control);
+Isolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); }

-  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* load = graph()->NewNode(
-      machine()->Load(kMachFloat64), val,
-      Int32Constant(HeapNumber::kValueOffset - kHeapObjectTag), if_true);

-  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* number = graph()->NewNode(
-      machine()->ChangeInt32ToFloat64(),
-      graph()->NewNode(
-          machine()->ConvertInt64ToInt32(),
-          graph()->NewNode(
-              machine()->Word64Sar(), val,
-              Int32Constant(SmiTagging<8>::kSmiShiftSize + kSmiTagSize))));
+Graph* ChangeLowering::graph() const { return jsgraph()->graph(); }

-  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-  Node* phi = graph()->NewNode(common()->Phi(2), load, number, merge);

-  return Replace(phi);
+CommonOperatorBuilder* ChangeLowering::common() const {
+  return jsgraph()->common();
 }
-
-
-template class ChangeLowering<4>;
-template class ChangeLowering<8>;

 }  // namespace compiler
 }  // namespace internal
=======================================
--- /branches/bleeding_edge/src/compiler/change-lowering.h Tue Aug 12 08:24:20 2014 UTC +++ /branches/bleeding_edge/src/compiler/change-lowering.h Mon Aug 18 06:54:07 2014 UTC
@@ -5,71 +5,47 @@
 #ifndef V8_COMPILER_CHANGE_LOWERING_H_
 #define V8_COMPILER_CHANGE_LOWERING_H_

-#include "include/v8.h"
-#include "src/compiler/common-operator.h"
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/machine-operator.h"

 namespace v8 {
 namespace internal {
 namespace compiler {

 // Forward declarations.
-class CommonNodeCache;
+class CommonOperatorBuilder;
+class JSGraph;
 class Linkage;
+class MachineOperatorBuilder;

-class ChangeLoweringBase : public Reducer {
+class ChangeLowering V8_FINAL : public Reducer {
  public:
- ChangeLoweringBase(Graph* graph, Linkage* linkage, CommonNodeCache* cache);
-  virtual ~ChangeLoweringBase();
+  ChangeLowering(JSGraph* jsgraph, Linkage* linkage,
+                 MachineOperatorBuilder* machine)
+      : jsgraph_(jsgraph), linkage_(linkage), machine_(machine) {}
+  virtual ~ChangeLowering();
+
+  virtual Reduction Reduce(Node* node) V8_OVERRIDE;

  protected:
-  Node* ExternalConstant(ExternalReference reference);
-  Node* HeapConstant(PrintableUnique<HeapObject> value);
-  Node* ImmovableHeapConstant(Handle<HeapObject> value);
-  Node* Int32Constant(int32_t value);
-  Node* NumberConstant(double value);
-  Node* CEntryStubConstant();
-  Node* TrueConstant();
-  Node* FalseConstant();
+  Node* HeapNumberValueIndexConstant();
+  Node* SmiShiftBitsConstant();

   Reduction ChangeBitToBool(Node* val, Node* control);
+  Reduction ChangeBoolToBit(Node* val);
+  Reduction ChangeInt32ToTagged(Node* val, Node* effect, Node* control);
+  Reduction ChangeTaggedToFloat64(Node* val, Node* effect, Node* control);

-  Graph* graph() const { return graph_; }
-  Isolate* isolate() const { return isolate_; }
+  Graph* graph() const;
+  Isolate* isolate() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
   Linkage* linkage() const { return linkage_; }
-  CommonNodeCache* cache() const { return cache_; }
-  CommonOperatorBuilder* common() { return &common_; }
-  MachineOperatorBuilder* machine() { return &machine_; }
+  CommonOperatorBuilder* common() const;
+  MachineOperatorBuilder* machine() const { return machine_; }

  private:
-  Graph* graph_;
-  Isolate* isolate_;
+  JSGraph* jsgraph_;
   Linkage* linkage_;
-  CommonNodeCache* cache_;
-  CommonOperatorBuilder common_;
-  MachineOperatorBuilder machine_;
-
-  SetOncePointer<Node> c_entry_stub_constant_;
-  SetOncePointer<Node> true_constant_;
-  SetOncePointer<Node> false_constant_;
-};
-
-
-template <size_t kPointerSize = kApiPointerSize>
-class ChangeLowering V8_FINAL : public ChangeLoweringBase {
- public:
-  ChangeLowering(Graph* graph, Linkage* linkage);
-  ChangeLowering(Graph* graph, Linkage* linkage, CommonNodeCache* cache)
-      : ChangeLoweringBase(graph, linkage, cache) {}
-  virtual ~ChangeLowering() {}
-
-  virtual Reduction Reduce(Node* node) V8_OVERRIDE;
-
- private:
-  Reduction ChangeBoolToBit(Node* val);
-  Reduction ChangeInt32ToTagged(Node* val, Node* effect, Node* control);
-  Reduction ChangeTaggedToFloat64(Node* val, Node* effect, Node* control);
+  MachineOperatorBuilder* machine_;
 };

 }  // namespace compiler
=======================================
--- /branches/bleeding_edge/src/compiler/js-graph.cc Wed Jul 30 13:54:45 2014 UTC +++ /branches/bleeding_edge/src/compiler/js-graph.cc Mon Aug 18 06:54:07 2014 UTC
@@ -22,6 +22,15 @@
   typer_->Init(node);
   return node;
 }
+
+
+Node* JSGraph::CEntryStubConstant() {
+  if (!c_entry_stub_constant_.is_set()) {
+    c_entry_stub_constant_.set(
+        ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode()));
+  }
+  return c_entry_stub_constant_.get();
+}


 Node* JSGraph::UndefinedConstant() {
=======================================
--- /branches/bleeding_edge/src/compiler/js-graph.h Mon Aug 4 11:34:54 2014 UTC +++ /branches/bleeding_edge/src/compiler/js-graph.h Mon Aug 18 06:54:07 2014 UTC
@@ -30,6 +30,7 @@
         cache_(zone()) {}

   // Canonicalized global constants.
+  Node* CEntryStubConstant();
   Node* UndefinedConstant();
   Node* TheHoleConstant();
   Node* TrueConstant();
@@ -76,6 +77,7 @@
   CommonOperatorBuilder* common() { return common_; }
   Graph* graph() { return graph_; }
   Zone* zone() { return graph()->zone(); }
+  Isolate* isolate() { return zone()->isolate(); }

  private:
   Graph* graph_;
@@ -83,6 +85,7 @@
   JSOperatorBuilder javascript_;
   Typer* typer_;

+  SetOncePointer<Node> c_entry_stub_constant_;
   SetOncePointer<Node> undefined_constant_;
   SetOncePointer<Node> the_hole_constant_;
   SetOncePointer<Node> true_constant_;
@@ -98,7 +101,7 @@
   Node* NumberConstant(double value);
   Node* NewNode(Operator* op);

-  Factory* factory() { return zone()->isolate()->factory(); }
+  Factory* factory() { return isolate()->factory(); }
 };
 }  // namespace compiler
 }  // namespace internal
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/DEPS Thu Aug 14 06:33:50 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/DEPS Mon Aug 18 06:54:07 2014 UTC
@@ -3,4 +3,5 @@
   "+testing/gtest",
   "+testing/gtest-support.h",
   "+testing/gmock",
+  "+testing/gmock-support.h",
 ]
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc Thu Aug 14 09:19:54 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc Mon Aug 18 06:54:07 2014 UTC
@@ -3,29 +3,33 @@
 // found in the LICENSE file.

 #include "src/compiler/change-lowering.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/simplified-operator.h"
-#include "src/factory.h"
-#include "test/compiler-unittests/compiler-unittests.h"
-#include "test/compiler-unittests/node-matchers.h"
+#include "src/compiler/typer.h"
+#include "test/compiler-unittests/graph-unittest.h"
+#include "testing/gmock-support.h"

 using testing::_;
+using testing::AllOf;
+using testing::Capture;
+using testing::CaptureEq;

 namespace v8 {
 namespace internal {
 namespace compiler {

 template <typename T>
-class ChangeLoweringTest : public CompilerTest {
+class ChangeLoweringTest : public GraphTest {
  public:
   static const size_t kPointerSize = sizeof(T);
+  static const MachineType kWordRepresentation =
+      (kPointerSize == 4) ? kRepWord32 : kRepWord64;
+  STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0);
+  static const int kHeapNumberValueOffset = static_cast<int>(
+      (HeapNumber::kValueOffset / kApiPointerSize) * kPointerSize);

-  explicit ChangeLoweringTest(int num_parameters = 1)
-      : graph_(zone()), common_(zone()), simplified_(zone()) {
-    graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
-  }
+  ChangeLoweringTest() : simplified_(zone()) {}
   virtual ~ChangeLoweringTest() {}

  protected:
@@ -34,15 +38,15 @@
   }

   Reduction Reduce(Node* node) {
+    Typer typer(zone());
+    JSGraph jsgraph(graph(), common(), &typer);
     CompilationInfo info(isolate(), zone());
     Linkage linkage(&info);
-    ChangeLowering<kPointerSize> reducer(graph(), &linkage);
+    MachineOperatorBuilder machine(zone(), kWordRepresentation);
+    ChangeLowering reducer(&jsgraph, &linkage, &machine);
     return reducer.Reduce(node);
   }

-  Graph* graph() { return &graph_; }
-  Factory* factory() const { return isolate()->factory(); }
-  CommonOperatorBuilder* common() { return &common_; }
   SimplifiedOperatorBuilder* simplified() { return &simplified_; }

   PrintableUnique<HeapObject> true_unique() {
@@ -55,8 +59,6 @@
   }

  private:
-  Graph graph_;
-  CommonOperatorBuilder common_;
   SimplifiedOperatorBuilder simplified_;
 };

@@ -73,21 +75,13 @@
   ASSERT_TRUE(reduction.Changed());

   Node* phi = reduction.replacement();
-  EXPECT_THAT(phi, IsPhi(IsHeapConstant(this->true_unique()),
-                         IsHeapConstant(this->false_unique()), _));
-
-  Node* merge = NodeProperties::GetControlInput(phi);
-  ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
-
-  Node* if_true = NodeProperties::GetControlInput(merge, 0);
-  ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
-
-  Node* if_false = NodeProperties::GetControlInput(merge, 1);
-  ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
-
-  Node* branch = NodeProperties::GetControlInput(if_true);
-  EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
-  EXPECT_THAT(branch, IsBranch(val, this->graph()->start()));
+  Capture<Node*> branch;
+  EXPECT_THAT(
+      phi, IsPhi(IsHeapConstant(this->true_unique()),
+                 IsHeapConstant(this->false_unique()),
+                 IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
+ IsBranch(val, this->graph()->start()))),
+                         IsIfFalse(CaptureEq(&branch)))));
 }


@@ -134,7 +128,7 @@
   Node* merge = NodeProperties::GetControlInput(phi);
   ASSERT_EQ(IrOpcode::kMerge, merge->opcode());

-  const int32_t kValueOffset = HeapNumber::kValueOffset - kHeapObjectTag;
+  const int32_t kValueOffset = kHeapNumberValueOffset - kHeapObjectTag;
   EXPECT_THAT(NodeProperties::GetControlInput(merge, 0),
               IsStore(kMachFloat64, kNoWriteBarrier, heap_number,
                       IsInt32Constant(kValueOffset),
@@ -155,6 +149,9 @@


 TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
   Node* val = Parameter(0);
Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
   Reduction reduction = Reduce(node);
@@ -162,29 +159,19 @@

   const int32_t kShiftAmount =
       kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize;
-  const int32_t kValueOffset = HeapNumber::kValueOffset - kHeapObjectTag;
+  const int32_t kValueOffset = kHeapNumberValueOffset - kHeapObjectTag;
   Node* phi = reduction.replacement();
-  ASSERT_THAT(phi,
- IsPhi(IsLoad(kMachFloat64, val, IsInt32Constant(kValueOffset), _),
-                    IsChangeInt32ToFloat64(
-                        IsWord32Sar(val, IsInt32Constant(kShiftAmount))),
-                    _));
-
-  Node* merge = NodeProperties::GetControlInput(phi);
-  ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
-
-  Node* if_true = NodeProperties::GetControlInput(merge, 0);
-  ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
-
-  Node* if_false = NodeProperties::GetControlInput(merge, 1);
-  ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
-
-  Node* branch = NodeProperties::GetControlInput(if_true);
-  EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
- EXPECT_THAT(branch, IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
-                               graph()->start()));
+  Capture<Node*> branch;
+  EXPECT_THAT(
+      phi,
+      IsPhi(IsLoad(kMachFloat64, val, IsInt32Constant(kValueOffset), _),
+            IsChangeInt32ToFloat64(
+                IsWord32Sar(val, IsInt32Constant(kShiftAmount))),
+            IsMerge(IsIfTrue(AllOf(
+                        CaptureEq(&branch),
+ IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
+                                 graph()->start()))),
+                    IsIfFalse(CaptureEq(&branch)))));
 }


@@ -219,6 +206,9 @@


 TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
   Node* val = Parameter(0);
Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
   Reduction reduction = Reduce(node);
@@ -226,29 +216,19 @@

   const int32_t kShiftAmount =
       kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize;
-  const int32_t kValueOffset = HeapNumber::kValueOffset - kHeapObjectTag;
+  const int32_t kValueOffset = kHeapNumberValueOffset - kHeapObjectTag;
   Node* phi = reduction.replacement();
-  ASSERT_THAT(phi,
- IsPhi(IsLoad(kMachFloat64, val, IsInt32Constant(kValueOffset), _),
-                    IsChangeInt32ToFloat64(IsConvertInt64ToInt32(
-                        IsWord64Sar(val, IsInt32Constant(kShiftAmount)))),
-                    _));
-
-  Node* merge = NodeProperties::GetControlInput(phi);
-  ASSERT_EQ(IrOpcode::kMerge, merge->opcode());
-
-  Node* if_true = NodeProperties::GetControlInput(merge, 0);
-  ASSERT_EQ(IrOpcode::kIfTrue, if_true->opcode());
-
-  Node* if_false = NodeProperties::GetControlInput(merge, 1);
-  ASSERT_EQ(IrOpcode::kIfFalse, if_false->opcode());
-
-  Node* branch = NodeProperties::GetControlInput(if_true);
-  EXPECT_EQ(branch, NodeProperties::GetControlInput(if_false));
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
- EXPECT_THAT(branch, IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
-                               graph()->start()));
+  Capture<Node*> branch;
+  EXPECT_THAT(
+      phi,
+      IsPhi(IsLoad(kMachFloat64, val, IsInt32Constant(kValueOffset), _),
+            IsChangeInt32ToFloat64(IsConvertInt64ToInt32(
+                IsWord64Sar(val, IsInt32Constant(kShiftAmount)))),
+            IsMerge(IsIfTrue(AllOf(
+                        CaptureEq(&branch),
+ IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
+                                 graph()->start()))),
+                    IsIfFalse(CaptureEq(&branch)))));
 }

 }  // namespace compiler
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.cc Fri Aug 8 07:04:07 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.cc Mon Aug 18 06:54:07 2014 UTC
@@ -3,6 +3,7 @@
 // found in the LICENSE file.

 #include "include/libplatform/libplatform.h"
+#include "src/isolate-inl.h"
 #include "test/compiler-unittests/compiler-unittests.h"
 #include "testing/gmock/include/gmock/gmock.h"

@@ -25,6 +26,9 @@


 CompilerTest::~CompilerTest() {}
+
+
+Factory* CompilerTest::factory() const { return isolate()->factory(); }


 // static
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.gyp Thu Aug 14 09:07:58 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.gyp Mon Aug 18 06:54:07 2014 UTC
@@ -21,11 +21,13 @@
       ],
       'sources': [  ### gcmole(all) ###
         'change-lowering-unittest.cc',
+        'common-operator-unittest.cc',
+        'common-operator-unittest.h',
         'compiler-unittests.cc',
+        'graph-unittest.cc',
+        'graph-unittest.h',
         'instruction-selector-unittest.cc',
         'machine-operator-reducer-unittest.cc',
-        'node-matchers.cc',
-        'node-matchers.h',
       ],
       'conditions': [
         ['v8_target_arch=="arm"', {
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h Thu Aug 14 06:33:50 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h Mon Aug 18 06:54:07 2014 UTC
@@ -48,6 +48,7 @@
   CompilerTest();
   virtual ~CompilerTest();

+  Factory* factory() const;
   Isolate* isolate() const { return reinterpret_cast<Isolate*>(isolate_); }
   Zone* zone() { return &zone_; }

=======================================
--- /branches/bleeding_edge/test/compiler-unittests/machine-operator-reducer-unittest.cc Thu Aug 14 09:07:58 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/machine-operator-reducer-unittest.cc Mon Aug 18 06:54:07 2014 UTC
@@ -3,22 +3,17 @@
 // found in the LICENSE file.

 #include "src/base/bits.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
 #include "src/compiler/machine-operator-reducer.h"
-#include "test/compiler-unittests/compiler-unittests.h"
-#include "test/compiler-unittests/node-matchers.h"
+#include "test/compiler-unittests/graph-unittest.h"

 namespace v8 {
 namespace internal {
 namespace compiler {

-class MachineOperatorReducerTest : public CompilerTest {
+class MachineOperatorReducerTest : public GraphTest {
  public:
   explicit MachineOperatorReducerTest(int num_parameters = 2)
-      : graph_(zone()), common_(zone()), machine_(zone()) {
-    graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
-  }
+      : GraphTest(num_parameters), machine_(zone()) {}
   virtual ~MachineOperatorReducerTest() {}

  protected:
@@ -34,13 +29,9 @@
     return reducer.Reduce(node);
   }

-  Graph* graph() { return &graph_; }
-  CommonOperatorBuilder* common() { return &common_; }
   MachineOperatorBuilder* machine() { return &machine_; }

  private:
-  Graph graph_;
-  CommonOperatorBuilder common_;
   MachineOperatorBuilder machine_;
 };

=======================================
--- /branches/bleeding_edge/testing/gmock.gyp   Mon Aug  4 09:11:02 2014 UTC
+++ /branches/bleeding_edge/testing/gmock.gyp   Mon Aug 18 06:54:07 2014 UTC
@@ -30,7 +30,7 @@
         'gmock/src/gmock-matchers.cc',
         'gmock/src/gmock-spec-builders.cc',
         'gmock/src/gmock.cc',
-        'gmock_mutant.h',  # gMock helpers
+        'gmock-support.h',  # gMock helpers
       ],
       'sources!': [
         'gmock/src/gmock-all.cc',  # Not needed by our build.

--
--
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.

Reply via email to