From bfa3884ae0c84faa695b5ae24de598c1e0cc3ec9 Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Thu, 11 Sep 2014 10:37:49 +0000 Subject: [PATCH] [turbofan] Machine operators are globally shared singletons. 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 --- BUILD.gn | 1 + src/compiler/arm/instruction-selector-arm.cc | 10 +- src/compiler/arm64/instruction-selector-arm64.cc | 10 +- src/compiler/ast-graph-builder.cc | 2 +- src/compiler/change-lowering-unittest.cc | 2 +- src/compiler/change-lowering.cc | 16 +- src/compiler/graph-unittest.cc | 24 +- src/compiler/graph-unittest.h | 2 +- src/compiler/ia32/instruction-selector-ia32.cc | 10 +- src/compiler/instruction-selector.cc | 4 +- src/compiler/js-generic-lowering.cc | 3 +- src/compiler/js-typed-lowering.h | 4 +- src/compiler/machine-operator-reducer-unittest.cc | 2 +- src/compiler/machine-operator-reducer.cc | 2 +- src/compiler/machine-operator-unittest.cc | 334 ++++++++++++++++++--- src/compiler/machine-operator.cc | 241 +++++++++++++++ src/compiler/machine-operator.h | 272 ++++++++--------- src/compiler/machine-type.h | 41 +-- src/compiler/operator.h | 15 +- src/compiler/pipeline.cc | 3 +- src/compiler/raw-machine-assembler.cc | 2 +- src/compiler/raw-machine-assembler.h | 7 +- src/compiler/simplified-lowering.cc | 10 +- src/compiler/simplified-lowering.h | 3 +- .../simplified-operator-reducer-unittest.cc | 2 +- src/compiler/simplified-operator.h | 2 + src/compiler/x64/instruction-selector-x64.cc | 10 +- src/unique.h | 4 +- test/cctest/compiler/graph-builder-tester.h | 1 - test/cctest/compiler/test-changes-lowering.cc | 7 +- test/cctest/compiler/test-instruction.cc | 1 - test/cctest/compiler/test-js-typed-lowering.cc | 1 - .../compiler/test-machine-operator-reducer.cc | 6 +- test/cctest/compiler/test-schedule.cc | 2 +- test/cctest/compiler/test-scheduler.cc | 6 +- test/cctest/compiler/test-simplified-lowering.cc | 8 +- tools/gyp/v8.gyp | 1 + 37 files changed, 766 insertions(+), 305 deletions(-) create mode 100644 src/compiler/machine-operator.cc diff --git a/BUILD.gn b/BUILD.gn index 9938901..76d48d1 100644 --- 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", diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc index cde0fe7..c645fb7 100644 --- a/src/compiler/arm/instruction-selector-arm.cc +++ b/src/compiler/arm/instruction-selector-arm.cc @@ -283,8 +283,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node, void InstructionSelector::VisitLoad(Node* node) { - MachineType rep = RepresentationOf(OpParameter(node)); - MachineType typ = TypeOf(OpParameter(node)); + MachineType rep = RepresentationOf(OpParameter(node)); + MachineType typ = TypeOf(OpParameter(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(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) { diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc index d5cfdbe..fa2f17f 100644 --- a/src/compiler/arm64/instruction-selector-arm64.cc +++ b/src/compiler/arm64/instruction-selector-arm64.cc @@ -136,8 +136,8 @@ static void VisitBinop(InstructionSelector* selector, Node* node, void InstructionSelector::VisitLoad(Node* node) { - MachineType rep = RepresentationOf(OpParameter(node)); - MachineType typ = TypeOf(OpParameter(node)); + MachineType rep = RepresentationOf(OpParameter(node)); + MachineType typ = TypeOf(OpParameter(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(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: diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc index 91ae5b2..25cde42 100644 --- a/src/compiler/ast-graph-builder.cc +++ b/src/compiler/ast-graph-builder.cc @@ -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; diff --git a/src/compiler/change-lowering-unittest.cc b/src/compiler/change-lowering-unittest.cc index 1978476..52e9931 100644 --- a/src/compiler/change-lowering-unittest.cc +++ b/src/compiler/change-lowering-unittest.cc @@ -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); } diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc index 7982b76..a885cf1 100644 --- a/src/compiler/change-lowering.cc +++ b/src/compiler/change-lowering.cc @@ -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(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()); diff --git a/src/compiler/graph-unittest.cc b/src/compiler/graph-unittest.cc index 85ab3dc..f7faa6d 100644 --- a/src/compiler/graph-unittest.cc +++ b/src/compiler/graph-unittest.cc @@ -428,20 +428,20 @@ class IsCallMatcher FINAL : public NodeMatcher { class IsLoadMatcher FINAL : public NodeMatcher { public: - IsLoadMatcher(const Matcher& type_matcher, + IsLoadMatcher(const Matcher& rep_matcher, const Matcher& base_matcher, const Matcher& index_matcher, const Matcher& 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(node), "type", - type_matcher_, listener) && + PrintMatchAndExplain(OpParameter(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 type_matcher_; + const Matcher rep_matcher_; const Matcher base_matcher_; const Matcher index_matcher_; const Matcher effect_matcher_; @@ -513,10 +513,10 @@ class IsStoreMatcher FINAL : public NodeMatcher { OVERRIDE { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain( - OpParameter(node).machine_type, "type", + OpParameter(node).machine_type(), "type", type_matcher_, listener) && PrintMatchAndExplain( - OpParameter(node).write_barrier_kind, + OpParameter(node).write_barrier_kind(), "write barrier", write_barrier_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && @@ -704,12 +704,12 @@ Matcher IsCall(const Matcher& descriptor_matcher, } -Matcher IsLoad(const Matcher& type_matcher, +Matcher IsLoad(const Matcher& rep_matcher, const Matcher& base_matcher, const Matcher& index_matcher, const Matcher& 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)); } diff --git a/src/compiler/graph-unittest.h b/src/compiler/graph-unittest.h index 761343c..42e4dd9 100644 --- a/src/compiler/graph-unittest.h +++ b/src/compiler/graph-unittest.h @@ -83,7 +83,7 @@ Matcher IsCall(const Matcher& descriptor_matcher, const Matcher& effect_matcher, const Matcher& control_matcher); -Matcher IsLoad(const Matcher& type_matcher, +Matcher IsLoad(const Matcher& rep_matcher, const Matcher& base_matcher, const Matcher& index_matcher, const Matcher& effect_matcher); diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index 8a63ec6..eb3752c 100644 --- a/src/compiler/ia32/instruction-selector-ia32.cc +++ b/src/compiler/ia32/instruction-selector-ia32.cc @@ -41,8 +41,8 @@ class IA32OperandGenerator FINAL : public OperandGenerator { void InstructionSelector::VisitLoad(Node* node) { - MachineType rep = RepresentationOf(OpParameter(node)); - MachineType typ = TypeOf(OpParameter(node)); + MachineType rep = RepresentationOf(OpParameter(node)); + MachineType typ = TypeOf(OpParameter(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(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); diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 9d9d932..dec46b6 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -488,8 +488,8 @@ void InstructionSelector::VisitNode(Node* node) { case IrOpcode::kStateValues: return; case IrOpcode::kLoad: { - MachineType load_rep = OpParameter(node); - MarkAsRepresentation(load_rep, node); + LoadRepresentation rep = OpParameter(node); + MarkAsRepresentation(rep, node); return VisitLoad(node); } case IrOpcode::kStore: diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc index 5631e69..ea84818 100644 --- a/src/compiler/js-generic-lowering.cc +++ b/src/compiler/js-generic-lowering.cc @@ -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; } diff --git a/src/compiler/js-typed-lowering.h b/src/compiler/js-typed-lowering.h index e2c464a..ebd2d85 100644 --- a/src/compiler/js-typed-lowering.h +++ b/src/compiler/js-typed-lowering.h @@ -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; diff --git a/src/compiler/machine-operator-reducer-unittest.cc b/src/compiler/machine-operator-reducer-unittest.cc index fdf062e..a564b67 100644 --- a/src/compiler/machine-operator-reducer-unittest.cc +++ b/src/compiler/machine-operator-reducer-unittest.cc @@ -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) { diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc index 68e3f72..a873fa2 100644 --- a/src/compiler/machine-operator-reducer.cc +++ b/src/compiler/machine-operator-reducer.cc @@ -15,7 +15,7 @@ namespace internal { namespace compiler { MachineOperatorReducer::MachineOperatorReducer(JSGraph* jsgraph) - : jsgraph_(jsgraph), machine_(jsgraph->zone()) {} + : jsgraph_(jsgraph) {} MachineOperatorReducer::~MachineOperatorReducer() {} diff --git a/src/compiler/machine-operator-unittest.cc b/src/compiler/machine-operator-unittest.cc index dbf0b5b..5b34000 100644 --- a/src/compiler/machine-operator-unittest.cc +++ b/src/compiler/machine-operator-unittest.cc @@ -4,82 +4,320 @@ #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 { - 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 +class MachineOperatorTestWithParam + : public ::testing::TestWithParam< ::testing::tuple > { 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 > 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 + 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(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 > { + protected: + StoreRepresentation GetParam() const { + return StoreRepresentation( + ::testing::get<0>(MachineOperatorTestWithParam< + ::testing::tuple >::GetParam()), + ::testing::get<1>(MachineOperatorTestWithParam< + ::testing::tuple >::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(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 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 index 0000000..fb46a98 --- /dev/null +++ b/src/compiler/machine-operator.cc @@ -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 { + 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 { + 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 { \ + Load##Type##Operator() \ + : Operator1( \ + 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 { \ + explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \ + : Operator1( \ + 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::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 diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h index 203fd96..6cfbfba 100644 --- a/src/compiler/machine-operator.h +++ b/src/compiler/machine-operator.h @@ -6,183 +6,177 @@ #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 { - 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(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 diff --git a/src/compiler/machine-type.h b/src/compiler/machine-type.h index 771350b..88b482c 100644 --- a/src/compiler/machine-type.h +++ b/src/compiler/machine-type.h @@ -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(0); -const MachineType kMachFloat32 = - static_cast(kRepFloat32 | kTypeNumber); -const MachineType kMachFloat64 = - static_cast(kRepFloat64 | kTypeNumber); -const MachineType kMachInt8 = static_cast(kRepWord8 | kTypeInt32); -const MachineType kMachUint8 = - static_cast(kRepWord8 | kTypeUint32); -const MachineType kMachInt16 = - static_cast(kRepWord16 | kTypeInt32); -const MachineType kMachUint16 = - static_cast(kRepWord16 | kTypeUint32); -const MachineType kMachInt32 = - static_cast(kRepWord32 | kTypeInt32); -const MachineType kMachUint32 = - static_cast(kRepWord32 | kTypeUint32); -const MachineType kMachInt64 = - static_cast(kRepWord64 | kTypeInt64); -const MachineType kMachUint64 = - static_cast(kRepWord64 | kTypeUint64); -const MachineType kMachPtr = kPointerSize == 4 ? kRepWord32 : kRepWord64; -const MachineType kMachAnyTagged = - static_cast(kRepTagged | kTypeAny); - // Gets only the type of the given type. inline MachineType TypeOf(MachineType machine_type) { int result = machine_type & kTypeMask; diff --git a/src/compiler/operator.h b/src/compiler/operator.h index 395cac8..8d17bc4 100644 --- a/src/compiler/operator.h +++ b/src/compiler/operator.h @@ -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 > NameOperator; - // Helper to extract parameters from Operator1<*> operator. template diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index 6b5fdcf..6edfb3f 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -169,6 +169,7 @@ Handle 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 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 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); diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc index 9e150aa..19f51d4 100644 --- a/src/compiler/raw-machine-assembler.cc +++ b/src/compiler/raw-machine-assembler.cc @@ -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_( diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h index 135d401..cb0302b 100644 --- a/src/compiler/raw-machine-assembler.h +++ b/src/compiler/raw-machine-assembler.h @@ -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); diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index 27212f7..023c843 100644 --- a/src/compiler/simplified-lowering.cc +++ b/src/compiler/simplified-lowering.cc @@ -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(node); + LoadRepresentation rep = OpParameter(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(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))); } diff --git a/src/compiler/simplified-lowering.h b/src/compiler/simplified-lowering.h index 94766f7..9e83fdf 100644 --- a/src/compiler/simplified-lowering.h +++ b/src/compiler/simplified-lowering.h @@ -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(); diff --git a/src/compiler/simplified-operator-reducer-unittest.cc b/src/compiler/simplified-operator-reducer-unittest.cc index 2ea4f47..9ab8109 100644 --- a/src/compiler/simplified-operator-reducer-unittest.cc +++ b/src/compiler/simplified-operator-reducer-unittest.cc @@ -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); diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h index a4ff635..b56b632 100644 --- a/src/compiler/simplified-operator.h +++ b/src/compiler/simplified-operator.h @@ -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 { diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index efde91b..8d41fa1 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -56,8 +56,8 @@ class X64OperandGenerator FINAL : public OperandGenerator { void InstructionSelector::VisitLoad(Node* node) { - MachineType rep = RepresentationOf(OpParameter(node)); - MachineType typ = TypeOf(OpParameter(node)); + MachineType rep = RepresentationOf(OpParameter(node)); + MachineType typ = TypeOf(OpParameter(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(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); diff --git a/src/unique.h b/src/unique.h index fcb6e3d..619c3c9 100644 --- a/src/unique.h +++ b/src/unique.h @@ -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" diff --git a/test/cctest/compiler/graph-builder-tester.h b/test/cctest/compiler/graph-builder-tester.h index 3fba64c..df79250 100644 --- a/test/cctest/compiler/graph-builder-tester.h +++ b/test/cctest/compiler/graph-builder-tester.h @@ -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: diff --git a/test/cctest/compiler/test-changes-lowering.cc b/test/cctest/compiler/test-changes-lowering.cc index 2537091..396cc5d 100644 --- a/test/cctest/compiler/test-changes-lowering.cc +++ b/test/cctest/compiler/test-changes-lowering.cc @@ -222,9 +222,10 @@ TEST(RunChangeTaggedToFloat64) { ChangesLoweringTester 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) { diff --git a/test/cctest/compiler/test-instruction.cc b/test/cctest/compiler/test-instruction.cc index e071d23..08e44ec 100644 --- a/test/cctest/compiler/test-instruction.cc +++ b/test/cctest/compiler/test-instruction.cc @@ -32,7 +32,6 @@ class InstructionTester : public HandleAndZoneScope { info(static_cast(NULL), main_isolate()), linkage(&info), common(zone()), - machine(zone()), code(NULL) {} ~InstructionTester() { delete code; } diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc index 5259d70..a7ffc67 100644 --- a/test/cctest/compiler/test-js-typed-lowering.cc +++ b/test/cctest/compiler/test-js-typed-lowering.cc @@ -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()), diff --git a/test/cctest/compiler/test-machine-operator-reducer.cc b/test/cctest/compiler/test-machine-operator-reducer.cc index 45b63b1..569fe87 100644 --- a/test/cctest/compiler/test-machine-operator-reducer.cc +++ b/test/cctest/compiler/test-machine-operator-reducer.cc @@ -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. diff --git a/test/cctest/compiler/test-schedule.cc b/test/cctest/compiler/test-schedule.cc index cad686a..6c05c05 100644 --- a/test/cctest/compiler/test-schedule.cc +++ b/test/cctest/compiler/test-schedule.cc @@ -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); diff --git a/test/cctest/compiler/test-scheduler.cc b/test/cctest/compiler/test-scheduler.cc index 9c0d38f..cf33123 100644 --- a/test/cctest/compiler/test-scheduler.cc +++ b/test/cctest/compiler/test-scheduler.cc @@ -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 = @@ -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); diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc index 27db0a5..4119402 100644 --- a/test/cctest/compiler/test-simplified-lowering.cc +++ b/test/cctest/compiler/test-simplified-lowering.cc @@ -1265,9 +1265,9 @@ TEST(LowerStoreField_to_store) { StoreRepresentation rep = OpParameter(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(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()); } } diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index 6a4fd90..1641138 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -426,6 +426,7 @@ '../../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', -- 2.7.4