Bug 1240796 - Inline SIMD operations that return scalars. r=bbouvier
authorJakob Stoklund Olesen <jolesen@mozilla.com>
Mon, 01 Feb 2016 14:55:06 -0800
changeset 282638 8c519f3497f9140afb80b5bec570b8d5557e05fd
parent 282637 449c568f3dc59845245086884a3cf56af2aa5fd4
child 282639 b91653bb5ab5417ad4e3887f91d50b4a62e15c6d
push id17362
push usercbook@mozilla.com
push dateTue, 02 Feb 2016 10:54:53 +0000
treeherderfx-team@e5f1b4782e38 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1240796
milestone47.0a1
Bug 1240796 - Inline SIMD operations that return scalars. r=bbouvier The extractLane(), anyTrue(), and allTrue() SIMD functions produce scalar values, and so they don't need a template object. The canInlineSimd() function was rejecting these functions because of the missing template object. At the same time, explicitly avoid inlining any SIMD operations if the JIT does not support SIMD. This was previously controlled by the absense of the template object.
js/src/jit/MCallOptimize.cpp
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -3055,16 +3055,21 @@ IonBuilder::inlineConstructTypedObject(C
 
     return InliningStatus_Inlined;
 }
 
 // Main entry point for SIMD inlining.
 IonBuilder::InliningStatus
 IonBuilder::inlineSimd(CallInfo& callInfo, JSFunction* target, MIRType simdType)
 {
+    if (!JitSupportsSimd()) {
+        trackOptimizationOutcome(TrackedOutcome::NoSimdJitSupport);
+        return InliningStatus_NotInlined;
+    }
+
     JSNative native = target->native();
     const JSJitInfo* jitInfo = target->jitInfo();
     MOZ_ASSERT(jitInfo && jitInfo->type() == JSJitInfo::InlinableNative);
     SimdOperation simdOp = SimdOperation(jitInfo->nativeOp);
     MOZ_ASSERT(IsSimdType(simdType));
 
     switch(simdOp) {
       case SimdOperation::Constructor:
@@ -3257,16 +3262,21 @@ bool SimdTypeToMIRType(SimdType type, MI
       case SimdType::Bool32x4:    *mirType = MIRType_Bool32x4;  return true;
       default:                    return false;
     }
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
 {
+    if (!JitSupportsSimd()) {
+        trackOptimizationOutcome(TrackedOutcome::NoSimdJitSupport);
+        return InliningStatus_NotInlined;
+    }
+
     // Generic constructor of SIMD valuesX4.
     MIRType simdType;
     if (!SimdTypeToMIRType(descr->type(), &simdType))
         return InliningStatus_NotInlined;
 
     // Take the templateObject out of Baseline ICs, such that we can box
     // SIMD value type in the same kind of objects.
     MOZ_ASSERT(size_t(descr->size(descr->type())) < InlineTypedObject::MaximumSize);
@@ -3427,19 +3437,22 @@ IonBuilder::inlineSimdSplat(CallInfo& ca
 
     MSimdSplatX4* ins = MSimdSplatX4::New(alloc(), arg, mirType);
     return boxSimd(callInfo, ins, templateObj);
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineSimdExtractLane(CallInfo& callInfo, JSNative native, MIRType vecType)
 {
-    InlineTypedObject* templateObj = nullptr;
-    if (!canInlineSimd(callInfo, native, 2, &templateObj))
+    // extractLane() returns a scalar, so don't use canInlineSimd() which looks
+    // for a template object.
+    if (callInfo.argc() != 2 || callInfo.constructing()) {
+        trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
+    }
 
     MDefinition* arg = callInfo.getArg(1);
     if (!arg->isConstantValue() || arg->type() != MIRType_Int32)
         return InliningStatus_NotInlined;
     int32_t lane = callInfo.getArg(1)->constantValue().toInt32();
     if (lane < 0 || lane >= 4)
         return InliningStatus_NotInlined;
 
@@ -3528,19 +3541,22 @@ IonBuilder::inlineSimdShuffle(CallInfo& 
         ins->setLane(i, callInfo.getArg(numVectors + i));
 
     return boxSimd(callInfo, ins, templateObj);
 }
 
 IonBuilder::InliningStatus
 IonBuilder::inlineSimdAnyAllTrue(CallInfo& callInfo, bool IsAllTrue, JSNative native)
 {
-    InlineTypedObject* templateObj = nullptr;
-    if (!canInlineSimd(callInfo, native, 1, &templateObj))
+    // anyTrue() / allTrue() return a scalar, so don't use canInlineSimd() which looks
+    // for a template object.
+    if (callInfo.argc() != 1 || callInfo.constructing()) {
+        trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
         return InliningStatus_NotInlined;
+    }
 
     MUnaryInstruction* ins;
     if (IsAllTrue)
         ins = MSimdAllTrue::New(alloc(), callInfo.getArg(0), MIRType_Bool32x4);
     else
         ins = MSimdAnyTrue::New(alloc(), callInfo.getArg(0), MIRType_Bool32x4);
 
     current->add(ins);