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,13 +141,18 @@ CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) { ...@@ -144,13 +141,18 @@ 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(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(LoadStackPointer, Operator::kNoProperties, 0, 0, 1) \
V(LoadFramePointer, 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) \ #define MACHINE_TYPE_LIST(V) \
V(MachFloat32) \ V(MachFloat32) \
...@@ -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) {
......
...@@ -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