From b1e7adaad5c2ff3de5158d6c36f6ddc8cb7864fb Mon Sep 17 00:00:00 2001 From: Sean Stangl Date: Thu, 7 Nov 2013 15:19:55 -0800 Subject: [PATCH] Bug 936234 - Inline n-Ary Math.min and Math.max. r=shu --- js/src/jit/MCallOptimize.cpp | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 706f70e5727..82b7e527adb 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -883,32 +883,36 @@ IonBuilder::inlineMathFRound(CallInfo &callInfo) IonBuilder::InliningStatus IonBuilder::inlineMathMinMax(CallInfo &callInfo, bool max) { - if (callInfo.argc() != 2 || callInfo.constructing()) + if (callInfo.argc() < 2 || callInfo.constructing()) return InliningStatus_NotInlined; MIRType returnType = getInlineReturnType(); if (!IsNumberType(returnType)) return InliningStatus_NotInlined; - MIRType arg0Type = callInfo.getArg(0)->type(); - if (!IsNumberType(arg0Type)) - return InliningStatus_NotInlined; - MIRType arg1Type = callInfo.getArg(1)->type(); - if (!IsNumberType(arg1Type)) - return InliningStatus_NotInlined; + for (unsigned i = 0; i < callInfo.argc(); i++) { + MIRType argType = callInfo.getArg(i)->type(); + if (!IsNumberType(argType)) + return InliningStatus_NotInlined; - if (returnType == MIRType_Int32 && - (arg0Type == MIRType_Double || arg1Type == MIRType_Double)) - { - // We would need to inform TI, if we happen to return a double. - return InliningStatus_NotInlined; + // We would need to inform TI if we happen to return a double. + if (returnType == MIRType_Int32 && IsFloatingPointType(argType)) + return InliningStatus_NotInlined; } callInfo.unwrapArgs(); - MMinMax *ins = MMinMax::New(callInfo.getArg(0), callInfo.getArg(1), returnType, max); - current->add(ins); - current->push(ins); + // Chain N-1 MMinMax instructions to compute the MinMax. + MMinMax *last = MMinMax::New(callInfo.getArg(0), callInfo.getArg(1), returnType, max); + current->add(last); + + for (unsigned i = 2; i < callInfo.argc(); i++) { + MMinMax *ins = MMinMax::New(last, callInfo.getArg(i), returnType, max); + current->add(ins); + last = ins; + } + + current->push(last); return InliningStatus_Inlined; }