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) {
}
}
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.
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) &&
machine()->HasFloat32Max()) {
machine()->Float32Max().IsSupported()) {
// We might now be able to further reduce the {merge} node.
Revisit(merge);
return Change(node, machine()->Float32Max(), vtrue, vfalse);
return Change(node, machine()->Float32Max().op(), vtrue, vfalse);
}
} else if (cond->opcode() == IrOpcode::kFloat64LessThan) {
Float64BinopMatcher mcond(cond);
......@@ -201,15 +201,15 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) {
}
}
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.
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) &&
machine()->HasFloat64Max()) {
machine()->Float64Max().IsSupported()) {
// We might now be able to further reduce the {merge} node.
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) {
}
}
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat32Min()) {
return Change(node, machine()->Float32Min(), vtrue, vfalse);
machine()->Float32Min().IsSupported()) {
return Change(node, machine()->Float32Min().op(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat32Max()) {
return Change(node, machine()->Float32Max(), vtrue, vfalse);
machine()->Float32Max().IsSupported()) {
return Change(node, machine()->Float32Max().op(), vtrue, vfalse);
}
break;
}
......@@ -274,11 +274,11 @@ Reduction CommonOperatorReducer::ReduceSelect(Node* node) {
}
}
if (mcond.left().Equals(vtrue) && mcond.right().Equals(vfalse) &&
machine()->HasFloat64Min()) {
return Change(node, machine()->Float64Min(), vtrue, vfalse);
machine()->Float64Min().IsSupported()) {
return Change(node, machine()->Float64Min().op(), vtrue, vfalse);
} else if (mcond.left().Equals(vfalse) && mcond.right().Equals(vtrue) &&
machine()->HasFloat64Max()) {
return Change(node, machine()->Float64Max(), vtrue, vfalse);
machine()->Float64Max().IsSupported()) {
return Change(node, machine()->Float64Max().op(), vtrue, vfalse);
}
break;
}
......
......@@ -279,8 +279,8 @@ Reduction JSIntrinsicLowering::ReduceMathClz32(Node* node) {
Reduction JSIntrinsicLowering::ReduceMathFloor(Node* node) {
if (!machine()->HasFloat64RoundDown()) return NoChange();
return Change(node, machine()->Float64RoundDown());
if (!machine()->Float64RoundDown().IsSupported()) return NoChange();
return Change(node, machine()->Float64RoundDown().op());
}
......
......@@ -118,22 +118,19 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
V(TruncateFloat64ToInt32, 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(Float32Sub, Operator::kNoProperties, 2, 0, 1) \
V(Float32Mul, Operator::kCommutative, 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(Float64Abs, Operator::kNoProperties, 1, 0, 1) \
V(Float64Add, Operator::kCommutative, 2, 0, 1) \
V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
V(Float64Mul, Operator::kCommutative, 2, 0, 1) \
V(Float64Div, 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(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(Float32LessThan, Operator::kNoProperties, 2, 0, 1) \
V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
......@@ -144,13 +141,18 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \
V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \
V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \
V(Float32Max, Operator::kNoProperties, 2, 0, 1) \
V(Float32Min, Operator::kNoProperties, 2, 0, 1) \
V(Float64Max, Operator::kNoProperties, 2, 0, 1) \
V(Float64Min, 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(Float32Min, Operator::kNoProperties, 2, 0, 1) \
V(Float64Max, Operator::kNoProperties, 2, 0, 1) \
V(Float64Min, Operator::kNoProperties, 2, 0, 1) \
V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1)
#define MACHINE_TYPE_LIST(V) \
V(MachFloat32) \
......@@ -185,6 +187,7 @@ struct MachineOperatorGlobalCache {
}; \
Name##Operator k##Name;
PURE_OP_LIST(PURE)
PURE_OPTIONAL_OP_LIST(PURE)
#undef PURE
#define LOAD(Type) \
......@@ -256,6 +259,13 @@ MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
PURE_OP_LIST(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) {
switch (rep) {
......
......@@ -16,6 +16,20 @@ namespace compiler {
struct MachineOperatorGlobalCache;
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.
enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
......@@ -83,7 +97,10 @@ class MachineOperatorBuilder final : public ZoneObject {
kFloat64RoundTiesAway = 1u << 6,
kInt32DivIsSafe = 1u << 7,
kUint32DivIsSafe = 1u << 8,
kWord32ShiftIsSafe = 1u << 9
kWord32ShiftIsSafe = 1u << 9,
kAllOptionalOps = kFloat32Max | kFloat32Min | kFloat64Max | kFloat64Min |
kFloat64RoundDown | kFloat64RoundTruncate |
kFloat64RoundTiesAway
};
typedef base::Flags<Flag, unsigned> Flags;
......@@ -186,16 +203,12 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* Float64LessThanOrEqual();
// Floating point min/max complying to IEEE 754 (single-precision).
const Operator* Float32Max();
const Operator* Float32Min();
bool HasFloat32Max() { return flags_ & kFloat32Max; }
bool HasFloat32Min() { return flags_ & kFloat32Min; }
const OptionalOperator Float32Max();
const OptionalOperator Float32Min();
// Floating point min/max complying to IEEE 754 (double-precision).
const Operator* Float64Max();
const Operator* Float64Min();
bool HasFloat64Max() { return flags_ & kFloat64Max; }
bool HasFloat64Min() { return flags_ & kFloat64Min; }
const OptionalOperator Float64Max();
const OptionalOperator Float64Min();
// Floating point abs complying to IEEE 754 (single-precision).
const Operator* Float32Abs();
......@@ -204,12 +217,9 @@ class MachineOperatorBuilder final : public ZoneObject {
const Operator* Float64Abs();
// Floating point rounding.
const Operator* Float64RoundDown();
const Operator* Float64RoundTruncate();
const Operator* Float64RoundTiesAway();
bool HasFloat64RoundDown() { return flags_ & kFloat64RoundDown; }
bool HasFloat64RoundTruncate() { return flags_ & kFloat64RoundTruncate; }
bool HasFloat64RoundTiesAway() { return flags_ & kFloat64RoundTiesAway; }
const OptionalOperator Float64RoundDown();
const OptionalOperator Float64RoundTruncate();
const OptionalOperator Float64RoundTiesAway();
// Floating point bit representation.
const Operator* Float64ExtractLowWord32();
......
......@@ -5070,7 +5070,7 @@ TEST(RunFloat64RoundDown1) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundDown()) return;
if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64RoundDown(m.LoadFromPointer(&input, kMachFloat64)));
m.Return(m.Int32Constant(0));
......@@ -5087,7 +5087,7 @@ TEST(RunFloat64RoundDown2) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundDown()) return;
if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64Sub(m.Float64Constant(-0.0),
m.Float64RoundDown(m.Float64Sub(
......@@ -5107,7 +5107,7 @@ TEST(RunFloat64RoundTruncate) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundTruncate()) return;
if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
......@@ -5125,7 +5125,7 @@ TEST(RunFloat64RoundTiesAway) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
if (!m.machine()->HasFloat64RoundTiesAway()) return;
if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
......
......@@ -37,22 +37,25 @@ class InstructionSelectorTest : public TestWithContext,
class StreamBuilder final : public RawMachineAssembler {
public:
StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
: RawMachineAssembler(test->isolate(),
new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type)),
: RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type), kMachPtr,
MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type)
: RawMachineAssembler(
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) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type, MachineType parameter1_type)
: RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type,
parameter1_type)),
parameter1_type),
kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
MachineType parameter0_type, MachineType parameter1_type,
......@@ -60,7 +63,8 @@ class InstructionSelectorTest : public TestWithContext,
: RawMachineAssembler(
test->isolate(), new (test->zone()) Graph(test->zone()),
MakeMachineSignature(test->zone(), return_type, parameter0_type,
parameter1_type, parameter2_type)),
parameter1_type, parameter2_type),
kMachPtr, MachineOperatorBuilder::kAllOptionalOps),
test_(test) {}
Stream Build(CpuFeature feature) {
......
......@@ -149,130 +149,199 @@ INSTANTIATE_TEST_CASE_P(
::testing::Combine(::testing::ValuesIn(kMachineTypes),
::testing::Values(kNoWriteBarrier,
kFullWriteBarrier))));
#endif
// -----------------------------------------------------------------------------
// Pure operators.
namespace {
struct PureOperator {
const Operator* (MachineOperatorBuilder::*constructor)();
IrOpcode::Value opcode;
char const* const constructor_name;
int value_input_count;
int control_input_count;
int value_output_count;
};
std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
return os << IrOpcode::Mnemonic(pop.opcode);
std::ostream& operator<<(std::ostream& os, PureOperator const& pop) {
return os << pop.constructor_name;
}
const PureOperator kPureOperators[] = {
#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 \
}
PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1),
PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1),
PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1),
PURE(Word32Equal, 2, 0, 1), PURE(Word32Clz, 1, 0, 1),
PURE(Word64And, 2, 0, 1), PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1),
PURE(Word64Shl, 2, 0, 1), PURE(Word64Shr, 2, 0, 1),
PURE(Word64Sar, 2, 0, 1), PURE(Word64Ror, 2, 0, 1),
PURE(Word64Equal, 2, 0, 1), PURE(Int32Add, 2, 0, 1),
PURE(Int32AddWithOverflow, 2, 0, 2), PURE(Int32Sub, 2, 0, 1),
PURE(Int32SubWithOverflow, 2, 0, 2), PURE(Int32Mul, 2, 0, 1),
PURE(Int32MulHigh, 2, 0, 1), PURE(Int32Div, 2, 1, 1),
PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1), PURE(Uint32Mod, 2, 1, 1),
PURE(Int32LessThan, 2, 0, 1), PURE(Int32LessThanOrEqual, 2, 0, 1),
PURE(Uint32LessThan, 2, 0, 1), PURE(Uint32LessThanOrEqual, 2, 0, 1),
PURE(Int64Add, 2, 0, 1), PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1),
PURE(Int64Div, 2, 0, 1), PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1),
PURE(Uint64Mod, 2, 0, 1), PURE(Int64LessThan, 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(Float32Add, 2, 0, 1), PURE(Float32Sub, 2, 0, 1),
PURE(Float32Mul, 2, 0, 1), PURE(Float32Div, 2, 0, 1),
PURE(Float32Abs, 1, 0, 1), PURE(Float32Sqrt, 1, 0, 1),
PURE(Float32Equal, 2, 0, 1), PURE(Float32LessThan, 2, 0, 1),
PURE(Float32LessThanOrEqual, 2, 0, 1), PURE(Float32Max, 2, 0, 1),
PURE(Float32Min, 2, 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(Float64Abs, 1, 0, 1), PURE(Float64Sqrt, 1, 0, 1),
PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1),
PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(Float64Max, 2, 0, 1),
PURE(Float64Min, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1),
PURE(Float64RoundDown, 1, 0, 1), PURE(Float64RoundTruncate, 1, 0, 1),
PURE(Float64RoundTiesAway, 1, 0, 1), PURE(Float64ExtractLowWord32, 1, 0, 1),
PURE(Float64ExtractHighWord32, 1, 0, 1),
PURE(Float64InsertLowWord32, 2, 0, 1),
PURE(Float64InsertHighWord32, 2, 0, 1)
PURE(Word32And, 2, 0, 1), // --
PURE(Word32Or, 2, 0, 1), // --
PURE(Word32Xor, 2, 0, 1), // --
PURE(Word32Shl, 2, 0, 1), // --
PURE(Word32Shr, 2, 0, 1), // --
PURE(Word32Sar, 2, 0, 1), // --
PURE(Word32Ror, 2, 0, 1), // --
PURE(Word32Equal, 2, 0, 1), // --
PURE(Word32Clz, 1, 0, 1), // --
PURE(Word64And, 2, 0, 1), // --
PURE(Word64Or, 2, 0, 1), // --
PURE(Word64Xor, 2, 0, 1), // --
PURE(Word64Shl, 2, 0, 1), // --
PURE(Word64Shr, 2, 0, 1), // --
PURE(Word64Sar, 2, 0, 1), // --
PURE(Word64Ror, 2, 0, 1), // --
PURE(Word64Equal, 2, 0, 1), // --
PURE(Int32Add, 2, 0, 1), // --
PURE(Int32AddWithOverflow, 2, 0, 2), // --
PURE(Int32Sub, 2, 0, 1), // --
PURE(Int32SubWithOverflow, 2, 0, 2), // --
PURE(Int32Mul, 2, 0, 1), // --
PURE(Int32MulHigh, 2, 0, 1), // --
PURE(Int32Div, 2, 1, 1), // --
PURE(Uint32Div, 2, 1, 1), // --
PURE(Int32Mod, 2, 1, 1), // --
PURE(Uint32Mod, 2, 1, 1), // --
PURE(Int32LessThan, 2, 0, 1), // --
PURE(Int32LessThanOrEqual, 2, 0, 1), // --
PURE(Uint32LessThan, 2, 0, 1), // --
PURE(Uint32LessThanOrEqual, 2, 0, 1), // --
PURE(Int64Add, 2, 0, 1), // --
PURE(Int64Sub, 2, 0, 1), // --
PURE(Int64Mul, 2, 0, 1), // --
PURE(Int64Div, 2, 0, 1), // --
PURE(Uint64Div, 2, 0, 1), // --
PURE(Int64Mod, 2, 0, 1), // --
PURE(Uint64Mod, 2, 0, 1), // --
PURE(Int64LessThan, 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
};
typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
} // namespace
class MachinePureOperatorTest : public TestWithZone {
protected:
MachineType word_type() { return kMachPtr; }
};
TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
const PureOperator& pop = GetParam();
MachineOperatorBuilder machine1(zone(), type());
MachineOperatorBuilder machine2(zone(), type());
EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
TEST_F(MachinePureOperatorTest, PureOperators) {
TRACED_FOREACH(MachineType, machine_rep1, kMachineReps) {
MachineOperatorBuilder machine1(zone(), machine_rep1);
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) {
MachineOperatorBuilder machine(zone(), type());
const PureOperator& pop = GetParam();
const Operator* op = (machine.*pop.constructor)();
// Optional operators.
EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
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));
namespace {
EXPECT_EQ(pop.value_output_count, op->ValueOutputCount());
EXPECT_EQ(0, op->EffectOutputCount());
EXPECT_EQ(0, op->ControlOutputCount());
}
struct OptionalOperatorEntry {
const OptionalOperator (MachineOperatorBuilder::*constructor)();
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) {
MachineOperatorBuilder machine(zone(), type());
const PureOperator& pop = GetParam();
const Operator* op = (machine.*pop.constructor)();
EXPECT_TRUE(op->HasProperty(Operator::kPure));
std::ostream& operator<<(std::ostream& os, OptionalOperatorEntry const& pop) {
return os << pop.constructor_name;
}
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 {
return NewNode(machine()->TruncateInt64ToInt32(), a);
}
Node* Float64RoundDown(Node* a) {
return NewNode(machine()->Float64RoundDown(), a);
return NewNode(machine()->Float64RoundDown().op(), a);
}
Node* Float64RoundTruncate(Node* a) {
return NewNode(machine()->Float64RoundTruncate(), a);
return NewNode(machine()->Float64RoundTruncate().op(), a);
}
Node* Float64RoundTiesAway(Node* a) {
return NewNode(machine()->Float64RoundTiesAway(), a);
return NewNode(machine()->Float64RoundTiesAway().op(), a);
}
// 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