Commit 46eba454 authored by epertoso's avatar epertoso Committed by Commit bot

[turbofan] Move lowering of Float64 optional operators to EffectControlLinearizer.

It's just a refactoring to avoid introducing new floating controls in the SimplifiedLowering phase.

R=bmeurer@chromium.org

Review-Url: https://codereview.chromium.org/2215183003
Cr-Commit-Position: refs/heads/master@{#38365}
parent 9d5e6129
...@@ -732,6 +732,15 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node, ...@@ -732,6 +732,15 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
case IrOpcode::kStoreTypedElement: case IrOpcode::kStoreTypedElement:
state = LowerStoreTypedElement(node, *effect, *control); state = LowerStoreTypedElement(node, *effect, *control);
break; break;
case IrOpcode::kFloat64RoundUp:
state = LowerFloat64RoundUp(node, *effect, *control);
break;
case IrOpcode::kFloat64RoundDown:
state = LowerFloat64RoundDown(node, *effect, *control);
break;
case IrOpcode::kFloat64RoundTruncate:
state = LowerFloat64RoundTruncate(node, *effect, *control);
break;
default: default:
return false; return false;
} }
...@@ -2702,6 +2711,390 @@ EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect, ...@@ -2702,6 +2711,390 @@ EffectControlLinearizer::LowerStoreTypedElement(Node* node, Node* effect,
return ValueEffectControl(nullptr, effect, control); return ValueEffectControl(nullptr, effect, control);
} }
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerFloat64RoundUp(Node* node, Node* effect,
Node* control) {
// Nothing to be done if a fast hardware instruction is available.
if (machine()->Float64RoundUp().IsSupported()) {
return ValueEffectControl(node, effect, control);
}
Node* const one = jsgraph()->Float64Constant(1.0);
Node* const zero = jsgraph()->Float64Constant(0.0);
Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
Node* const input = node->InputAt(0);
// General case for ceil.
//
// if 0.0 < input then
// if 2^52 <= input then
// input
// else
// let temp1 = (2^52 + input) - 2^52 in
// if temp1 < input then
// temp1 + 1
// else
// temp1
// else
// if input == 0 then
// input
// else
// if input <= -2^52 then
// input
// else
// let temp1 = -0 - input in
// let temp2 = (2^52 + temp1) - 2^52 in
// let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
// -0 - temp3
//
// Note: We do not use the Diamond helper class here, because it really hurts
// readability with nested diamonds.
Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
Node* branch0 =
graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
Node* vtrue0;
{
Node* check1 =
graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* temp1 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
vfalse1 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp1, input),
graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
}
if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_true0);
}
Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
Node* vfalse0;
{
Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check1, if_false0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
input, minus_two_52);
Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check2, if_false1);
Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
Node* vtrue2 = input;
Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
Node* vfalse2;
{
Node* temp1 =
graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
Node* temp2 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
Node* temp3 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
}
if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
vfalse1 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue2, vfalse2, if_false1);
}
if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vfalse0 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_false0);
}
Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
Node* value =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue0, vfalse0, merge0);
return ValueEffectControl(value, effect, merge0);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerFloat64RoundDown(Node* node, Node* effect,
Node* control) {
// Nothing to be done if a fast hardware instruction is available.
if (machine()->Float64RoundDown().IsSupported()) {
return ValueEffectControl(node, effect, control);
}
Node* const one = jsgraph()->Float64Constant(1.0);
Node* const zero = jsgraph()->Float64Constant(0.0);
Node* const minus_one = jsgraph()->Float64Constant(-1.0);
Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
Node* const input = node->InputAt(0);
// General case for floor.
//
// if 0.0 < input then
// if 2^52 <= input then
// input
// else
// let temp1 = (2^52 + input) - 2^52 in
// if input < temp1 then
// temp1 - 1
// else
// temp1
// else
// if input == 0 then
// input
// else
// if input <= -2^52 then
// input
// else
// let temp1 = -0 - input in
// let temp2 = (2^52 + temp1) - 2^52 in
// if temp2 < temp1 then
// -1 - temp2
// else
// -0 - temp2
//
// Note: We do not use the Diamond helper class here, because it really hurts
// readability with nested diamonds.
Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
Node* branch0 =
graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
Node* vtrue0;
{
Node* check1 =
graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* temp1 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
vfalse1 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), input, temp1),
graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
}
if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_true0);
}
Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
Node* vfalse0;
{
Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check1, if_false0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
input, minus_two_52);
Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check2, if_false1);
Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
Node* vtrue2 = input;
Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
Node* vfalse2;
{
Node* temp1 =
graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
Node* temp2 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
vfalse2 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp2, temp1),
graph()->NewNode(machine()->Float64Sub(), minus_one, temp2),
graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2));
}
if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
vfalse1 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue2, vfalse2, if_false1);
}
if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vfalse0 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_false0);
}
Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
Node* value =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue0, vfalse0, merge0);
return ValueEffectControl(value, effect, merge0);
}
EffectControlLinearizer::ValueEffectControl
EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node, Node* effect,
Node* control) {
// Nothing to be done if a fast hardware instruction is available.
if (machine()->Float64RoundTruncate().IsSupported()) {
return ValueEffectControl(node, effect, control);
}
Node* const one = jsgraph()->Float64Constant(1.0);
Node* const zero = jsgraph()->Float64Constant(0.0);
Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
Node* const input = node->InputAt(0);
// General case for trunc.
//
// if 0.0 < input then
// if 2^52 <= input then
// input
// else
// let temp1 = (2^52 + input) - 2^52 in
// if input < temp1 then
// temp1 - 1
// else
// temp1
// else
// if input == 0 then
// input
// else
// if input <= -2^52 then
// input
// else
// let temp1 = -0 - input in
// let temp2 = (2^52 + temp1) - 2^52 in
// let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
// -0 - temp3
//
// Note: We do not use the Diamond helper class here, because it really hurts
// readability with nested diamonds.
Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
Node* branch0 =
graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
Node* vtrue0;
{
Node* check1 =
graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* temp1 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
vfalse1 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), input, temp1),
graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
}
if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_true0);
}
Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
Node* vfalse0;
{
Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check1, if_false0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
input, minus_two_52);
Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check2, if_false1);
Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
Node* vtrue2 = input;
Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
Node* vfalse2;
{
Node* temp1 =
graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
Node* temp2 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
Node* temp3 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
}
if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
vfalse1 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue2, vfalse2, if_false1);
}
if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vfalse0 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_false0);
}
Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
Node* value =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue0, vfalse0, merge0);
return ValueEffectControl(value, effect, merge0);
}
Factory* EffectControlLinearizer::factory() const { Factory* EffectControlLinearizer::factory() const {
return isolate()->factory(); return isolate()->factory();
} }
......
...@@ -143,6 +143,14 @@ class EffectControlLinearizer { ...@@ -143,6 +143,14 @@ class EffectControlLinearizer {
ValueEffectControl LowerStoreTypedElement(Node* node, Node* effect, ValueEffectControl LowerStoreTypedElement(Node* node, Node* effect,
Node* control); Node* control);
// Lowering of optional operators.
ValueEffectControl LowerFloat64RoundUp(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerFloat64RoundDown(Node* node, Node* effect,
Node* control);
ValueEffectControl LowerFloat64RoundTruncate(Node* node, Node* effect,
Node* control);
ValueEffectControl AllocateHeapNumberWithValue(Node* node, Node* effect, ValueEffectControl AllocateHeapNumberWithValue(Node* node, Node* effect,
Node* control); Node* control);
ValueEffectControl BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode, ValueEffectControl BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
......
...@@ -719,6 +719,8 @@ const Operator* RepresentationChanger::Float64OperatorFor( ...@@ -719,6 +719,8 @@ const Operator* RepresentationChanger::Float64OperatorFor(
return machine()->Float64Atan2(); return machine()->Float64Atan2();
case IrOpcode::kNumberCbrt: case IrOpcode::kNumberCbrt:
return machine()->Float64Cbrt(); return machine()->Float64Cbrt();
case IrOpcode::kNumberCeil:
return machine()->Float64RoundUp().placeholder();
case IrOpcode::kNumberCos: case IrOpcode::kNumberCos:
return machine()->Float64Cos(); return machine()->Float64Cos();
case IrOpcode::kNumberCosh: case IrOpcode::kNumberCosh:
...@@ -727,6 +729,8 @@ const Operator* RepresentationChanger::Float64OperatorFor( ...@@ -727,6 +729,8 @@ const Operator* RepresentationChanger::Float64OperatorFor(
return machine()->Float64Exp(); return machine()->Float64Exp();
case IrOpcode::kNumberExpm1: case IrOpcode::kNumberExpm1:
return machine()->Float64Expm1(); return machine()->Float64Expm1();
case IrOpcode::kNumberFloor:
return machine()->Float64RoundDown().placeholder();
case IrOpcode::kNumberFround: case IrOpcode::kNumberFround:
return machine()->TruncateFloat64ToFloat32(); return machine()->TruncateFloat64ToFloat32();
case IrOpcode::kNumberLog: case IrOpcode::kNumberLog:
...@@ -753,6 +757,8 @@ const Operator* RepresentationChanger::Float64OperatorFor( ...@@ -753,6 +757,8 @@ const Operator* RepresentationChanger::Float64OperatorFor(
return machine()->Float64Tan(); return machine()->Float64Tan();
case IrOpcode::kNumberTanh: case IrOpcode::kNumberTanh:
return machine()->Float64Tanh(); return machine()->Float64Tanh();
case IrOpcode::kNumberTrunc:
return machine()->Float64RoundTruncate().placeholder();
case IrOpcode::kNumberSilenceNaN: case IrOpcode::kNumberSilenceNaN:
return machine()->Float64SilenceNaN(); return machine()->Float64SilenceNaN();
default: default:
......
...@@ -1870,18 +1870,6 @@ class RepresentationSelector { ...@@ -1870,18 +1870,6 @@ class RepresentationSelector {
if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
return; return;
} }
case IrOpcode::kNumberCeil: {
VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64);
if (lower()) DeferReplacement(node, lowering->Float64Ceil(node));
return;
}
case IrOpcode::kNumberFloor: {
VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64);
if (lower()) DeferReplacement(node, lowering->Float64Floor(node));
return;
}
case IrOpcode::kNumberFround: { case IrOpcode::kNumberFround: {
VisitUnop(node, UseInfo::TruncatingFloat64(), VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat32); MachineRepresentation::kFloat32);
...@@ -1953,10 +1941,12 @@ class RepresentationSelector { ...@@ -1953,10 +1941,12 @@ class RepresentationSelector {
case IrOpcode::kNumberAsinh: case IrOpcode::kNumberAsinh:
case IrOpcode::kNumberAtan: case IrOpcode::kNumberAtan:
case IrOpcode::kNumberAtanh: case IrOpcode::kNumberAtanh:
case IrOpcode::kNumberCeil:
case IrOpcode::kNumberCos: case IrOpcode::kNumberCos:
case IrOpcode::kNumberCosh: case IrOpcode::kNumberCosh:
case IrOpcode::kNumberExp: case IrOpcode::kNumberExp:
case IrOpcode::kNumberExpm1: case IrOpcode::kNumberExpm1:
case IrOpcode::kNumberFloor:
case IrOpcode::kNumberLog: case IrOpcode::kNumberLog:
case IrOpcode::kNumberLog1p: case IrOpcode::kNumberLog1p:
case IrOpcode::kNumberLog2: case IrOpcode::kNumberLog2:
...@@ -1965,7 +1955,8 @@ class RepresentationSelector { ...@@ -1965,7 +1955,8 @@ class RepresentationSelector {
case IrOpcode::kNumberSin: case IrOpcode::kNumberSin:
case IrOpcode::kNumberSinh: case IrOpcode::kNumberSinh:
case IrOpcode::kNumberTan: case IrOpcode::kNumberTan:
case IrOpcode::kNumberTanh: { case IrOpcode::kNumberTanh:
case IrOpcode::kNumberTrunc: {
VisitUnop(node, UseInfo::TruncatingFloat64(), VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64); MachineRepresentation::kFloat64);
if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
...@@ -1995,12 +1986,6 @@ class RepresentationSelector { ...@@ -1995,12 +1986,6 @@ class RepresentationSelector {
if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
return; return;
} }
case IrOpcode::kNumberTrunc: {
VisitUnop(node, UseInfo::TruncatingFloat64(),
MachineRepresentation::kFloat64);
if (lower()) DeferReplacement(node, lowering->Float64Trunc(node));
return;
}
case IrOpcode::kNumberToInt32: { case IrOpcode::kNumberToInt32: {
// Just change representation if necessary. // Just change representation if necessary.
VisitUnop(node, UseInfo::TruncatingWord32(), VisitUnop(node, UseInfo::TruncatingWord32(),
...@@ -2927,262 +2912,14 @@ void SimplifiedLowering::DoStoreBuffer(Node* node) { ...@@ -2927,262 +2912,14 @@ void SimplifiedLowering::DoStoreBuffer(Node* node) {
NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); NodeProperties::ChangeOp(node, machine()->CheckedStore(rep));
} }
Node* SimplifiedLowering::Float64Ceil(Node* const node) {
Node* const one = jsgraph()->Float64Constant(1.0);
Node* const zero = jsgraph()->Float64Constant(0.0);
Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
Node* const input = node->InputAt(0);
// Use fast hardware instruction if available.
if (machine()->Float64RoundUp().IsSupported()) {
return graph()->NewNode(machine()->Float64RoundUp().op(), input);
}
// General case for ceil.
//
// if 0.0 < input then
// if 2^52 <= input then
// input
// else
// let temp1 = (2^52 + input) - 2^52 in
// if temp1 < input then
// temp1 + 1
// else
// temp1
// else
// if input == 0 then
// input
// else
// if input <= -2^52 then
// input
// else
// let temp1 = -0 - input in
// let temp2 = (2^52 + temp1) - 2^52 in
// let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
// -0 - temp3
//
// Note: We do not use the Diamond helper class here, because it really hurts
// readability with nested diamonds.
Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
graph()->start());
Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
Node* vtrue0;
{
Node* check1 =
graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* temp1 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
vfalse1 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp1, input),
graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
}
if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_true0);
}
Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
Node* vfalse0;
{
Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check1, if_false0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
input, minus_two_52);
Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check2, if_false1);
Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
Node* vtrue2 = input;
Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
Node* vfalse2;
{
Node* temp1 =
graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
Node* temp2 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
Node* temp3 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
}
if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
vfalse1 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue2, vfalse2, if_false1);
}
if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vfalse0 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_false0);
}
Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue0, vfalse0, merge0);
}
Node* SimplifiedLowering::Float64Floor(Node* const node) {
Node* const one = jsgraph()->Float64Constant(1.0);
Node* const zero = jsgraph()->Float64Constant(0.0);
Node* const minus_one = jsgraph()->Float64Constant(-1.0);
Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
Node* const input = node->InputAt(0);
// Use fast hardware instruction if available.
if (machine()->Float64RoundDown().IsSupported()) {
return graph()->NewNode(machine()->Float64RoundDown().op(), input);
}
// General case for floor.
//
// if 0.0 < input then
// if 2^52 <= input then
// input
// else
// let temp1 = (2^52 + input) - 2^52 in
// if input < temp1 then
// temp1 - 1
// else
// temp1
// else
// if input == 0 then
// input
// else
// if input <= -2^52 then
// input
// else
// let temp1 = -0 - input in
// let temp2 = (2^52 + temp1) - 2^52 in
// if temp2 < temp1 then
// -1 - temp2
// else
// -0 - temp2
//
// Note: We do not use the Diamond helper class here, because it really hurts
// readability with nested diamonds.
Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
graph()->start());
Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
Node* vtrue0;
{
Node* check1 =
graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* temp1 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
vfalse1 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), input, temp1),
graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
}
if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_true0);
}
Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
Node* vfalse0;
{
Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check1, if_false0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
input, minus_two_52);
Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check2, if_false1);
Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
Node* vtrue2 = input;
Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
Node* vfalse2;
{
Node* temp1 =
graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
Node* temp2 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
vfalse2 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp2, temp1),
graph()->NewNode(machine()->Float64Sub(), minus_one, temp2),
graph()->NewNode(machine()->Float64Sub(), minus_zero, temp2));
}
if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
vfalse1 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue2, vfalse2, if_false1);
}
if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vfalse0 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_false0);
}
Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue0, vfalse0, merge0);
}
Node* SimplifiedLowering::Float64Round(Node* const node) { Node* SimplifiedLowering::Float64Round(Node* const node) {
Node* const one = jsgraph()->Float64Constant(1.0); Node* const one = jsgraph()->Float64Constant(1.0);
Node* const one_half = jsgraph()->Float64Constant(0.5); Node* const one_half = jsgraph()->Float64Constant(0.5);
Node* const input = node->InputAt(0); Node* const input = node->InputAt(0);
// Round up towards Infinity, and adjust if the difference exceeds 0.5. // Round up towards Infinity, and adjust if the difference exceeds 0.5.
Node* result = Float64Ceil(node); Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
node->InputAt(0));
return graph()->NewNode( return graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64), common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode( graph()->NewNode(
...@@ -3207,129 +2944,6 @@ Node* SimplifiedLowering::Float64Sign(Node* const node) { ...@@ -3207,129 +2944,6 @@ Node* SimplifiedLowering::Float64Sign(Node* const node) {
zero)); zero));
} }
Node* SimplifiedLowering::Float64Trunc(Node* const node) {
Node* const one = jsgraph()->Float64Constant(1.0);
Node* const zero = jsgraph()->Float64Constant(0.0);
Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
Node* const input = node->InputAt(0);
// Use fast hardware instruction if available.
if (machine()->Float64RoundTruncate().IsSupported()) {
return graph()->NewNode(machine()->Float64RoundTruncate().op(), input);
}
// General case for trunc.
//
// if 0.0 < input then
// if 2^52 <= input then
// input
// else
// let temp1 = (2^52 + input) - 2^52 in
// if input < temp1 then
// temp1 - 1
// else
// temp1
// else
// if input == 0 then
// input
// else
// if input <= -2^52 then
// input
// else
// let temp1 = -0 - input in
// let temp2 = (2^52 + temp1) - 2^52 in
// let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
// -0 - temp3
//
// Note: We do not use the Diamond helper class here, because it really hurts
// readability with nested diamonds.
Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
graph()->start());
Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
Node* vtrue0;
{
Node* check1 =
graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* temp1 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
vfalse1 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), input, temp1),
graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
}
if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_true0);
}
Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
Node* vfalse0;
{
Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check1, if_false0);
Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
Node* vtrue1 = input;
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
Node* vfalse1;
{
Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
input, minus_two_52);
Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
check2, if_false1);
Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
Node* vtrue2 = input;
Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
Node* vfalse2;
{
Node* temp1 =
graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
Node* temp2 = graph()->NewNode(
machine()->Float64Sub(),
graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
Node* temp3 = graph()->NewNode(
common()->Select(MachineRepresentation::kFloat64),
graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
}
if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
vfalse1 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue2, vfalse2, if_false1);
}
if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
vfalse0 =
graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue1, vfalse1, if_false0);
}
Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
vtrue0, vfalse0, merge0);
}
Node* SimplifiedLowering::Int32Abs(Node* const node) { Node* SimplifiedLowering::Int32Abs(Node* const node) {
Node* const input = node->InputAt(0); Node* const input = node->InputAt(0);
......
...@@ -60,11 +60,8 @@ class SimplifiedLowering final { ...@@ -60,11 +60,8 @@ class SimplifiedLowering final {
// position information via the SourcePositionWrapper like all other reducers. // position information via the SourcePositionWrapper like all other reducers.
SourcePositionTable* source_positions_; SourcePositionTable* source_positions_;
Node* Float64Ceil(Node* const node);
Node* Float64Floor(Node* const node);
Node* Float64Round(Node* const node); Node* Float64Round(Node* const node);
Node* Float64Sign(Node* const node); Node* Float64Sign(Node* const node);
Node* Float64Trunc(Node* const node);
Node* Int32Abs(Node* const node); Node* Int32Abs(Node* const node);
Node* Int32Div(Node* const node); Node* Int32Div(Node* const node);
Node* Int32Mod(Node* const node); Node* Int32Mod(Node* const node);
......
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