Commit b35a7aaf authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Fix '[builtins] Make Math.max and Math.min fast by default.'

Port cb9b8010

Original commit message:
The previous versions of Math.max and Math.min made it difficult to
optimize those (that's why we already have custom code in Crankshaft),
and due to lack of ideas what to do about the variable number of
arguments, we will probably need to stick in special code in TurboFan
as well; so inlining those builtins is off the table, hence there's no
real advantage in having them around as "not quite JS" with extra work
necessary in the optimizing compilers to still make those builtins
somewhat fast in cases where we cannot inline them (also there's a
tricky deopt loop in Crankshaft related to Math.min and Math.max, but
that will be dealt with later).

So to sum up: Instead of trying to make Math.max and Math.min semi-fast
in the optimizing compilers with weird work-arounds support %_Arguments
%_ArgumentsLength, we do provide the optimal code as native builtins
instead and call it a day (which gives a nice performance boost on some
benchmarks).

BUG=

Review URL: https://codereview.chromium.org/1643973002

Cr-Commit-Position: refs/heads/master@{#33611}
parent 5c7134a9
......@@ -166,11 +166,10 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
{
// Check if all parameters done.
__ Subu(a0, a0, Operand(1));
__ Branch(USE_DELAY_SLOT, &done_loop, lt, a0, Operand(zero_reg));
__ Branch(&done_loop, lt, a0, Operand(zero_reg));
// Load the next parameter tagged value into a2.
__ sll(at, a0, kPointerSizeLog2); // In delay slot
__ Addu(at, at, sp);
__ Lsa(at, sp, a0, kPointerSizeLog2);
__ lw(a2, MemOperand(at));
// Load the double value of the parameter into f2, maybe converting the
......@@ -213,7 +212,7 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ bind(&done_convert);
// Perform the actual comparison with the accumulator value on the left hand
// side (d1) and the next parameter value on the right hand side (d2).
// side (f0) and the next parameter value on the right hand side (f2).
Label compare_equal, compare_nan, compare_swap;
__ BranchF(&compare_equal, &compare_nan, eq, f0, f2);
__ BranchF(&compare_swap, nullptr, cc, f0, f2);
......@@ -238,8 +237,7 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
}
__ bind(&done_loop);
__ sll(a3, a3, kPointerSizeLog2);
__ addu(sp, sp, a3);
__ Lsa(sp, sp, a3, kPointerSizeLog2);
__ mov(v0, a1);
__ DropAndRet(1);
}
......
......@@ -165,11 +165,10 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
{
// Check if all parameters done.
__ Dsubu(a0, a0, Operand(1));
__ Branch(USE_DELAY_SLOT, &done_loop, lt, a0, Operand(zero_reg));
__ Branch(&done_loop, lt, a0, Operand(zero_reg));
// Load the next parameter tagged value into a2.
__ dsll(at, a0, kPointerSizeLog2); // In delay slot
__ Daddu(at, at, sp);
__ Dlsa(at, sp, a0, kPointerSizeLog2);
__ ld(a2, MemOperand(at));
// Load the double value of the parameter into f2, maybe converting the
......@@ -177,8 +176,8 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
Label convert, convert_smi, convert_number, done_convert;
__ bind(&convert);
__ JumpIfSmi(a2, &convert_smi);
__ ld(t0, FieldMemOperand(a2, HeapObject::kMapOffset));
__ JumpIfRoot(t0, Heap::kHeapNumberMapRootIndex, &convert_number);
__ ld(a4, FieldMemOperand(a2, HeapObject::kMapOffset));
__ JumpIfRoot(a4, Heap::kHeapNumberMapRootIndex, &convert_number);
{
// Parameter is not a Number, use the ToNumberStub to convert it.
FrameScope scope(masm, StackFrame::INTERNAL);
......@@ -197,7 +196,7 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ ldc1(f0, FieldMemOperand(a1, HeapNumber::kValueOffset));
__ jmp(&done_restore);
__ bind(&restore_smi);
__ SmiToDoubleFPURegister(a1, f0, t0);
__ SmiToDoubleFPURegister(a1, f0, a4);
__ bind(&done_restore);
}
__ SmiUntag(a3);
......@@ -208,11 +207,11 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
__ ldc1(f2, FieldMemOperand(a2, HeapNumber::kValueOffset));
__ jmp(&done_convert);
__ bind(&convert_smi);
__ SmiToDoubleFPURegister(a2, f2, t0);
__ SmiToDoubleFPURegister(a2, f2, a4);
__ bind(&done_convert);
// Perform the actual comparison with the accumulator value on the left hand
// side (d1) and the next parameter value on the right hand side (d2).
// side (f0) and the next parameter value on the right hand side (f2).
Label compare_equal, compare_nan, compare_swap;
__ BranchF(&compare_equal, &compare_nan, eq, f0, f2);
__ BranchF(&compare_swap, nullptr, cc, f0, f2);
......@@ -220,8 +219,10 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
// Left and right hand side are equal, check for -0 vs. +0.
__ bind(&compare_equal);
__ FmoveHigh(t0, reg);
__ Branch(&loop, ne, t0, Operand(0x80000000));
__ FmoveHigh(a4, reg);
// Make a4 unsigned.
__ dsll32(a4, a4, 0);
__ Branch(&loop, ne, a4, Operand(0x8000000000000000));
// Result is on the right hand side.
__ bind(&compare_swap);
......@@ -237,8 +238,7 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
}
__ bind(&done_loop);
__ dsll(a3, a3, kPointerSizeLog2);
__ Daddu(sp, sp, a3);
__ Dlsa(sp, sp, a3, kPointerSizeLog2);
__ mov(v0, a1);
__ DropAndRet(1);
}
......
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