Commit deb5dcea authored by titzer's avatar titzer Committed by Commit bot

[turbofan] Make an OptionalOperator for MachineOperatorBuilder.

This makes usage of the MachineOperatorBuilder more robust, as it will be
an error to request an unsupported operator.

Along the way, I noticed that all 7 platforms support Float32Abs and
Float64Abs. Should make them non-optional in another CL?

R=bmeurer@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#29223}
parent 046e91dd
...@@ -179,15 +179,15 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) { ...@@ -179,15 +179,15 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) {
} }
} }
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat32Min()) { machine()->Float32Min().IsSupported()) {
// We might now be able to further reduce the {merge} node. // We might now be able to further reduce the {merge} node.
Revisit(merge); Revisit(merge);
return Change(node, machine()->Float32Min(), vtrue, vfalse); return Change(node, machine()->Float32Min().op(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) && } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat32Max()) { machine()->Float32Max().IsSupported()) {
// We might now be able to further reduce the {merge} node. // We might now be able to further reduce the {merge} node.
Revisit(merge); Revisit(merge);
return Change(node, machine()->Float32Max(), vtrue, vfalse); return Change(node, machine()->Float32Max().op(), vtrue, vfalse);
} }
} else if (cond->opcode() == IrOpcode::kFloat64LessThan) { } else if (cond->opcode() == IrOpcode::kFloat64LessThan) {
Float64BinopMatcher mcond(cond); Float64BinopMatcher mcond(cond);
...@@ -201,15 +201,15 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) { ...@@ -201,15 +201,15 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) {
} }
} }
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat64Min()) { machine()->Float64Min().IsSupported()) {
// We might now be able to further reduce the {merge} node. // We might now be able to further reduce the {merge} node.
Revisit(merge); Revisit(merge);
return Change(node, machine()->Float64Min(), vtrue, vfalse); return Change(node, machine()->Float64Min().op(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) && } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat64Max()) { machine()->Float64Max().IsSupported()) {
// We might now be able to further reduce the {merge} node. // We might now be able to further reduce the {merge} node.
Revisit(merge); Revisit(merge);
return Change(node, machine()->Float64Max(), vtrue, vfalse); return Change(node, machine()->Float64Max().op(), vtrue, vfalse);
} }
} }
} }
...@@ -256,11 +256,11 @@ Reduction CommonOperatorReducer::ReduceSelect(Node* node) { ...@@ -256,11 +256,11 @@ Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
} }
} }
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat32Min()) { machine()->Float32Min().IsSupported()) {
return Change(node, machine()->Float32Min(), vtrue, vfalse); return Change(node, machine()->Float32Min().op(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) && } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat32Max()) { machine()->Float32Max().IsSupported()) {
return Change(node, machine()->Float32Max(), vtrue, vfalse); return Change(node, machine()->Float32Max().op(), vtrue, vfalse);
} }
break; break;
} }
...@@ -274,11 +274,11 @@ Reduction CommonOperatorReducer::ReduceSelect(Node* node) { ...@@ -274,11 +274,11 @@ Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
} }
} }
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) && if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat64Min()) { machine()->Float64Min().IsSupported()) {
return Change(node, machine()->Float64Min(), vtrue, vfalse); return Change(node, machine()->Float64Min().op(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) && } else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat64Max()) { machine()->Float64Max().IsSupported()) {
return Change(node, machine()->Float64Max(), vtrue, vfalse); return Change(node, machine()->Float64Max().op(), vtrue, vfalse);
} }
break; break;
} }
......
...@@ -279,8 +279,8 @@ Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) { ...@@ -279,8 +279,8 @@ Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) {
Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) { Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) {
if (!machine()->HasFloat64RoundDown()) return NoChange(); if (!machine()->Float64RoundDown().IsSupported()) return NoChange();
return Change(node, machine()->Float64RoundDown()); return Change(node, machine()->Float64RoundDown().op());
} }
......
...@@ -118,22 +118,19 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) { ...@@ -118,22 +118,19 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \ V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \ V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \ V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
V(Float32Abs, Operator::kNoProperties, 1, 0, 1) \
V(Float32Add, Operator::kCommutative, 2, 0, 1) \ V(Float32Add, Operator::kCommutative, 2, 0, 1) \
V(Float32Sub, Operator::kNoProperties, 2, 0, 1) \ V(Float32Sub, Operator::kNoProperties, 2, 0, 1) \
V(Float32Mul, Operator::kCommutative, 2, 0, 1) \ V(Float32Mul, Operator::kCommutative, 2, 0, 1) \
V(Float32Div, Operator::kNoProperties, 2, 0, 1) \ V(Float32Div, Operator::kNoProperties, 2, 0, 1) \
V(Float32Abs, Operator::kNoProperties, 1, 0, 1) \
V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1) \ V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1) \
V(Float64Abs, Operator::kNoProperties, 1, 0, 1) \
V(Float64Add, Operator::kCommutative, 2, 0, 1) \ V(Float64Add, Operator::kCommutative, 2, 0, 1) \
V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \ V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
V(Float64Mul, Operator::kCommutative, 2, 0, 1) \ V(Float64Mul, Operator::kCommutative, 2, 0, 1) \
V(Float64Div, Operator::kNoProperties, 2, 0, 1) \ V(Float64Div, Operator::kNoProperties, 2, 0, 1) \
V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \ V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \
V(Float64Abs, Operator::kNoProperties, 1, 0, 1) \
V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \ V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
V(Float32Equal, Operator::kCommutative, 2, 0, 1) \ V(Float32Equal, Operator::kCommutative, 2, 0, 1) \
V(Float32LessThan, Operator::kNoProperties, 2, 0, 1) \ V(Float32LessThan, Operator::kNoProperties, 2, 0, 1) \
V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \ V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
...@@ -144,12 +141,17 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) { ...@@ -144,12 +141,17 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \ V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \
V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \ V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \
V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \ V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \
V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1) \
V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1)
#define PURE_OPTIONAL_OP_LIST(V) \
V(Float32Max, Operator::kNoProperties, 2, 0, 1) \ V(Float32Max, Operator::kNoProperties, 2, 0, 1) \
V(Float32Min, Operator::kNoProperties, 2, 0, 1) \ V(Float32Min, Operator::kNoProperties, 2, 0, 1) \
V(Float64Max, Operator::kNoProperties, 2, 0, 1) \ V(Float64Max, Operator::kNoProperties, 2, 0, 1) \
V(Float64Min, Operator::kNoProperties, 2, 0, 1) \ V(Float64Min, Operator::kNoProperties, 2, 0, 1) \
V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1) \ V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1) V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1)
#define MACHINE_TYPE_LIST(V) \ #define MACHINE_TYPE_LIST(V) \
...@@ -185,6 +187,7 @@ struct MachineOperatorGlobalCache { ...@@ -185,6 +187,7 @@ struct MachineOperatorGlobalCache {
}; \ }; \
Name##Operator k##Name; Name##Operator k##Name;
PURE_OP_LIST(PURE) PURE_OP_LIST(PURE)
PURE_OPTIONAL_OP_LIST(PURE)
#undef PURE #undef PURE
#define LOAD(Type) \ #define LOAD(Type) \
...@@ -256,6 +259,13 @@ MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word, ...@@ -256,6 +259,13 @@ MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
PURE_OP_LIST(PURE) PURE_OP_LIST(PURE)
#undef PURE #undef PURE
#define PURE(Name, properties, value_input_count, control_input_count, \
output_count) \
const OptionalOperator MachineOperatorBuilder::Name() { \
return OptionalOperator(flags_ & k##Name ? &cache_.k##Name : nullptr); \
}
PURE_OPTIONAL_OP_LIST(PURE)
#undef PURE
const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) { const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
switch (rep) { switch (rep) {
......
...@@ -16,6 +16,20 @@ namespace compiler { ...@@ -16,6 +16,20 @@ namespace compiler {
struct MachineOperatorGlobalCache; struct MachineOperatorGlobalCache;
class Operator; class Operator;
// For operators that are not supported on all platforms.
class OptionalOperator {
public:
explicit OptionalOperator(const Operator* op) : op_(op) {}
bool IsSupported() const { return op_ != nullptr; }
const Operator* op() const {
DCHECK_NOT_NULL(op_);
return op_;
}
private:
const Operator* op_;
};
// Supported write barrier modes. // Supported write barrier modes.
enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier }; enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
...@@ -83,7 +97,10 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -83,7 +97,10 @@ class MachineOperatorBuilder final : public ZoneObject {
kFloat64RoundTiesAway = 1u << 6, kFloat64RoundTiesAway = 1u << 6,
kInt32DivIsSafe = 1u << 7, kInt32DivIsSafe = 1u << 7,
kUint32DivIsSafe = 1u << 8, kUint32DivIsSafe = 1u << 8,
kWord32ShiftIsSafe = 1u << 9 kWord32ShiftIsSafe = 1u << 9,
kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
kFloat64RoundDown | kFloat64RoundTruncate |
kFloat64RoundTiesAway
}; };
typedef base::Flags<Flag, unsigned> Flags; typedef base::Flags<Flag, unsigned> Flags;
...@@ -186,16 +203,12 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -186,16 +203,12 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* Float64LessThanOrEqual(); const Operator* Float64LessThanOrEqual();
// Floating point min/max complying to IEEE 754 (single-precision). // Floating point min/max complying to IEEE 754 (single-precision).
const Operator* Float32Max(); const OptionalOperator Float32Max();
const Operator* Float32Min(); const OptionalOperator Float32Min();
bool HasFloat32Max() { return flags_ & kFloat32Max; }
bool HasFloat32Min() { return flags_ & kFloat32Min; }
// Floating point min/max complying to IEEE 754 (double-precision). // Floating point min/max complying to IEEE 754 (double-precision).
const Operator* Float64Max(); const OptionalOperator Float64Max();
const Operator* Float64Min(); const OptionalOperator Float64Min();
bool HasFloat64Max() { return flags_ & kFloat64Max; }
bool HasFloat64Min() { return flags_ & kFloat64Min; }
// Floating point abs complying to IEEE 754 (single-precision). // Floating point abs complying to IEEE 754 (single-precision).
const Operator* Float32Abs(); const Operator* Float32Abs();
...@@ -204,12 +217,9 @@ class MachineOperatorBuilder final : public ZoneObject { ...@@ -204,12 +217,9 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* Float64Abs(); const Operator* Float64Abs();
// Floating point rounding. // Floating point rounding.
const Operator* Float64RoundDown(); const OptionalOperator Float64RoundDown();
const Operator* Float64RoundTruncate(); const OptionalOperator Float64RoundTruncate();
const Operator* Float64RoundTiesAway(); const OptionalOperator Float64RoundTiesAway();
bool HasFloat64RoundDown() { return flags_ & kFloat64RoundDown; }
bool HasFloat64RoundTruncate() { return flags_ & kFloat64RoundTruncate; }
bool HasFloat64RoundTiesAway() { return flags_ & kFloat64RoundTiesAway; }
// Floating point bit representation. // Floating point bit representation.
const Operator* Float64ExtractLowWord32(); const Operator* Float64ExtractLowWord32();
......
...@@ -5070,7 +5070,7 @@ TEST(RunFloat64RoundDown1) { ...@@ -5070,7 +5070,7 @@ TEST(RunFloat64RoundDown1) {
double input = -1.0; double input = -1.0;
double result = 0.0; double result = 0.0;
RawMachineAssemblerTester<int32_t> m; RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundDown()) return; if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64, m.StoreToPointer(&result, kMachFloat64,
m.Float64RoundDown(m.LoadFromPointer(&input, kMachFloat64))); m.Float64RoundDown(m.LoadFromPointer(&input, kMachFloat64)));
m.Return(m.Int32Constant(0)); m.Return(m.Int32Constant(0));
...@@ -5087,7 +5087,7 @@ TEST(RunFloat64RoundDown2) { ...@@ -5087,7 +5087,7 @@ TEST(RunFloat64RoundDown2) {
double input = -1.0; double input = -1.0;
double result = 0.0; double result = 0.0;
RawMachineAssemblerTester<int32_t> m; RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundDown()) return; if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64, m.StoreToPointer(&result, kMachFloat64,
m.Float64Sub(m.Float64Constant(-0.0), m.Float64Sub(m.Float64Constant(-0.0),
m.Float64RoundDown(m.Float64Sub( m.Float64RoundDown(m.Float64Sub(
...@@ -5107,7 +5107,7 @@ TEST(RunFloat64RoundTruncate) { ...@@ -5107,7 +5107,7 @@ TEST(RunFloat64RoundTruncate) {
double input = -1.0; double input = -1.0;
double result = 0.0; double result = 0.0;
RawMachineAssemblerTester<int32_t> m; RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundTruncate()) return; if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
m.StoreToPointer( m.StoreToPointer(
&result, kMachFloat64, &result, kMachFloat64,
m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64))); m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
...@@ -5125,7 +5125,7 @@ TEST(RunFloat64RoundTiesAway) { ...@@ -5125,7 +5125,7 @@ TEST(RunFloat64RoundTiesAway) {
double input = -1.0; double input = -1.0;
double result = 0.0; double result = 0.0;
RawMachineAssemblerTester<int32_t> m; RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundTiesAway()) return; if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
m.StoreToPointer( m.StoreToPointer(
&result, kMachFloat64, &result, kMachFloat64,
m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64))); m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
......
...@@ -37,22 +37,25 @@ class InstructionSelectorTest : public TestWithContext, ...@@ -37,22 +37,25 @@ class InstructionSelectorTest : public TestWithContext,
class StreamBuilder final : public RawMachineAssembler { class StreamBuilder final : public RawMachineAssembler {
public: public:
StreamBuilder(InstructionSelectorTest* test, MachineType return_type) StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
: RawMachineAssembler(test->isolate(), : RawMachineAssembler(
new (test->zone()) Graph(test->zone()), test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type)), MakeMachineSignature(test->zone(), return_type), kMachPtr,
MachineOperatorBuilder::kAllOptionalOps),
test_(test) {} test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type, StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type) MachineType parameter0_type)
: RawMachineAssembler( : RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()), test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type)), MakeMachineSignature(test->zone(), return_type, parameter0_type),
kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {} test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type, StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type, MachineType parameter1_type) MachineType parameter0_type, MachineType parameter1_type)
: RawMachineAssembler( : RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()), test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type, MakeMachineSignature(test->zone(), return_type, parameter0_type,
parameter1_type)), parameter1_type),
kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {} test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type, StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type, MachineType parameter1_type, MachineType parameter0_type, MachineType parameter1_type,
...@@ -60,7 +63,8 @@ class InstructionSelectorTest : public TestWithContext, ...@@ -60,7 +63,8 @@ class InstructionSelectorTest : public TestWithContext,
: RawMachineAssembler( : RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()), test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type, MakeMachineSignature(test->zone(), return_type, parameter0_type,
parameter1_type, parameter2_type)), parameter1_type, parameter2_type),
kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {} test_(test) {}
Stream Build(CpuFeature feature) { Stream Build(CpuFeature feature) {
......
...@@ -149,130 +149,199 @@ INSTANTIATE_TEST_CASE_P( ...@@ -149,130 +149,199 @@ INSTANTIATE_TEST_CASE_P(
::testing::Combine(::testing::ValuesIn(kMachineTypes), ::testing::Combine(::testing::ValuesIn(kMachineTypes),
::testing::Values(kNoWriteBarrier, ::testing::Values(kNoWriteBarrier,
kFullWriteBarrier)))); kFullWriteBarrier))));
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Pure operators. // Pure operators.
namespace { namespace {
struct PureOperator { struct PureOperator {
const Operator* (MachineOperatorBuilder::*constructor)(); const Operator* (MachineOperatorBuilder::*constructor)();
IrOpcode::Value opcode; char const* const constructor_name;
int value_input_count; int value_input_count;
int control_input_count; int control_input_count;
int value_output_count; int value_output_count;
}; };
std::ostream& operator<<(std::ostream& os, const PureOperator& pop) { std::ostream& operator<<(std::ostream& os, PureOperator const& pop) {
return os << IrOpcode::Mnemonic(pop.opcode); return os << pop.constructor_name;
} }
const PureOperator kPureOperators[] = { const PureOperator kPureOperators[] = {
#define PURE(Name, value_input_count, control_input_count, value_output_count) \ #define PURE(Name, value_input_count, control_input_count, value_output_count) \
{ \ { \
&MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count, \ &MachineOperatorBuilder::Name, #Name, value_input_count, \
control_input_count, value_output_count \ control_input_count, value_output_count \
} }
PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1), PURE(Word32And, 2, 0, 1), // --
PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1), PURE(Word32Or, 2, 0, 1), // --
PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1), PURE(Word32Xor, 2, 0, 1), // --
PURE(Word32Equal, 2, 0, 1), PURE(Word32Clz, 1, 0, 1), PURE(Word32Shl, 2, 0, 1), // --
PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), PURE(Word32Shr, 2, 0, 1), // --
PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1), PURE(Word32Sar, 2, 0, 1), // --
PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1), PURE(Word32Ror, 2, 0, 1), // --
PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1), PURE(Word32Equal, 2, 0, 1), // --
PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1), PURE(Word32Clz, 1, 0, 1), // --
PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1), PURE(Word64And, 2, 0, 1), // --
PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1), PURE(Word64Or, 2, 0, 1), // --
PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1), PURE(Word64Xor, 2, 0, 1), // --
PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1), PURE(Word64Shl, 2, 0, 1), // --
PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1), PURE(Word64Shr, 2, 0, 1), // --
PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), PURE(Word64Sar, 2, 0, 1), // --
PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), PURE(Word64Ror, 2, 0, 1), // --
PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1), PURE(Word64Equal, 2, 0, 1), // --
PURE(Int64LessThanOrEqual, 2, 0, 1), PURE(Uint64LessThan, 2, 0, 1), PURE(Int32Add, 2, 0, 1), // --
PURE(ChangeFloat32ToFloat64, 1, 0, 1), PURE(ChangeFloat64ToInt32, 1, 0, 1), PURE(Int32AddWithOverflow, 2, 0, 2), // --
PURE(ChangeFloat64ToUint32, 1, 0, 1), PURE(ChangeInt32ToInt64, 1, 0, 1), PURE(Int32Sub, 2, 0, 1), // --
PURE(ChangeUint32ToFloat64, 1, 0, 1), PURE(ChangeUint32ToUint64, 1, 0, 1), PURE(Int32SubWithOverflow, 2, 0, 2), // --
PURE(TruncateFloat64ToFloat32, 1, 0, 1), PURE(Int32Mul, 2, 0, 1), // --
PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1), PURE(Int32MulHigh, 2, 0, 1), // --
PURE(Float32Add, 2, 0, 1), PURE(Float32Sub, 2, 0, 1), PURE(Int32Div, 2, 1, 1), // --
PURE(Float32Mul, 2, 0, 1), PURE(Float32Div, 2, 0, 1), PURE(Uint32Div, 2, 1, 1), // --
PURE(Float32Abs, 1, 0, 1), PURE(Float32Sqrt, 1, 0, 1), PURE(Int32Mod, 2, 1, 1), // --
PURE(Float32Equal, 2, 0, 1), PURE(Float32LessThan, 2, 0, 1), PURE(Uint32Mod, 2, 1, 1), // --
PURE(Float32LessThanOrEqual, 2, 0, 1), PURE(Float32Max, 2, 0, 1), PURE(Int32LessThan, 2, 0, 1), // --
PURE(Float32Min, 2, 0, 1), PURE(Float64Add, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1), // --
PURE(Float64Sub, 2, 0, 1), PURE(Float64Mul, 2, 0, 1), PURE(Uint32LessThan, 2, 0, 1), // --
PURE(Float64Div, 2, 0, 1), PURE(Float64Mod, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1), // --
PURE(Float64Abs, 1, 0, 1), PURE(Float64Sqrt, 1, 0, 1), PURE(Int64Add, 2, 0, 1), // --
PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), // --
PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(Float64Max, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), // --
PURE(Float64Min, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1), PURE(Int64Div, 2, 0, 1), // --
PURE(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1), PURE(Uint64Div, 2, 0, 1), // --
PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1), PURE(Int64Mod, 2, 0, 1), // --
PURE(Float64ExtractHighWord32, 1, 0, 1), PURE(Uint64Mod, 2, 0, 1), // --
PURE(Float64InsertLowWord32, 2, 0, 1), PURE(Int64LessThan, 2, 0, 1), // --
PURE(Float64InsertHighWord32, 2, 0, 1) PURE(Int64LessThanOrEqual, 2, 0, 1), // --
PURE(Uint64LessThan, 2, 0, 1), // --
PURE(ChangeFloat32ToFloat64, 1, 0, 1), // --
PURE(ChangeFloat64ToInt32, 1, 0, 1), // --
PURE(ChangeFloat64ToUint32, 1, 0, 1), // --
PURE(ChangeInt32ToInt64, 1, 0, 1), // --
PURE(ChangeUint32ToFloat64, 1, 0, 1), // --
PURE(ChangeUint32ToUint64, 1, 0, 1), // --
PURE(TruncateFloat64ToFloat32, 1, 0, 1), // --
PURE(TruncateFloat64ToInt32, 1, 0, 1), // --
PURE(TruncateInt64ToInt32, 1, 0, 1), // --
PURE(Float32Abs, 1, 0, 1), // --
PURE(Float32Add, 2, 0, 1), // --
PURE(Float32Sub, 2, 0, 1), // --
PURE(Float32Mul, 2, 0, 1), // --
PURE(Float32Div, 2, 0, 1), // --
PURE(Float32Sqrt, 1, 0, 1), // --
PURE(Float32Equal, 2, 0, 1), // --
PURE(Float32LessThan, 2, 0, 1), // --
PURE(Float32LessThanOrEqual, 2, 0, 1), // --
PURE(Float64Abs, 1, 0, 1), // --
PURE(Float64Add, 2, 0, 1), // --
PURE(Float64Sub, 2, 0, 1), // --
PURE(Float64Mul, 2, 0, 1), // --
PURE(Float64Div, 2, 0, 1), // --
PURE(Float64Mod, 2, 0, 1), // --
PURE(Float64Sqrt, 1, 0, 1), // --
PURE(Float64Equal, 2, 0, 1), // --
PURE(Float64LessThan, 2, 0, 1), // --
PURE(Float64LessThanOrEqual, 2, 0, 1), // --
PURE(LoadStackPointer, 0, 0, 1), // --
PURE(Float64ExtractLowWord32, 1, 0, 1), // --
PURE(Float64ExtractHighWord32, 1, 0, 1), // --
PURE(Float64InsertLowWord32, 2, 0, 1), // --
PURE(Float64InsertHighWord32, 2, 0, 1), // --
#undef PURE #undef PURE
}; };
typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
} // namespace } // namespace
class MachinePureOperatorTest : public TestWithZone {
protected:
MachineType word_type() { return kMachPtr; }
};
TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
const PureOperator& pop = GetParam(); TEST_F(MachinePureOperatorTest, PureOperators) {
MachineOperatorBuilder machine1(zone(), type()); TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) {
MachineOperatorBuilder machine2(zone(), type()); MachineOperatorBuilder machine1(zone(), machine_rep1);
EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)()); TRACED_FOREACH(MachineType, machine_rep2, kMachineReps) {
MachineOperatorBuilder machine2(zone(), machine_rep2);
TRACED_FOREACH(PureOperator, pop, kPureOperators) {
const Operator* op1 = (machine1.*pop.constructor)();
const Operator* op2 = (machine2.*pop.constructor)();
EXPECT_EQ(op1, op2);
EXPECT_EQ(pop.value_input_count, op1->ValueInputCount());
EXPECT_EQ(pop.control_input_count, op1->ControlInputCount());
EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount());
}
}
}
} }
TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) { // Optional operators.
MachineOperatorBuilder machine(zone(), type());
const PureOperator& pop = GetParam();
const Operator* op = (machine.*pop.constructor)();
EXPECT_EQ(pop.value_input_count, op->ValueInputCount()); namespace {
EXPECT_EQ(0, op->EffectInputCount());
EXPECT_EQ(pop.control_input_count, op->ControlInputCount());
EXPECT_EQ(pop.value_input_count + pop.control_input_count,
OperatorProperties::GetTotalInputCount(op));
EXPECT_EQ(pop.value_output_count, op->ValueOutputCount()); struct OptionalOperatorEntry {
EXPECT_EQ(0, op->EffectOutputCount()); const OptionalOperator (MachineOperatorBuilder::*constructor)();
EXPECT_EQ(0, op->ControlOutputCount()); MachineOperatorBuilder::Flag enabling_flag;
} char const* const constructor_name;
int value_input_count;
int control_input_count;
int value_output_count;
};
TEST_P(MachinePureOperatorTest, MarkedAsPure) { std::ostream& operator<<(std::ostream& os, OptionalOperatorEntry const& pop) {
MachineOperatorBuilder machine(zone(), type()); return os << pop.constructor_name;
const PureOperator& pop = GetParam();
const Operator* op = (machine.*pop.constructor)();
EXPECT_TRUE(op->HasProperty(Operator::kPure));
} }
const OptionalOperatorEntry kOptionalOperators[] = {
#define OPTIONAL_ENTRY(Name, value_input_count, control_input_count, \
value_output_count) \
{ \
&MachineOperatorBuilder::Name, MachineOperatorBuilder::k##Name, #Name, \
value_input_count, control_input_count, value_output_count \
}
OPTIONAL_ENTRY(Float32Max, 2, 0, 1), // --
OPTIONAL_ENTRY(Float32Min, 2, 0, 1), // --
OPTIONAL_ENTRY(Float64Max, 2, 0, 1), // --
OPTIONAL_ENTRY(Float64Min, 2, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundDown, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundTruncate, 1, 0, 1), // --
OPTIONAL_ENTRY(Float64RoundTiesAway, 1, 0, 1), // --
#undef OPTIONAL_ENTRY
};
} // namespace
TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
MachineOperatorBuilder machine(zone(), type());
const PureOperator& pop = GetParam();
const Operator* op = (machine.*pop.constructor)();
EXPECT_EQ(pop.opcode, op->opcode());
}
class MachineOptionalOperatorTest : public TestWithZone {
protected:
MachineType word_type() { return kMachPtr; }
};
INSTANTIATE_TEST_CASE_P(
MachineOperatorTest, MachinePureOperatorTest,
::testing::Combine(::testing::ValuesIn(kMachineReps),
::testing::ValuesIn(kPureOperators)));
#endif // GTEST_HAS_COMBINE TEST_F(MachineOptionalOperatorTest, OptionalOperators) {
TRACED_FOREACH(OptionalOperatorEntry, pop, kOptionalOperators) {
TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) {
MachineOperatorBuilder machine1(zone(), machine_rep1, pop.enabling_flag);
TRACED_FOREACH(MachineType, machine_rep2, kMachineReps) {
MachineOperatorBuilder machine2(zone(), machine_rep2,
pop.enabling_flag);
const Operator* op1 = (machine1.*pop.constructor)().op();
const Operator* op2 = (machine2.*pop.constructor)().op();
EXPECT_EQ(op1, op2);
EXPECT_EQ(pop.value_input_count, op1->ValueInputCount());
EXPECT_EQ(pop.control_input_count, op1->ControlInputCount());
EXPECT_EQ(pop.value_output_count, op1->ValueOutputCount());
MachineOperatorBuilder machine3(zone(), word_type());
EXPECT_TRUE((machine1.*pop.constructor)().IsSupported());
EXPECT_FALSE((machine3.*pop.constructor)().IsSupported());
}
}
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -416,13 +416,13 @@ class RawMachineAssembler : public GraphBuilder { ...@@ -416,13 +416,13 @@ class RawMachineAssembler : public GraphBuilder {
return NewNode(machine()->TruncateInt64ToInt32(), a); return NewNode(machine()->TruncateInt64ToInt32(), a);
} }
Node* Float64RoundDown(Node* a) { Node* Float64RoundDown(Node* a) {
return NewNode(machine()->Float64RoundDown(), a); return NewNode(machine()->Float64RoundDown().op(), a);
} }
Node* Float64RoundTruncate(Node* a) { Node* Float64RoundTruncate(Node* a) {
return NewNode(machine()->Float64RoundTruncate(), a); return NewNode(machine()->Float64RoundTruncate().op(), a);
} }
Node* Float64RoundTiesAway(Node* a) { Node* Float64RoundTiesAway(Node* a) {
return NewNode(machine()->Float64RoundTiesAway(), a); return NewNode(machine()->Float64RoundTiesAway().op(), a);
} }
// Float64 bit operations. // Float64 bit operations.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment