[turbofan] Machine operators are globally shared singletons.
authorbmeurer@chromium.org <bmeurer@chromium.org>
Thu, 11 Sep 2014 10:37:49 +0000 (10:37 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org>
Thu, 11 Sep 2014 10:37:49 +0000 (10:37 +0000)
TEST=compiler-unittests,cctest
R=svenpanne@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23864 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

37 files changed:
BUILD.gn
src/compiler/arm/instruction-selector-arm.cc
src/compiler/arm64/instruction-selector-arm64.cc
src/compiler/ast-graph-builder.cc
src/compiler/change-lowering-unittest.cc
src/compiler/change-lowering.cc
src/compiler/graph-unittest.cc
src/compiler/graph-unittest.h
src/compiler/ia32/instruction-selector-ia32.cc
src/compiler/instruction-selector.cc
src/compiler/js-generic-lowering.cc
src/compiler/js-typed-lowering.h
src/compiler/machine-operator-reducer-unittest.cc
src/compiler/machine-operator-reducer.cc
src/compiler/machine-operator-unittest.cc
src/compiler/machine-operator.cc [new file with mode: 0644]
src/compiler/machine-operator.h
src/compiler/machine-type.h
src/compiler/operator.h
src/compiler/pipeline.cc
src/compiler/raw-machine-assembler.cc
src/compiler/raw-machine-assembler.h
src/compiler/simplified-lowering.cc
src/compiler/simplified-lowering.h
src/compiler/simplified-operator-reducer-unittest.cc
src/compiler/simplified-operator.h
src/compiler/x64/instruction-selector-x64.cc
src/unique.h
test/cctest/compiler/graph-builder-tester.h
test/cctest/compiler/test-changes-lowering.cc
test/cctest/compiler/test-instruction.cc
test/cctest/compiler/test-js-typed-lowering.cc
test/cctest/compiler/test-machine-operator-reducer.cc
test/cctest/compiler/test-schedule.cc
test/cctest/compiler/test-scheduler.cc
test/cctest/compiler/test-simplified-lowering.cc
tools/gyp/v8.gyp

index 9938901..76d48d1 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -514,6 +514,7 @@ source_set("v8_base") {
     "src/compiler/linkage.h",
     "src/compiler/machine-operator-reducer.cc",
     "src/compiler/machine-operator-reducer.h",
+    "src/compiler/machine-operator.cc",
     "src/compiler/machine-operator.h",
     "src/compiler/machine-type.cc",
     "src/compiler/machine-type.h",
index cde0fe7..c645fb7 100644 (file)
@@ -283,8 +283,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
+  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
   ArmOperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -330,8 +330,8 @@ void InstructionSelector::VisitStore(Node* node) {
   Node* value = node->InputAt(2);
 
   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type);
-  if (store_rep.write_barrier_kind == kFullWriteBarrier) {
+  MachineType rep = RepresentationOf(store_rep.machine_type());
+  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
     DCHECK(rep == kRepTagged);
     // TODO(dcarney): refactor RecordWrite function to take temp registers
     //                and pass them here instead of using fixed regs
@@ -342,7 +342,7 @@ void InstructionSelector::VisitStore(Node* node) {
          temps);
     return;
   }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind);
+  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
 
   ArchOpcode opcode;
   switch (rep) {
index d5cfdbe..fa2f17f 100644 (file)
@@ -136,8 +136,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node,
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
+  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
   Arm64OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -184,8 +184,8 @@ void InstructionSelector::VisitStore(Node* node) {
   Node* value = node->InputAt(2);
 
   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type);
-  if (store_rep.write_barrier_kind == kFullWriteBarrier) {
+  MachineType rep = RepresentationOf(store_rep.machine_type());
+  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
     DCHECK(rep == kRepTagged);
     // TODO(dcarney): refactor RecordWrite function to take temp registers
     //                and pass them here instead of using fixed regs
@@ -196,7 +196,7 @@ void InstructionSelector::VisitStore(Node* node) {
          temps);
     return;
   }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind);
+  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat32:
index 91ae5b2..25cde42 100644 (file)
@@ -1924,7 +1924,7 @@ Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
 
 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
   // TODO(sigurds) Use simplified load here once it is ready.
-  MachineOperatorBuilder machine(zone());
+  MachineOperatorBuilder machine;
   Node* field_load = NewNode(machine.Load(kMachAnyTagged), object,
                              jsgraph_->Int32Constant(offset - kHeapObjectTag));
   return field_load;
index 1978476..52e9931 100644 (file)
@@ -77,7 +77,7 @@ class ChangeLoweringTest : public GraphTest {
     JSGraph jsgraph(graph(), common(), &typer);
     CompilationInfo info(isolate(), zone());
     Linkage linkage(&info);
-    MachineOperatorBuilder machine(zone(), WordRepresentation());
+    MachineOperatorBuilder machine(WordRepresentation());
     ChangeLowering reducer(&jsgraph, &linkage, &machine);
     return reducer.Reduce(node);
   }
index 7982b76..a885cf1 100644 (file)
@@ -44,13 +44,13 @@ Reduction ChangeLowering::Reduce(Node* node) {
 Node* ChangeLowering::HeapNumberValueIndexConstant() {
   STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0);
   const int heap_number_value_offset =
-      ((HeapNumber::kValueOffset / kPointerSize) * (machine()->is64() ? 8 : 4));
+      ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4));
   return jsgraph()->Int32Constant(heap_number_value_offset - kHeapObjectTag);
 }
 
 
 Node* ChangeLowering::SmiMaxValueConstant() {
-  const int smi_value_size = machine()->is32() ? SmiTagging<4>::SmiValueSize()
+  const int smi_value_size = machine()->Is32() ? SmiTagging<4>::SmiValueSize()
                                                : SmiTagging<8>::SmiValueSize();
   return jsgraph()->Int32Constant(
       -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1));
