[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: Maya Lekova <mslekova@chromium.org> Cr-Commit-Position: refs/heads/main@{#81341}
This commit is contained in:
parent
258b146b1b
commit
83470dee90
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user