Commit 83470dee authored by Fanchen Kong's avatar Fanchen Kong Committed by V8 LUCI CQ

[turbofan] Add fast path for Math.pow with small positive integer exponent

For small positive integer exponents, calculate the result with an inlined loop.

This change may improve the average runtime of JetStream2/raytrace for ~8%.

Change-Id: I0e3939dc9c21b0c392c04d61fd197bf618004ab4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3708024
Commit-Queue: Fanchen Kong <fanchen.kong@intel.com>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81341}
parent 258b146b
......@@ -239,6 +239,7 @@ class EffectControlLinearizer {
Maybe<Node*> LowerFloat64RoundDown(Node* node);
Maybe<Node*> LowerFloat64RoundTiesEven(Node* node);
Maybe<Node*> LowerFloat64RoundTruncate(Node* node);
Maybe<Node*> LowerFloat64Pow(Node* node);
Node* AllocateHeapNumberWithValue(Node* node);
Node* BuildCheckedFloat64ToInt32(CheckForMinusZeroMode mode,
......@@ -1377,6 +1378,11 @@ bool EffectControlLinearizer::TryWireInStateEffect(Node* node,
return false;
}
break;
case IrOpcode::kFloat64Pow:
if (!LowerFloat64Pow(node).To(&result)) {
return false;
}
break;
case IrOpcode::kDateNow:
result = LowerDateNow(node);
break;
......@@ -6325,6 +6331,76 @@ Maybe<Node*> EffectControlLinearizer::LowerFloat64RoundTruncate(Node* node) {
return Just(BuildFloat64RoundTruncate(input));
}
Maybe<Node*> EffectControlLinearizer::LowerFloat64Pow(Node* node) {
Node* base = node->InputAt(0);
Node* exponent = node->InputAt(1);
auto float64_pow = __ MakeDeferredLabel();
auto done = __ MakeLabel(MachineRepresentation::kFloat64);
Node* int_exp;
if (exponent->opcode() == IrOpcode::kChangeInt32ToFloat64 ||
exponent->opcode() == IrOpcode::kChangeUint32ToFloat64) {
int_exp = exponent->InputAt(0);
} else {
int_exp = __ RoundFloat64ToInt32(exponent);
Node* check_same =
__ Float64Equal(exponent, __ ChangeInt32ToFloat64(int_exp));
__ GotoIfNot(check_same, &float64_pow);
}
// Calculate Float64Pow with a loop when exponent is integer in range [0,
// 1000]. Use unsigned comparison to handle the bailout to slow path with one
// branch (exponent is less than 0 or too big).
int const max_int_exponent = 1000;
Node* is_small_int =
__ Uint32LessThanOrEqual(int_exp, __ Int32Constant(max_int_exponent));
__ GotoIfNot(is_small_int, &float64_pow);
{
Node* initial_result = __ Float64Constant(1.0);
auto loop_exit = __ MakeLabel(MachineRepresentation::kFloat64);
auto loop = __ MakeLoopLabel(MachineRepresentation::kFloat64,
MachineRepresentation::kWord32,
MachineRepresentation::kFloat64);
__ Goto(&loop, base, int_exp, initial_result);
__ Bind(&loop);
{
Node* base = loop.PhiAt(0);
Node* exponent = loop.PhiAt(1);
Node* result = loop.PhiAt(2);
auto if_odd = __ MakeLabel();
auto if_even = __ MakeLabel();
auto loop_next = __ MakeLabel(MachineRepresentation::kFloat64);
Node* is_zero = __ Word32Equal(exponent, __ Int32Constant(0));
__ GotoIf(is_zero, &loop_exit, result);
Node* check = __ Word32And(exponent, __ Uint32Constant(0x1));
__ Branch(check, &if_odd, &if_even);
__ Bind(&if_odd);
__ Goto(&loop_next, __ Float64Mul(base, result));
__ Bind(&if_even);
__ Goto(&loop_next, result);
__ Bind(&loop_next);
__ Goto(&loop, __ Float64Mul(base, base),
__ Word32Shr(exponent, __ Int32Constant(1)), loop_next.PhiAt(0));
}
__ Bind(&loop_exit);
__ Goto(&done, loop_exit.PhiAt(0));
}
__ Bind(&float64_pow);
__ Goto(&done, __ Float64Pow(base, exponent));
__ Bind(&done);
return Just(done.PhiAt(0));
}
Node* EffectControlLinearizer::LowerFindOrderedHashMapEntry(Node* node) {
Node* table = NodeProperties::GetValueInput(node, 0);
Node* key = NodeProperties::GetValueInput(node, 1);
......
......@@ -64,6 +64,8 @@ class Reducer;
V(Float64LessThanOrEqual) \
V(Float64Mod) \
V(Float64Sub) \
V(Float64Mul) \
V(Float64Pow) \
V(Int32Add) \
V(Int32LessThan) \
V(Int32LessThanOrEqual) \
......
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