@@ -58,7 +58,7 @@ Node* ChangeLowering::SmiMaxValueConstant() {
 
 
 Node* ChangeLowering::SmiShiftBitsConstant() {
-  const int smi_shift_size = machine()->is32() ? SmiTagging<4>::SmiShiftSize()
+  const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize()
                                                : SmiTagging<8>::SmiShiftSize();
   return jsgraph()->Int32Constant(smi_shift_size + kSmiTagSize);
 }
@@ -79,15 +79,15 @@ Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) {
       jsgraph()->ExternalConstant(ExternalReference(function, isolate())),
       jsgraph()->Int32Constant(function->nargs), context, effect, control);
   Node* store = graph()->NewNode(
-      machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number,
-      HeapNumberValueIndexConstant(), value, heap_number, control);
+      machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
+      heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
   return graph()->NewNode(common()->Finish(1), heap_number, store);
 }
 
 
 Node* ChangeLowering::ChangeSmiToInt32(Node* value) {
   value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
-  if (machine()->is64()) {
+  if (machine()->Is64()) {
     value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value);
   }
   return value;
@@ -131,7 +131,7 @@ Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
 
 
 Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* control) {
-  if (machine()->is64()) {
+  if (machine()->Is64()) {
     return Replace(
         graph()->NewNode(machine()->Word64Shl(),
                          graph()->NewNode(machine()->ChangeInt32ToInt64(), val),
@@ -219,7 +219,7 @@ Reduction ChangeLowering::ChangeUint32ToTagged(Node* val, Node* control) {
   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
   Node* smi = graph()->NewNode(
       machine()->WordShl(),
-      machine()->is64()
+      machine()->Is64()
           ? graph()->NewNode(machine()->ChangeUint32ToUint64(), val)
           : val,
       SmiShiftBitsConstant());
index 85ab3dc..f7faa6d 100644 (file)
@@ -428,20 +428,20 @@ class IsCallMatcher FINAL : public NodeMatcher {
 
 class IsLoadMatcher FINAL : public NodeMatcher {
  public:
-  IsLoadMatcher(const Matcher<MachineType>& type_matcher,
+  IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
                 const Matcher<Node*>& base_matcher,
                 const Matcher<Node*>& index_matcher,
                 const Matcher<Node*>& effect_matcher)
       : NodeMatcher(IrOpcode::kLoad),
-        type_matcher_(type_matcher),
+        rep_matcher_(rep_matcher),
         base_matcher_(base_matcher),
         index_matcher_(index_matcher),
         effect_matcher_(effect_matcher) {}
 
   virtual void DescribeTo(std::ostream* os) const OVERRIDE {
     NodeMatcher::DescribeTo(os);
-    *os << " whose type (";
-    type_matcher_.DescribeTo(os);
+    *os << " whose rep (";
+    rep_matcher_.DescribeTo(os);
     *os << "), base (";
     base_matcher_.DescribeTo(os);
     *os << "), index (";
@@ -454,8 +454,8 @@ class IsLoadMatcher FINAL : public NodeMatcher {
   virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
       OVERRIDE {
     return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
-                                 type_matcher_, listener) &&
+            PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
+                                 rep_matcher_, listener) &&
             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
                                  base_matcher_, listener) &&
             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
@@ -465,7 +465,7 @@ class IsLoadMatcher FINAL : public NodeMatcher {
   }
 
  private:
-  const Matcher<MachineType> type_matcher_;
+  const Matcher<LoadRepresentation> rep_matcher_;
   const Matcher<Node*> base_matcher_;
   const Matcher<Node*> index_matcher_;
   const Matcher<Node*> effect_matcher_;
@@ -513,10 +513,10 @@ class IsStoreMatcher FINAL : public NodeMatcher {
       OVERRIDE {
     return (NodeMatcher::MatchAndExplain(node, listener) &&
             PrintMatchAndExplain(
-                OpParameter<StoreRepresentation>(node).machine_type, "type",
+                OpParameter<StoreRepresentation>(node).machine_type(), "type",
                 type_matcher_, listener) &&
             PrintMatchAndExplain(
-                OpParameter<StoreRepresentation>(node).write_barrier_kind,
+                OpParameter<StoreRepresentation>(node).write_barrier_kind(),
                 "write barrier", write_barrier_matcher_, listener) &&
             PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
                                  base_matcher_, listener) &&
@@ -704,12 +704,12 @@ Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
 }
 
 
-Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
+Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_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));
+  return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
+                                       effect_matcher));
 }
 
 
index 761343c..42e4dd9 100644 (file)
@@ -83,7 +83,7 @@ Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
                       const Matcher<Node*>& effect_matcher,
                       const Matcher<Node*>& control_matcher);
 
-Matcher<Node*> IsLoad(const Matcher<MachineType>& type_matcher,
+Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
                       const Matcher<Node*>& base_matcher,
                       const Matcher<Node*>& index_matcher,
                       const Matcher<Node*>& effect_matcher);
index 8a63ec6..eb3752c 100644 (file)
@@ -41,8 +41,8 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
+  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
   IA32OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -98,8 +98,8 @@ void InstructionSelector::VisitStore(Node* node) {
   Node* value = node->InputAt(2);
 
   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type);
-  if (store_rep.write_barrier_kind == kFullWriteBarrier) {
+  MachineType rep = RepresentationOf(store_rep.machine_type());
+  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
     DCHECK_EQ(kRepTagged, rep);
     // TODO(dcarney): refactor RecordWrite function to take temp registers
     //                and pass them here instead of using fixed regs
@@ -110,7 +110,7 @@ void InstructionSelector::VisitStore(Node* node) {
          temps);
     return;
   }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind);
+  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
   InstructionOperand* val;
   if (g.CanBeImmediate(value)) {
     val = g.UseImmediate(value);
index 9d9d932..dec46b6 100644 (file)
@@ -488,8 +488,8 @@ void InstructionSelector::VisitNode(Node* node) {
     case IrOpcode::kStateValues:
       return;
     case IrOpcode::kLoad: {
-      MachineType load_rep = OpParameter<MachineType>(node);
-      MarkAsRepresentation(load_rep, node);
+      LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
+      MarkAsRepresentation(rep, node);
       return VisitLoad(node);
     }
     case IrOpcode::kStore:
index 5631e69..ea84818 100644 (file)
@@ -490,7 +490,8 @@ Node* JSGenericLowering::LowerJSStoreContext(Node* node) {
   }
   node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
   node->ReplaceInput(1, Int32Constant(Context::SlotOffset(access.index())));
-  PatchOperator(node, machine()->Store(kMachAnyTagged, kFullWriteBarrier));
+  PatchOperator(node, machine()->Store(StoreRepresentation(kMachAnyTagged,
+                                                           kFullWriteBarrier)));
   return node;
 }
 
index e2c464a..ebd2d85 100644 (file)
@@ -19,9 +19,7 @@ namespace compiler {
 class JSTypedLowering FINAL : public Reducer {
  public:
   explicit JSTypedLowering(JSGraph* jsgraph)
-      : jsgraph_(jsgraph),
-        simplified_(jsgraph->zone()),
-        machine_(jsgraph->zone()) {}
+      : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
   virtual ~JSTypedLowering();
 
   virtual Reduction Reduce(Node* node) OVERRIDE;
index fdf062e..a564b67 100644 (file)
@@ -15,7 +15,7 @@ namespace compiler {
 class MachineOperatorReducerTest : public GraphTest {
  public:
   explicit MachineOperatorReducerTest(int num_parameters = 2)
-      : GraphTest(num_parameters), machine_(zone()) {}
+      : GraphTest(num_parameters) {}
 
  protected:
   Reduction Reduce(Node* node) {
index 68e3f72..a873fa2 100644 (file)
@@ -15,7 +15,7 @@ namespace internal {
 namespace compiler {
 
 MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph)
-    : jsgraph_(jsgraph), machine_(jsgraph->zone()) {}
+    : jsgraph_(jsgraph) {}
 
 
 MachineOperatorReducer::~MachineOperatorReducer() {}
index dbf0b5b..5b34000 100644 (file)
 
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/operator-properties-inl.h"
-#include "src/test/test-utils.h"
+#include "testing/gtest-support.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-class MachineOperatorCommonTest
-    : public TestWithZone,
-      public ::testing::WithParamInterface<MachineType> {
- public:
-  MachineOperatorCommonTest() : machine_(NULL) {}
-  virtual ~MachineOperatorCommonTest() { EXPECT_EQ(NULL, machine_); }
-
-  virtual void SetUp() OVERRIDE {
-    TestWithZone::SetUp();
-    EXPECT_EQ(NULL, machine_);
-    machine_ = new MachineOperatorBuilder(zone(), GetParam());
-  }
+#if GTEST_HAS_COMBINE
+
+// TODO(bmeurer): Find a new home for these.
+inline std::ostream& operator<<(std::ostream& os, const MachineType& type) {
+  OStringStream ost;
+  ost << type;
+  return os << ost.c_str();
+}
+inline std::ostream& operator<<(std::ostream& os,
+                         const WriteBarrierKind& write_barrier_kind) {
+  OStringStream ost;
+  ost << write_barrier_kind;
+  return os << ost.c_str();
+}
 
-  virtual void TearDown() OVERRIDE {
-    ASSERT_TRUE(machine_ != NULL);
-    delete machine_;
-    machine_ = NULL;
-    TestWithZone::TearDown();
-  }
 
+template <typename T>
+class MachineOperatorTestWithParam
+    : public ::testing::TestWithParam< ::testing::tuple<MachineType, T> > {
  protected:
-  MachineOperatorBuilder* machine() const { return machine_; }
+  MachineType type() const { return ::testing::get<0>(B::GetParam()); }
+  const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
 
  private:
-  MachineOperatorBuilder* machine_;
+  typedef ::testing::TestWithParam< ::testing::tuple<MachineType, T> > B;
 };
 
 
-TEST_P(MachineOperatorCommonTest, ChangeInt32ToInt64) {
-  const Operator* op = machine()->ChangeInt32ToInt64();
-  EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+namespace {
+
+const MachineType kMachineReps[] = {kRepWord32, kRepWord64};
+
+
+const MachineType kMachineTypes[] = {
+    kMachFloat32, kMachFloat64,   kMachInt8,   kMachUint8,  kMachInt16,
+    kMachUint16,  kMachInt32,     kMachUint32, kMachInt64,  kMachUint64,
+    kMachPtr,     kMachAnyTagged, kRepBit,     kRepWord8,   kRepWord16,
+    kRepWord32,   kRepWord64,     kRepFloat32, kRepFloat64, kRepTagged};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Load operator.
+
+
+typedef MachineOperatorTestWithParam<LoadRepresentation>
+    MachineLoadOperatorTest;
+
+
+TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
+  MachineOperatorBuilder machine1(type());
+  MachineOperatorBuilder machine2(type());
+  EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
 }
 
 
-TEST_P(MachineOperatorCommonTest, ChangeUint32ToUint64) {
-  const Operator* op = machine()->ChangeUint32ToUint64();
-  EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
+TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
+  MachineOperatorBuilder machine(type());
+  const Operator* op = machine.Load(GetParam());
+
+  EXPECT_EQ(2, OperatorProperties::GetValueInputCount(op));
+  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
+  EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
+  EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
+
   EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+  EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
+  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
 }
 
 
-TEST_P(MachineOperatorCommonTest, TruncateFloat64ToInt32) {
-  const Operator* op = machine()->TruncateFloat64ToInt32();
-  EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
+  MachineOperatorBuilder machine(type());
+  EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
+}
+
+
+TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
+  MachineOperatorBuilder machine(type());
+  EXPECT_EQ(GetParam(),
+            OpParameter<LoadRepresentation>(machine.Load(GetParam())));
 }
 
 
-TEST_P(MachineOperatorCommonTest, TruncateInt64ToInt32) {
-  const Operator* op = machine()->TruncateInt64ToInt32();
-  EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetTotalInputCount(op));
+INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineLoadOperatorTest,
+                        ::testing::Combine(::testing::ValuesIn(kMachineReps),
+                                           ::testing::ValuesIn(kMachineTypes)));
+
+
+// -----------------------------------------------------------------------------
+// Store operator.
+
+
+class MachineStoreOperatorTest
+    : public MachineOperatorTestWithParam<
+          ::testing::tuple<MachineType, WriteBarrierKind> > {
+ protected:
+  StoreRepresentation GetParam() const {
+    return StoreRepresentation(
+        ::testing::get<0>(MachineOperatorTestWithParam<
+            ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()),
+        ::testing::get<1>(MachineOperatorTestWithParam<
+            ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()));
+  }
+};
+
+
+TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
+  MachineOperatorBuilder machine1(type());
+  MachineOperatorBuilder machine2(type());
+  EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
+}
+
+
+TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
+  MachineOperatorBuilder machine(type());
+  const Operator* op = machine.Store(GetParam());
+
+  EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
+  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
+  EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
+  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
+  EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
   EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+}
+
+
+TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
+  MachineOperatorBuilder machine(type());
+  EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
+}
+
+
+TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
+  MachineOperatorBuilder machine(type());
+  EXPECT_EQ(GetParam(),
+            OpParameter<StoreRepresentation>(machine.Store(GetParam())));
+}
+
+
+INSTANTIATE_TEST_CASE_P(
+    MachineOperatorTest, MachineStoreOperatorTest,
+    ::testing::Combine(
+        ::testing::ValuesIn(kMachineReps),
+        ::testing::Combine(::testing::ValuesIn(kMachineTypes),
+                           ::testing::Values(kNoWriteBarrier,
+                                             kFullWriteBarrier))));
+
+
+// -----------------------------------------------------------------------------
+// Pure operators.
+
+
+namespace {
+
+struct PureOperator {
+  const Operator* (MachineOperatorBuilder::*constructor)();
+  IrOpcode::Value opcode;
+  int value_input_count;
+  int value_output_count;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
+  return os << IrOpcode::Mnemonic(pop.opcode);
+}
+
+
+const PureOperator kPureOperators[] = {
+#define PURE(Name, input_count, output_count)                      \
+  {                                                                \
+    &MachineOperatorBuilder::Name, IrOpcode::k##Name, input_count, \
+        output_count                                               \
+  }
+    PURE(Word32And, 2, 1),             PURE(Word32Or, 2, 1),
+    PURE(Word32Xor, 2, 1),             PURE(Word32Shl, 2, 1),
+    PURE(Word32Shr, 2, 1),             PURE(Word32Sar, 2, 1),
+    PURE(Word32Ror, 2, 1),             PURE(Word32Equal, 2, 1),
+    PURE(Word64And, 2, 1),             PURE(Word64Or, 2, 1),
+    PURE(Word64Xor, 2, 1),             PURE(Word64Shl, 2, 1),
+    PURE(Word64Shr, 2, 1),             PURE(Word64Sar, 2, 1),
+    PURE(Word64Ror, 2, 1),             PURE(Word64Equal, 2, 1),
+    PURE(Int32Add, 2, 1),              PURE(Int32AddWithOverflow, 2, 2),
+    PURE(Int32Sub, 2, 1),              PURE(Int32SubWithOverflow, 2, 2),
+    PURE(Int32Mul, 2, 1),              PURE(Int32Div, 2, 1),
+    PURE(Int32UDiv, 2, 1),             PURE(Int32Mod, 2, 1),
+    PURE(Int32UMod, 2, 1),             PURE(Int32LessThan, 2, 1),
+    PURE(Int32LessThanOrEqual, 2, 1),  PURE(Uint32LessThan, 2, 1),
+    PURE(Uint32LessThanOrEqual, 2, 1), PURE(Int64Add, 2, 1),
+    PURE(Int64Sub, 2, 1),              PURE(Int64Mul, 2, 1),
+    PURE(Int64Div, 2, 1),              PURE(Int64UDiv, 2, 1),
+    PURE(Int64Mod, 2, 1),              PURE(Int64UMod, 2, 1),
+    PURE(Int64LessThan, 2, 1),         PURE(Int64LessThanOrEqual, 2, 1),
+    PURE(ChangeFloat64ToInt32, 1, 1),  PURE(ChangeFloat64ToUint32, 1, 1),
+    PURE(ChangeInt32ToInt64, 1, 1),    PURE(ChangeUint32ToFloat64, 1, 1),
+    PURE(ChangeUint32ToUint64, 1, 1),  PURE(TruncateFloat64ToInt32, 1, 1),
+    PURE(TruncateInt64ToInt32, 1, 1),  PURE(Float64Add, 2, 1),
+    PURE(Float64Sub, 2, 1),            PURE(Float64Mul, 2, 1),
+    PURE(Float64Div, 2, 1),            PURE(Float64Mod, 2, 1),
+    PURE(Float64Equal, 2, 1),          PURE(Float64LessThan, 2, 1),
+    PURE(Float64LessThanOrEqual, 2, 1)
+#undef PURE
+};
+
+
+typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
+
+}  // namespace
+
+
+TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
+  const PureOperator& pop = GetParam();
+  MachineOperatorBuilder machine1(type());
+  MachineOperatorBuilder machine2(type());
+  EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
+}
+
+
+TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
+  MachineOperatorBuilder machine(type());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (machine.*pop.constructor)();
+
+  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetValueInputCount(op));
+  EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
+  EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
+  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(pop.value_output_count,
+            OperatorProperties::GetValueOutputCount(op));
   EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
+  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+}
+
+
+TEST_P(MachinePureOperatorTest, MarkedAsPure) {
+  MachineOperatorBuilder machine(type());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (machine.*pop.constructor)();
+  EXPECT_TRUE(op->HasProperty(Operator::kPure));
 }
 
 
-INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineOperatorCommonTest,
-                        ::testing::Values(kRepWord32, kRepWord64));
+TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
+  MachineOperatorBuilder machine(type());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (machine.*pop.constructor)();
+  EXPECT_EQ(pop.opcode, op->opcode());
+}
+
+
+INSTANTIATE_TEST_CASE_P(
+    MachineOperatorTest, MachinePureOperatorTest,
+    ::testing::Combine(::testing::ValuesIn(kMachineReps),
+                       ::testing::ValuesIn(kPureOperators)));
+
+#endif  // GTEST_HAS_COMBINE
+
+
+// -----------------------------------------------------------------------------
+// Pseudo operators.
+
+
+TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
+  MachineOperatorBuilder machine(kRepWord32);
+  EXPECT_EQ(machine.Word32And(), machine.WordAnd());
+  EXPECT_EQ(machine.Word32Or(), machine.WordOr());
+  EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
+  EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
+  EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
+  EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
+  EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
+  EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
+  EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
+  EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
+  EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
+  EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
+  EXPECT_EQ(machine.Int32UDiv(), machine.IntUDiv());
+  EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
+  EXPECT_EQ(machine.Int32UMod(), machine.IntUMod());
+  EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
+  EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
+}
+
+
+TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
+  MachineOperatorBuilder machine(kRepWord64);
+  EXPECT_EQ(machine.Word64And(), machine.WordAnd());
+  EXPECT_EQ(machine.Word64Or(), machine.WordOr());
+  EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
+  EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
+  EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
+  EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
+  EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
+  EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
+  EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
+  EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
+  EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
+  EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
+  EXPECT_EQ(machine.Int64UDiv(), machine.IntUDiv());
+  EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
+  EXPECT_EQ(machine.Int64UMod(), machine.IntUMod());
+  EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
+  EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
+}
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/machine-operator.cc b/src/compiler/machine-operator.cc
new file mode 100644 (file)
index 0000000..fb46a98
--- /dev/null
@@ -0,0 +1,241 @@
+// 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 "src/compiler/machine-operator.h"
+
+#include "src/base/lazy-instance.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+OStream& operator<<(OStream& os, const WriteBarrierKind& write_barrier_kind) {
+  switch (write_barrier_kind) {
+    case kNoWriteBarrier:
+      return os << "NoWriteBarrier";
+    case kFullWriteBarrier:
+      return os << "FullWriteBarrier";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+OStream& operator<<(OStream& os, const StoreRepresentation& rep) {
+  return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
+            << ")";
+}
+
+
+template <>
+struct StaticParameterTraits<StoreRepresentation> {
+  static OStream& PrintTo(OStream& os, const StoreRepresentation& rep) {
+    return os << rep;
+  }
+  static int HashCode(const StoreRepresentation& rep) {
+    return rep.machine_type() + rep.write_barrier_kind();
+  }
+  static bool Equals(const StoreRepresentation& rep1,
+                     const StoreRepresentation& rep2) {
+    return rep1 == rep2;
+  }
+};
+
+
+template <>
+struct StaticParameterTraits<LoadRepresentation> {
+  static OStream& PrintTo(OStream& os, LoadRepresentation type) {  // NOLINT
+    return os << type;
+  }
+  static int HashCode(LoadRepresentation type) { return type; }
+  static bool Equals(LoadRepresentation lhs, LoadRepresentation rhs) {
+    return lhs == rhs;
+  }
+};
+
+
+#define PURE_OP_LIST(V)                                                       \
+  V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
+  V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
+  V(Word32Shl, Operator::kNoProperties, 2, 1)                                 \
+  V(Word32Shr, Operator::kNoProperties, 2, 1)                                 \
+  V(Word32Sar, Operator::kNoProperties, 2, 1)                                 \
+  V(Word32Ror, Operator::kNoProperties, 2, 1)                                 \
+  V(Word32Equal, Operator::kCommutative, 2, 1)                                \
+  V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
+  V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
+  V(Word64Shl, Operator::kNoProperties, 2, 1)                                 \
+  V(Word64Shr, Operator::kNoProperties, 2, 1)                                 \
+  V(Word64Sar, Operator::kNoProperties, 2, 1)                                 \
+  V(Word64Ror, Operator::kNoProperties, 2, 1)                                 \
+  V(Word64Equal, Operator::kCommutative, 2, 1)                                \
+  V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
+    2)                                                                        \
+  V(Int32Sub, Operator::kNoProperties, 2, 1)                                  \
+  V(Int32SubWithOverflow, Operator::kNoProperties, 2, 2)                      \
+  V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Int32Div, Operator::kNoProperties, 2, 1)                                  \
+  V(Int32UDiv, Operator::kNoProperties, 2, 1)                                 \
+  V(Int32Mod, Operator::kNoProperties, 2, 1)                                  \
+  V(Int32UMod, Operator::kNoProperties, 2, 1)                                 \
+  V(Int32LessThan, Operator::kNoProperties, 2, 1)                             \
+  V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 1)                      \
+  V(Uint32LessThan, Operator::kNoProperties, 2, 1)                            \
+  V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 1)                     \
+  V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Int64Sub, Operator::kNoProperties, 2, 1)                                  \
+  V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Int64Div, Operator::kNoProperties, 2, 1)                                  \
+  V(Int64UDiv, Operator::kNoProperties, 2, 1)                                 \
+  V(Int64Mod, Operator::kNoProperties, 2, 1)                                  \
+  V(Int64UMod, Operator::kNoProperties, 2, 1)                                 \
+  V(Int64LessThan, Operator::kNoProperties, 2, 1)                             \
+  V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 1)                      \
+  V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 1)                      \
+  V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 1)                     \
+  V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 1)                      \
+  V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 1)                        \
+  V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 1)                     \
+  V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 1)                      \
+  V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 1)                    \
+  V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 1)                      \
+  V(Float64Add, Operator::kCommutative, 2, 1)                                 \
+  V(Float64Sub, Operator::kNoProperties, 2, 1)                                \
+  V(Float64Mul, Operator::kCommutative, 2, 1)                                 \
+  V(Float64Div, Operator::kNoProperties, 2, 1)                                \
+  V(Float64Mod, Operator::kNoProperties, 2, 1)                                \
+  V(Float64Equal, Operator::kCommutative, 2, 1)                               \
+  V(Float64LessThan, Operator::kNoProperties, 2, 1)                           \
+  V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 1)
+
+
+#define MACHINE_TYPE_LIST(V) \
+  V(MachFloat32)             \
+  V(MachFloat64)             \
+  V(MachInt8)                \
+  V(MachUint8)               \
+  V(MachInt16)               \
+  V(MachUint16)              \
+  V(MachInt32)               \
+  V(MachUint32)              \
+  V(MachInt64)               \
+  V(MachUint64)              \
+  V(MachAnyTagged)           \
+  V(RepBit)                  \
+  V(RepWord8)                \
+  V(RepWord16)               \
+  V(RepWord32)               \
+  V(RepWord64)               \
+  V(RepFloat32)              \
+  V(RepFloat64)              \
+  V(RepTagged)
+
+
+struct MachineOperatorBuilderImpl {
+#define PURE(Name, properties, input_count, output_count)                 \
+  struct Name##Operator FINAL : public SimpleOperator {                   \
+    Name##Operator()                                                      \
+        : SimpleOperator(IrOpcode::k##Name, Operator::kPure | properties, \
+                         input_count, output_count, #Name) {}             \
+  };                                                                      \
+  Name##Operator k##Name;
+  PURE_OP_LIST(PURE)
+#undef PURE
+
+#define LOAD(Type)                                                            \
+  struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> {  \
+    Load##Type##Operator()                                                    \
+        : Operator1<LoadRepresentation>(                                      \
+              IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, 2, 1, \
+              "Load", k##Type) {}                                             \
+  };                                                                          \
+  Load##Type##Operator k##Load##Type;
+  MACHINE_TYPE_LIST(LOAD)
+#undef LOAD
+
+#define STORE(Type)                                                           \
+  struct Store##Type##Operator : public Operator1<StoreRepresentation> {      \
+    explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind)       \
+        : Operator1<StoreRepresentation>(                                     \
+              IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, 3, 0, \
+              "Store", StoreRepresentation(k##Type, write_barrier_kind)) {}   \
+  };                                                                          \
+  struct Store##Type##NoWriteBarrier##Operator FINAL                          \
+      : public Store##Type##Operator {                                        \
+    Store##Type##NoWriteBarrier##Operator()                                   \
+        : Store##Type##Operator(kNoWriteBarrier) {}                           \
+  };                                                                          \
+  struct Store##Type##FullWriteBarrier##Operator FINAL                        \
+      : public Store##Type##Operator {                                        \
+    Store##Type##FullWriteBarrier##Operator()                                 \
+        : Store##Type##Operator(kFullWriteBarrier) {}                         \
+  };                                                                          \
+  Store##Type##NoWriteBarrier##Operator k##Store##Type##NoWriteBarrier;       \
+  Store##Type##FullWriteBarrier##Operator k##Store##Type##FullWriteBarrier;
+  MACHINE_TYPE_LIST(STORE)
+#undef STORE
+};
+
+
+static base::LazyInstance<MachineOperatorBuilderImpl>::type kImpl =
+    LAZY_INSTANCE_INITIALIZER;
+
+
+MachineOperatorBuilder::MachineOperatorBuilder(MachineType word)
+    : impl_(kImpl.Get()), word_(word) {
+  DCHECK(word == kRepWord32 || word == kRepWord64);
+}
+
+
+#define PURE(Name, properties, input_count, output_count) \
+  const Operator* MachineOperatorBuilder::Name() { return &impl_.k##Name; }
+PURE_OP_LIST(PURE)
+#undef PURE
+
+
+const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
+  switch (rep) {
+#define LOAD(Type) \
+  case k##Type:    \
+    return &impl_.k##Load##Type;
+    MACHINE_TYPE_LIST(LOAD)
+#undef LOAD
+
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
+  switch (rep.machine_type()) {
+#define STORE(Type)                                     \
+  case k##Type:                                         \
+    switch (rep.write_barrier_kind()) {                 \
+      case kNoWriteBarrier:                             \
+        return &impl_.k##Store##Type##NoWriteBarrier;   \
+      case kFullWriteBarrier:                           \
+        return &impl_.k##Store##Type##FullWriteBarrier; \
+    }                                                   \
+    break;
+    MACHINE_TYPE_LIST(STORE)
+#undef STORE
+
+    default:
+      break;
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
index 203fd96..6cfbfba 100644 (file)
 #define V8_COMPILER_MACHINE_OPERATOR_H_
 
 #include "src/compiler/machine-type.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
-#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// TODO(turbofan): other write barriers are possible based on type
+// Forward declarations.
+struct MachineOperatorBuilderImpl;
+class Operator;
+
+
+// Supported write barrier modes.
 enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
 
+OStream& operator<<(OStream& os, const WriteBarrierKind& write_barrier_kind);
+
+
+typedef MachineType LoadRepresentation;
+
 
 // A Store needs a MachineType and a WriteBarrierKind
 // in order to emit the correct write barrier.
-struct StoreRepresentation {
-  MachineType machine_type;
-  WriteBarrierKind write_barrier_kind;
-};
+class StoreRepresentation FINAL {
+ public:
+  StoreRepresentation(MachineType machine_type,
+                      WriteBarrierKind write_barrier_kind)
+      : machine_type_(machine_type), write_barrier_kind_(write_barrier_kind) {}
 
+  MachineType machine_type() const { return machine_type_; }
+  WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
 
-// TODO(bmeurer): Phi will probably also need this in the future.
-template <>
-struct StaticParameterTraits<MachineType> {
-  static OStream& PrintTo(OStream& os, MachineType type) {  // NOLINT
-    return os << type;
-  }
-  static int HashCode(MachineType type) { return type; }
-  static bool Equals(MachineType lhs, MachineType rhs) { return lhs == rhs; }
+ private:
+  MachineType machine_type_;
+  WriteBarrierKind write_barrier_kind_;
 };
 
+inline bool operator==(const StoreRepresentation& rep1,
+                       const StoreRepresentation& rep2) {
+  return rep1.machine_type() == rep2.machine_type() &&
+         rep1.write_barrier_kind() == rep2.write_barrier_kind();
+}
+
+inline bool operator!=(const StoreRepresentation& rep1,
+                       const StoreRepresentation& rep2) {
+  return !(rep1 == rep2);
+}
+
+OStream& operator<<(OStream& os, const StoreRepresentation& rep);
+
 
 // Interface for building machine-level operators. These operators are
 // machine-level but machine-independent and thus define a language suitable
 // for generating code to run on architectures such as ia32, x64, arm, etc.
-class MachineOperatorBuilder {
+class MachineOperatorBuilder FINAL {
  public:
-  explicit MachineOperatorBuilder(Zone* zone, MachineType word = kMachPtr)
-      : zone_(zone), word_(word) {
-    CHECK(word == kRepWord32 || word == kRepWord64);
-  }
-
-#define SIMPLE(name, properties, inputs, outputs) \
-  return new (zone_)                              \
-      SimpleOperator(IrOpcode::k##name, properties, inputs, outputs, #name);
-
-#define OP1(name, ptype, pname, properties, inputs, outputs)               \
-  return new (zone_)                                                       \
-      Operator1<ptype>(IrOpcode::k##name, properties | Operator::kNoThrow, \
-                       inputs, outputs, #name, pname)
-
-#define BINOP(name) SIMPLE(name, Operator::kPure, 2, 1)
-#define BINOP_O(name) SIMPLE(name, Operator::kPure, 2, 2)
-#define BINOP_C(name) \
-  SIMPLE(name, Operator::kCommutative | Operator::kPure, 2, 1)
-#define BINOP_AC(name)                                                         \
-  SIMPLE(name,                                                                 \
-         Operator::kAssociative | Operator::kCommutative | Operator::kPure, 2, \
-         1)
-#define BINOP_ACO(name)                                                        \
-  SIMPLE(name,                                                                 \
-         Operator::kAssociative | Operator::kCommutative | Operator::kPure, 2, \
-         2)
-#define UNOP(name) SIMPLE(name, Operator::kPure, 1, 1)
-
-#define WORD_SIZE(x) return is64() ? Word64##x() : Word32##x()
-#define INT_SIZE(x) return is64() ? Int64##x() : Int32##x()
-
-  const Operator* Load(MachineType rep) {  // load [base + index]
-    OP1(Load, MachineType, rep, Operator::kNoWrite, 2, 1);
-  }
-  // store [base + index], value
-  const Operator* Store(MachineType rep, WriteBarrierKind kind) {
-    StoreRepresentation store_rep = {rep, kind};
-    OP1(Store, StoreRepresentation, store_rep, Operator::kNoRead, 3, 0);
-  }
-
-  const Operator* WordAnd() { WORD_SIZE(And); }
-  const Operator* WordOr() { WORD_SIZE(Or); }
-  const Operator* WordXor() { WORD_SIZE(Xor); }
-  const Operator* WordShl() { WORD_SIZE(Shl); }
-  const Operator* WordShr() { WORD_SIZE(Shr); }
-  const Operator* WordSar() { WORD_SIZE(Sar); }
-  const Operator* WordRor() { WORD_SIZE(Ror); }
-  const Operator* WordEqual() { WORD_SIZE(Equal); }
-
-  const Operator* Word32And() { BINOP_AC(Word32And); }
-  const Operator* Word32Or() { BINOP_AC(Word32Or); }
-  const Operator* Word32Xor() { BINOP_AC(Word32Xor); }
-  const Operator* Word32Shl() { BINOP(Word32Shl); }
-  const Operator* Word32Shr() { BINOP(Word32Shr); }
-  const Operator* Word32Sar() { BINOP(Word32Sar); }
-  const Operator* Word32Ror() { BINOP(Word32Ror); }
-  const Operator* Word32Equal() { BINOP_C(Word32Equal); }
-
-  const Operator* Word64And() { BINOP_AC(Word64And); }
-  const Operator* Word64Or() { BINOP_AC(Word64Or); }
-  const Operator* Word64Xor() { BINOP_AC(Word64Xor); }
-  const Operator* Word64Shl() { BINOP(Word64Shl); }
-  const Operator* Word64Shr() { BINOP(Word64Shr); }
-  const Operator* Word64Sar() { BINOP(Word64Sar); }
-  const Operator* Word64Ror() { BINOP(Word64Ror); }
-  const Operator* Word64Equal() { BINOP_C(Word64Equal); }
-
-  const Operator* Int32Add() { BINOP_AC(Int32Add); }
-  const Operator* Int32AddWithOverflow() { BINOP_ACO(Int32AddWithOverflow); }
-  const Operator* Int32Sub() { BINOP(Int32Sub); }
-  const Operator* Int32SubWithOverflow() { BINOP_O(Int32SubWithOverflow); }
-  const Operator* Int32Mul() { BINOP_AC(Int32Mul); }
-  const Operator* Int32Div() { BINOP(Int32Div); }
-  const Operator* Int32UDiv() { BINOP(Int32UDiv); }
-  const Operator* Int32Mod() { BINOP(Int32Mod); }
-  const Operator* Int32UMod() { BINOP(Int32UMod); }
-  const Operator* Int32LessThan() { BINOP(Int32LessThan); }
-  const Operator* Int32LessThanOrEqual() { BINOP(Int32LessThanOrEqual); }
-  const Operator* Uint32LessThan() { BINOP(Uint32LessThan); }
-  const Operator* Uint32LessThanOrEqual() { BINOP(Uint32LessThanOrEqual); }
-
-  const Operator* Int64Add() { BINOP_AC(Int64Add); }
-  const Operator* Int64Sub() { BINOP(Int64Sub); }
-  const Operator* Int64Mul() { BINOP_AC(Int64Mul); }
-  const Operator* Int64Div() { BINOP(Int64Div); }
-  const Operator* Int64UDiv() { BINOP(Int64UDiv); }
-  const Operator* Int64Mod() { BINOP(Int64Mod); }
-  const Operator* Int64UMod() { BINOP(Int64UMod); }
-  const Operator* Int64LessThan() { BINOP(Int64LessThan); }
-  const Operator* Int64LessThanOrEqual() { BINOP(Int64LessThanOrEqual); }
-
-  // Signed comparison of word-sized integer values, translates to int32/int64
-  // comparisons depending on the word-size of the machine.
-  const Operator* IntLessThan() { INT_SIZE(LessThan); }
-  const Operator* IntLessThanOrEqual() { INT_SIZE(LessThanOrEqual); }
+  explicit MachineOperatorBuilder(MachineType word = kMachPtr);
+
+  const Operator* Word32And() WARN_UNUSED_RESULT;
+  const Operator* Word32Or() WARN_UNUSED_RESULT;
+  const Operator* Word32Xor() WARN_UNUSED_RESULT;
+  const Operator* Word32Shl() WARN_UNUSED_RESULT;
+  const Operator* Word32Shr() WARN_UNUSED_RESULT;
+  const Operator* Word32Sar() WARN_UNUSED_RESULT;
+  const Operator* Word32Ror() WARN_UNUSED_RESULT;
+  const Operator* Word32Equal() WARN_UNUSED_RESULT;
+
+  const Operator* Word64And() WARN_UNUSED_RESULT;
+  const Operator* Word64Or() WARN_UNUSED_RESULT;
+  const Operator* Word64Xor() WARN_UNUSED_RESULT;
+  const Operator* Word64Shl() WARN_UNUSED_RESULT;
+  const Operator* Word64Shr() WARN_UNUSED_RESULT;
+  const Operator* Word64Sar() WARN_UNUSED_RESULT;
+  const Operator* Word64Ror() WARN_UNUSED_RESULT;
+  const Operator* Word64Equal() WARN_UNUSED_RESULT;
+
+  const Operator* Int32Add() WARN_UNUSED_RESULT;
+  const Operator* Int32AddWithOverflow() WARN_UNUSED_RESULT;
+  const Operator* Int32Sub() WARN_UNUSED_RESULT;
+  const Operator* Int32SubWithOverflow() WARN_UNUSED_RESULT;
+  const Operator* Int32Mul() WARN_UNUSED_RESULT;
+  const Operator* Int32Div() WARN_UNUSED_RESULT;
+  const Operator* Int32UDiv() WARN_UNUSED_RESULT;
+  const Operator* Int32Mod() WARN_UNUSED_RESULT;
+  const Operator* Int32UMod() WARN_UNUSED_RESULT;
+  const Operator* Int32LessThan() WARN_UNUSED_RESULT;
+  const Operator* Int32LessThanOrEqual() WARN_UNUSED_RESULT;
+  const Operator* Uint32LessThan() WARN_UNUSED_RESULT;
+  const Operator* Uint32LessThanOrEqual() WARN_UNUSED_RESULT;
+
+  const Operator* Int64Add() WARN_UNUSED_RESULT;
+  const Operator* Int64Sub() WARN_UNUSED_RESULT;
+  const Operator* Int64Mul() WARN_UNUSED_RESULT;
+  const Operator* Int64Div() WARN_UNUSED_RESULT;
+  const Operator* Int64UDiv() WARN_UNUSED_RESULT;
+  const Operator* Int64Mod() WARN_UNUSED_RESULT;
+  const Operator* Int64UMod() WARN_UNUSED_RESULT;
+  const Operator* Int64LessThan() WARN_UNUSED_RESULT;
+  const Operator* Int64LessThanOrEqual() WARN_UNUSED_RESULT;
 
   // Convert representation of integers between float64 and int32/uint32.
   // The precise rounding mode and handling of out of range inputs are *not*
   // defined for these operators, since they are intended only for use with
   // integers.
-  const Operator* ChangeInt32ToFloat64() { UNOP(ChangeInt32ToFloat64); }
-  const Operator* ChangeUint32ToFloat64() { UNOP(ChangeUint32ToFloat64); }
-  const Operator* ChangeFloat64ToInt32() { UNOP(ChangeFloat64ToInt32); }
-  const Operator* ChangeFloat64ToUint32() { UNOP(ChangeFloat64ToUint32); }
+  const Operator* ChangeInt32ToFloat64() WARN_UNUSED_RESULT;
+  const Operator* ChangeUint32ToFloat64() WARN_UNUSED_RESULT;
+  const Operator* ChangeFloat64ToInt32() WARN_UNUSED_RESULT;
+  const Operator* ChangeFloat64ToUint32() WARN_UNUSED_RESULT;
 
   // Sign/zero extend int32/uint32 to int64/uint64.
-  const Operator* ChangeInt32ToInt64() { UNOP(ChangeInt32ToInt64); }
-  const Operator* ChangeUint32ToUint64() { UNOP(ChangeUint32ToUint64); }
+  const Operator* ChangeInt32ToInt64() WARN_UNUSED_RESULT;
+  const Operator* ChangeUint32ToUint64() WARN_UNUSED_RESULT;
 
   // Truncate double to int32 using JavaScript semantics.
-  const Operator* TruncateFloat64ToInt32() { UNOP(TruncateFloat64ToInt32); }
+  const Operator* TruncateFloat64ToInt32() WARN_UNUSED_RESULT;
 
   // Truncate the high order bits and convert the remaining bits to int32.
-  const Operator* TruncateInt64ToInt32() { UNOP(TruncateInt64ToInt32); }
+  const Operator* TruncateInt64ToInt32() WARN_UNUSED_RESULT;
 
   // Floating point operators always operate with IEEE 754 round-to-nearest.
-  const Operator* Float64Add() { BINOP_C(Float64Add); }
-  const Operator* Float64Sub() { BINOP(Float64Sub); }
-  const Operator* Float64Mul() { BINOP_C(Float64Mul); }
-  const Operator* Float64Div() { BINOP(Float64Div); }
-  const Operator* Float64Mod() { BINOP(Float64Mod); }
+  const Operator* Float64Add() WARN_UNUSED_RESULT;
+  const Operator* Float64Sub() WARN_UNUSED_RESULT;
+  const Operator* Float64Mul() WARN_UNUSED_RESULT;
+  const Operator* Float64Div() WARN_UNUSED_RESULT;
+  const Operator* Float64Mod() WARN_UNUSED_RESULT;
 
   // Floating point comparisons complying to IEEE 754.
-  const Operator* Float64Equal() { BINOP_C(Float64Equal); }
-  const Operator* Float64LessThan() { BINOP(Float64LessThan); }
-  const Operator* Float64LessThanOrEqual() { BINOP(Float64LessThanOrEqual); }
+  const Operator* Float64Equal() WARN_UNUSED_RESULT;
+  const Operator* Float64LessThan() WARN_UNUSED_RESULT;
+  const Operator* Float64LessThanOrEqual() WARN_UNUSED_RESULT;
 
-  inline bool is32() const { return word_ == kRepWord32; }
-  inline bool is64() const { return word_ == kRepWord64; }
-  inline MachineType word() const { return word_; }
+  // load [base + index]
+  const Operator* Load(LoadRepresentation rep) WARN_UNUSED_RESULT;
 
-#undef WORD_SIZE
-#undef INT_SIZE
-#undef UNOP
-#undef BINOP
-#undef OP1
-#undef SIMPLE
+  // store [base + index], value
+  const Operator* Store(StoreRepresentation rep) WARN_UNUSED_RESULT;
+
+  // Target machine word-size assumed by this builder.
+  bool Is32() const { return word() == kRepWord32; }
+  bool Is64() const { return word() == kRepWord64; }
+  MachineType word() const { return word_; }
+
+// Pseudo operators that translate to 32/64-bit operators depending on the
+// word-size of the target machine assumed by this builder.
+#define PSEUDO_OP_LIST(V) \
+  V(Word, And)            \
+  V(Word, Or)             \
+  V(Word, Xor)            \
+  V(Word, Shl)            \
+  V(Word, Shr)            \
+  V(Word, Sar)            \
+  V(Word, Ror)            \
+  V(Word, Equal)          \
+  V(Int, Add)             \
+  V(Int, Sub)             \
+  V(Int, Mul)             \
+  V(Int, Div)             \
+  V(Int, UDiv)            \
+  V(Int, Mod)             \
+  V(Int, UMod)            \
+  V(Int, LessThan)        \
+  V(Int, LessThanOrEqual)
+#define PSEUDO_OP(Prefix, Suffix)                                \
+  const Operator* Prefix##Suffix() {                             \
+    return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
+  }
+  PSEUDO_OP_LIST(PSEUDO_OP)
+#undef PSEUDO_OP
+#undef PSEUDO_OP_LIST
 
  private:
-  Zone* zone_;
-  MachineType word_;
+  const MachineOperatorBuilderImpl& impl_;
+  const MachineType word_;
 };
 
 }  // namespace compiler
index 771350b..88b482c 100644 (file)
@@ -36,7 +36,22 @@ enum MachineType {
   kTypeInt64 = 1 << 11,
   kTypeUint64 = 1 << 12,
   kTypeNumber = 1 << 13,
-  kTypeAny = 1 << 14
+  kTypeAny = 1 << 14,
+
+  // Machine types.
+  kMachNone = 0,
+  kMachFloat32 = kRepFloat32 | kTypeNumber,
+  kMachFloat64 = kRepFloat64 | kTypeNumber,
+  kMachInt8 = kRepWord8 | kTypeInt32,
+  kMachUint8 = kRepWord8 | kTypeUint32,
+  kMachInt16 = kRepWord16 | kTypeInt32,
+  kMachUint16 = kRepWord16 | kTypeUint32,
+  kMachInt32 = kRepWord32 | kTypeInt32,
+  kMachUint32 = kRepWord32 | kTypeUint32,
+  kMachInt64 = kRepWord64 | kTypeInt64,
+  kMachUint64 = kRepWord64 | kTypeUint64,
+  kMachPtr = (kPointerSize == 4) ? kRepWord32 : kRepWord64,
+  kMachAnyTagged = kRepTagged | kTypeAny
 };
 
 OStream& operator<<(OStream& os, const MachineType& type);
@@ -51,30 +66,6 @@ const MachineTypeUnion kTypeMask = kTypeBool | kTypeInt32 | kTypeUint32 |
                                    kTypeInt64 | kTypeUint64 | kTypeNumber |
                                    kTypeAny;
 
-const MachineType kMachNone = static_cast<MachineType>(0);
-const MachineType kMachFloat32 =
-    static_cast<MachineType>(kRepFloat32 | kTypeNumber);
-const MachineType kMachFloat64 =
-    static_cast<MachineType>(kRepFloat64 | kTypeNumber);
-const MachineType kMachInt8 = static_cast<MachineType>(kRepWord8 | kTypeInt32);
-const MachineType kMachUint8 =
-    static_cast<MachineType>(kRepWord8 | kTypeUint32);
-const MachineType kMachInt16 =
-    static_cast<MachineType>(kRepWord16 | kTypeInt32);
-const MachineType kMachUint16 =
-    static_cast<MachineType>(kRepWord16 | kTypeUint32);
-const MachineType kMachInt32 =
-    static_cast<MachineType>(kRepWord32 | kTypeInt32);
-const MachineType kMachUint32 =
-    static_cast<MachineType>(kRepWord32 | kTypeUint32);
-const MachineType kMachInt64 =
-    static_cast<MachineType>(kRepWord64 | kTypeInt64);
-const MachineType kMachUint64 =
-    static_cast<MachineType>(kRepWord64 | kTypeUint64);
-const MachineType kMachPtr = kPointerSize == 4 ? kRepWord32 : kRepWord64;
-const MachineType kMachAnyTagged =
-    static_cast<MachineType>(kRepTagged | kTypeAny);
-
 // Gets only the type of the given type.
 inline MachineType TypeOf(MachineType machine_type) {
   int result = machine_type & kTypeMask;
index 395cac8..8d17bc4 100644 (file)
@@ -110,21 +110,21 @@ OStream& operator<<(OStream& os, const Operator& op);
 // An implementation of Operator that has no static parameters. Such operators
 // have just a name, an opcode, and a fixed number of inputs and outputs.
 // They can represented by singletons and shared globally.
-class SimpleOperator FINAL : public Operator {
+class SimpleOperator : public Operator {
  public:
   SimpleOperator(Opcode opcode, Properties properties, int input_count,
                  int output_count, const char* mnemonic);
   ~SimpleOperator();
 
-  virtual bool Equals(const Operator* that) const OVERRIDE {
+  virtual bool Equals(const Operator* that) const FINAL {
     return opcode() == that->opcode();
   }
-  virtual int HashCode() const OVERRIDE { return opcode(); }
-  virtual int InputCount() const OVERRIDE { return input_count_; }
-  virtual int OutputCount() const OVERRIDE { return output_count_; }
+  virtual int HashCode() const FINAL { return opcode(); }
+  virtual int InputCount() const FINAL { return input_count_; }
+  virtual int OutputCount() const FINAL { return output_count_; }
 
  private:
-  virtual OStream& PrintTo(OStream& os) const OVERRIDE {  // NOLINT
+  virtual OStream& PrintTo(OStream& os) const FINAL {  // NOLINT
     return os << mnemonic();
   }
 
@@ -260,9 +260,6 @@ class Operator1 : public Operator {
   T parameter_;
 };
 
-// Type definitions for operators with specific types of parameters.
-typedef Operator1<Unique<Name> > NameOperator;
-
 
 // Helper to extract parameters from Operator1<*> operator.
 template <typename T>
index 6b5fdcf..6edfb3f 100644 (file)
@@ -169,6 +169,7 @@ Handle<Code> Pipeline::GenerateCode() {
   // construction.  This is currently only needed for the node cache, which the
   // typer could sweep over later.
   Typer typer(zone());
+  MachineOperatorBuilder machine;
   CommonOperatorBuilder common(zone());
   JSGraph jsgraph(&graph, &common, &typer);
   Node* context_node;
@@ -256,7 +257,6 @@ Handle<Code> Pipeline::GenerateCode() {
       SourcePositionTable::Scope pos(&source_positions,
                                      SourcePosition::Unknown());
       Linkage linkage(info());
-      MachineOperatorBuilder machine(zone());
       ValueNumberingReducer vn_reducer(zone());
       SimplifiedOperatorReducer simple_reducer(&jsgraph, &machine);
       ChangeLowering lowering(&jsgraph, &linkage, &machine);
@@ -281,7 +281,6 @@ Handle<Code> Pipeline::GenerateCode() {
                                 "generic lowering");
       SourcePositionTable::Scope pos(&source_positions,
                                      SourcePosition::Unknown());
-      MachineOperatorBuilder machine(zone());
       JSGenericLowering lowering(info(), &jsgraph, &machine);
       GraphReducer graph_reducer(&graph);
       graph_reducer.AddReducer(&lowering);
index 9e150aa..19f51d4 100644 (file)
@@ -15,7 +15,7 @@ RawMachineAssembler::RawMachineAssembler(Graph* graph,
                                          MachineType word)
     : GraphBuilder(graph),
       schedule_(new (zone()) Schedule(zone())),
-      machine_(zone(), word),
+      machine_(word),
       common_(zone()),
       machine_sig_(machine_sig),
       call_descriptor_(
index 135d401..cb0302b 100644 (file)
@@ -108,7 +108,8 @@ class RawMachineAssembler : public GraphBuilder {
     Store(rep, base, Int32Constant(0), value);
   }
   void Store(MachineType rep, Node* base, Node* index, Node* value) {
-    NewNode(machine()->Store(rep, kNoWriteBarrier), base, index, value);
+    NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
+            index, value);
   }
   // Arithmetic Operations.
   Node* WordAnd(Node* a, Node* b) {
@@ -137,14 +138,14 @@ class RawMachineAssembler : public GraphBuilder {
     return WordBinaryNot(WordEqual(a, b));
   }
   Node* WordNot(Node* a) {
-    if (machine()->is32()) {
+    if (machine()->Is32()) {
       return Word32Not(a);
     } else {
       return Word64Not(a);
     }
   }
   Node* WordBinaryNot(Node* a) {
-    if (machine()->is32()) {
+    if (machine()->Is32()) {
       return Word32BinaryNot(a);
     } else {
       return Word64BinaryNot(a);
index 27212f7..023c843 100644 (file)
@@ -590,11 +590,11 @@ class RepresentationSelector {
       case IrOpcode::kLoad: {
         // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
         MachineType tBase = kRepTagged;
-        MachineType machine_type = OpParameter<MachineType>(node);
+        LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
         ProcessInput(node, 0, tBase);   // pointer or object
         ProcessInput(node, 1, kMachInt32);  // index
         ProcessRemainingInputs(node, 2);
-        SetOutput(node, machine_type);
+        SetOutput(node, rep);
         break;
       }
       case IrOpcode::kStore: {
@@ -603,7 +603,7 @@ class RepresentationSelector {
         StoreRepresentation rep = OpParameter<StoreRepresentation>(node);
         ProcessInput(node, 0, tBase);   // pointer or object
         ProcessInput(node, 1, kMachInt32);  // index
-        ProcessInput(node, 2, rep.machine_type);
+        ProcessInput(node, 2, rep.machine_type());
         ProcessRemainingInputs(node, 3);
         SetOutput(node, 0);
         break;
@@ -814,7 +814,7 @@ void SimplifiedLowering::DoStoreField(Node* node) {
   const FieldAccess& access = FieldAccessOf(node->op());
   WriteBarrierKind kind = ComputeWriteBarrierKind(
       access.base_is_tagged, access.machine_type, access.type);
-  node->set_op(machine_.Store(access.machine_type, kind));
+  node->set_op(machine_.Store(StoreRepresentation(access.machine_type, kind)));
   Node* offset = jsgraph()->Int32Constant(access.offset - access.tag());
   node->InsertInput(zone(), 1, offset);
 }
@@ -845,7 +845,7 @@ void SimplifiedLowering::DoStoreElement(Node* node) {
   const ElementAccess& access = ElementAccessOf(node->op());
   WriteBarrierKind kind = ComputeWriteBarrierKind(
       access.base_is_tagged, access.machine_type, access.type);
-  node->set_op(machine_.Store(access.machine_type, kind));
+  node->set_op(machine_.Store(StoreRepresentation(access.machine_type, kind)));
   node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
 }
 
index 94766f7..9e83fdf 100644 (file)
@@ -16,8 +16,7 @@ namespace compiler {
 
 class SimplifiedLowering {
  public:
-  explicit SimplifiedLowering(JSGraph* jsgraph)
-      : jsgraph_(jsgraph), machine_(jsgraph->zone()) {}
+  explicit SimplifiedLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
   virtual ~SimplifiedLowering() {}
 
   void LowerAllNodes();
index 2ea4f47..9ab8109 100644 (file)
@@ -22,7 +22,7 @@ class SimplifiedOperatorReducerTest : public GraphTest {
  protected:
   Reduction Reduce(Node* node) {
     Typer typer(zone());
-    MachineOperatorBuilder machine(zone());
+    MachineOperatorBuilder machine;
     JSGraph jsgraph(graph(), common(), &typer);
     SimplifiedOperatorReducer reducer(&jsgraph, &machine);
     return reducer.Reduce(node);
index a4ff635..b56b632 100644 (file)
@@ -7,6 +7,8 @@
 
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+#include "src/handles.h"
 #include "src/zone.h"
 
 namespace v8 {
index efde91b..8d41fa1 100644 (file)
@@ -56,8 +56,8 @@ class X64OperandGenerator FINAL : public OperandGenerator {
 
 
 void InstructionSelector::VisitLoad(Node* node) {
-  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
-  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
+  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
   X64OperandGenerator g(this);
   Node* base = node->InputAt(0);
   Node* index = node->InputAt(1);
@@ -111,8 +111,8 @@ void InstructionSelector::VisitStore(Node* node) {
   Node* value = node->InputAt(2);
 
   StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
-  MachineType rep = RepresentationOf(store_rep.machine_type);
-  if (store_rep.write_barrier_kind == kFullWriteBarrier) {
+  MachineType rep = RepresentationOf(store_rep.machine_type());
+  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
     DCHECK(rep == kRepTagged);
     // TODO(dcarney): refactor RecordWrite function to take temp registers
     //                and pass them here instead of using fixed regs
@@ -123,7 +123,7 @@ void InstructionSelector::VisitStore(Node* node) {
          temps);
     return;
   }
-  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind);
+  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
   InstructionOperand* val;
   if (g.CanBeImmediate(value)) {
     val = g.UseImmediate(value);
index fcb6e3d..619c3c9 100644 (file)
@@ -5,8 +5,8 @@
 #ifndef V8_HYDROGEN_UNIQUE_H_
 #define V8_HYDROGEN_UNIQUE_H_
 
-#include "src/handles.h"
-#include "src/objects.h"
+#include "src/handles-inl.h"  // TODO(everyone): Fix our inl.h crap
+#include "src/objects-inl.h"  // TODO(everyone): Fix our inl.h crap
 #include "src/string-stream.h"
 #include "src/utils.h"
 #include "src/zone.h"
index 3fba64c..df79250 100644 (file)
@@ -61,7 +61,6 @@ class GraphAndBuilders {
   explicit GraphAndBuilders(Zone* zone)
       : main_graph_(new (zone) Graph(zone)),
         main_common_(zone),
-        main_machine_(zone),
         main_simplified_(zone) {}
 
  protected:
index 2537091..396cc5d 100644 (file)
@@ -222,9 +222,10 @@ TEST(RunChangeTaggedToFloat64) {
   ChangesLoweringTester<int32_t> t(kMachAnyTagged);
   double result;
 
-  t.BuildStoreAndLower(t.simplified()->ChangeTaggedToFloat64(),
-                       t.machine()->Store(kMachFloat64, kNoWriteBarrier),
-                       &result);
+  t.BuildStoreAndLower(
+      t.simplified()->ChangeTaggedToFloat64(),
+      t.machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
+      &result);
 
   if (Pipeline::SupportedTarget()) {
     FOR_INT32_INPUTS(i) {
index e071d23..08e44ec 100644 (file)
@@ -32,7 +32,6 @@ class InstructionTester : public HandleAndZoneScope {
         info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
         linkage(&info),
         common(zone()),
-        machine(zone()),
         code(NULL) {}
 
   ~InstructionTester() { delete code; }
index 5259d70..a7ffc67 100644 (file)
@@ -21,7 +21,6 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
         binop(NULL),
         unop(NULL),
         javascript(main_zone()),
-        machine(main_zone()),
         simplified(main_zone()),
         common(main_zone()),
         graph(main_zone()),
index 45b63b1..569fe87 100644 (file)
@@ -53,7 +53,6 @@ class ReducerTester : public HandleAndZoneScope {
       : isolate(main_isolate()),
         binop(NULL),
         unop(NULL),
-        machine(main_zone()),
         common(main_zone()),
         graph(main_zone()),
         typer(main_zone()),
@@ -667,8 +666,9 @@ TEST(ReduceLoadStore) {
   }
 
   {
-    Node* store = R.graph.NewNode(R.machine.Store(kMachInt32, kNoWriteBarrier),
-                                  base, index, load);
+    Node* store = R.graph.NewNode(
+        R.machine.Store(StoreRepresentation(kMachInt32, kNoWriteBarrier)), base,
+        index, load);
     MachineOperatorReducer reducer(&R.jsgraph);
     Reduction reduction = reducer.Reduce(store);
     CHECK(!reduction.Changed());  // stores should not be reduced.
index cad686a..6c05c05 100644 (file)
@@ -131,7 +131,7 @@ TEST(BuildMulNodeGraph) {
   Schedule schedule(scope.main_zone());
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
-  MachineOperatorBuilder machine(scope.main_zone());
+  MachineOperatorBuilder machine;
 
   Node* start = graph.NewNode(common.Start(0));
   graph.SetStart(start);
index 9c0d38f..cf33123 100644 (file)
@@ -1509,7 +1509,7 @@ TEST(BuildScheduleSimpleLoopWithCodeMotion) {
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common_builder(scope.main_zone());
   JSOperatorBuilder js_builder(scope.main_zone());
-  MachineOperatorBuilder machine_builder(scope.main_zone());
+  MachineOperatorBuilder machine_builder;
   const Operator* op;
 
   Handle<Object> object =
@@ -1668,7 +1668,7 @@ TEST(FloatingDiamond2) {
   HandleAndZoneScope scope;
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
-  MachineOperatorBuilder machine(scope.main_zone());
+  MachineOperatorBuilder machine;
 
   Node* start = graph.NewNode(common.Start(2));
   graph.SetStart(start);
@@ -1691,7 +1691,7 @@ TEST(FloatingDiamond3) {
   HandleAndZoneScope scope;
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
-  MachineOperatorBuilder machine(scope.main_zone());
+  MachineOperatorBuilder machine;
 
   Node* start = graph.NewNode(common.Start(2));
   graph.SetStart(start);
index 27db0a5..4119402 100644 (file)
@@ -1265,9 +1265,9 @@ TEST(LowerStoreField_to_store) {
 
     StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
     if (machine_reps[i] & kRepTagged) {
-      CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind);
+      CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
     }
-    CHECK_EQ(machine_reps[i], rep.machine_type);
+    CHECK_EQ(machine_reps[i], rep.machine_type());
   }
 }
 
@@ -1312,9 +1312,9 @@ TEST(LowerStoreElement_to_store) {
 
     StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
     if (machine_reps[i] & kRepTagged) {
-      CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind);
+      CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
     }
-    CHECK_EQ(machine_reps[i], rep.machine_type);
+    CHECK_EQ(machine_reps[i], rep.machine_type());
   }
 }
 
index 6a4fd90..1641138 100644 (file)
         '../../src/compiler/linkage.h',
         '../../src/compiler/machine-operator-reducer.cc',
         '../../src/compiler/machine-operator-reducer.h',
+        '../../src/compiler/machine-operator.cc',
         '../../src/compiler/machine-operator.h',
         '../../src/compiler/machine-type.cc',
         '../../src/compiler/machine-type.h',