Bug 1136226 - Enable inlining of 8x16 and 16x8 types. r=sunfish
authorJakob Olesen <jolesen@mozilla.com>
Tue, 31 May 2016 09:00:20 -0700
changeset 338740 c19c99878a6076e928690f45b37403b110cd5482
parent 338739 4314ed7441b656c689d98d54996dcd524f80b72a
child 338741 5da8ebecdfb7ce16dc5a1ef242bea1287b132123
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1136226
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1136226 - Enable inlining of 8x16 and 16x8 types. r=sunfish
js/src/builtin/SIMD.cpp
js/src/jit/BaselineIC.cpp
js/src/jit/InlinableNatives.h
js/src/jit/MCallOptimize.cpp
js/src/jit/Recover.cpp
js/src/jit/shared/CodeGenerator-shared.cpp
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -272,24 +272,48 @@ static_assert(uint64_t(SimdOperation::La
     /* Remaining fields are not used for inlinable natives. They are zero-initialized. */        \
 };
 
 // This list of inlinable types should match the one in jit/InlinableNatives.h.
 #define TDEFN(Name, Func, Operands) DEFN(Float32x4, Name)
 FLOAT32X4_FUNCTION_LIST(TDEFN)
 #undef TDEFN
 
+#define TDEFN(Name, Func, Operands) DEFN(Int8x16, Name)
+INT8X16_FUNCTION_LIST(TDEFN)
+#undef TDEFN
+
+#define TDEFN(Name, Func, Operands) DEFN(Uint8x16, Name)
+UINT8X16_FUNCTION_LIST(TDEFN)
+#undef TDEFN
+
+#define TDEFN(Name, Func, Operands) DEFN(Int16x8, Name)
+INT16X8_FUNCTION_LIST(TDEFN)
+#undef TDEFN
+
+#define TDEFN(Name, Func, Operands) DEFN(Uint16x8, Name)
+UINT16X8_FUNCTION_LIST(TDEFN)
+#undef TDEFN
+
 #define TDEFN(Name, Func, Operands) DEFN(Int32x4, Name)
 INT32X4_FUNCTION_LIST(TDEFN)
 #undef TDEFN
 
 #define TDEFN(Name, Func, Operands) DEFN(Uint32x4, Name)
 UINT32X4_FUNCTION_LIST(TDEFN)
 #undef TDEFN
 
+#define TDEFN(Name, Func, Operands) DEFN(Bool8x16, Name)
+BOOL8X16_FUNCTION_LIST(TDEFN)
+#undef TDEFN
+
+#define TDEFN(Name, Func, Operands) DEFN(Bool16x8, Name)
+BOOL16X8_FUNCTION_LIST(TDEFN)
+#undef TDEFN
+
 #define TDEFN(Name, Func, Operands) DEFN(Bool32x4, Name)
 BOOL32X4_FUNCTION_LIST(TDEFN)
 #undef TDEFN
 
 } // namespace jit
 } // namespace js
 
 const JSFunctionSpec Float32x4Defn::Methods[] = {
@@ -305,73 +329,73 @@ const JSFunctionSpec Float64x2Defn::Meth
     JS_FN(#Name, js::simd_float64x2_##Name, Operands, 0),
     FLOAT64X2_FUNCTION_LIST(SIMD_FLOAT64X2_FUNCTION_ITEM)
 #undef SIMD_FLOAT64X2_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Int8x16Defn::Methods[] = {
 #define SIMD_INT8X16_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_int8x16_##Name, Operands, 0),
+    JS_INLINABLE_FN(#Name, js::simd_int8x16_##Name, Operands, 0, SimdInt8x16_##Name),
     INT8X16_FUNCTION_LIST(SIMD_INT8X16_FUNCTION_ITEM)
 #undef SIMD_INT8X16_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Int16x8Defn::Methods[] = {
 #define SIMD_INT16X8_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_int16x8_##Name, Operands, 0),
+    JS_INLINABLE_FN(#Name, js::simd_int16x8_##Name, Operands, 0, SimdInt16x8_##Name),
     INT16X8_FUNCTION_LIST(SIMD_INT16X8_FUNCTION_ITEM)
 #undef SIMD_INT16X8_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Int32x4Defn::Methods[] = {
 #define SIMD_INT32X4_FUNCTION_ITEM(Name, Func, Operands) \
     JS_INLINABLE_FN(#Name, js::simd_int32x4_##Name, Operands, 0, SimdInt32x4_##Name),
     INT32X4_FUNCTION_LIST(SIMD_INT32X4_FUNCTION_ITEM)
 #undef SIMD_INT32X4_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Uint8x16Defn::Methods[] = {
 #define SIMD_UINT8X16_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_uint8x16_##Name, Operands, 0),
+    JS_INLINABLE_FN(#Name, js::simd_uint8x16_##Name, Operands, 0, SimdUint8x16_##Name),
     UINT8X16_FUNCTION_LIST(SIMD_UINT8X16_FUNCTION_ITEM)
 #undef SIMD_UINT8X16_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Uint16x8Defn::Methods[] = {
 #define SIMD_UINT16X8_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_uint16x8_##Name, Operands, 0),
+    JS_INLINABLE_FN(#Name, js::simd_uint16x8_##Name, Operands, 0, SimdUint16x8_##Name),
     UINT16X8_FUNCTION_LIST(SIMD_UINT16X8_FUNCTION_ITEM)
 #undef SIMD_UINT16X8_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Uint32x4Defn::Methods[] = {
 #define SIMD_UINT32X4_FUNCTION_ITEM(Name, Func, Operands) \
     JS_INLINABLE_FN(#Name, js::simd_uint32x4_##Name, Operands, 0, SimdUint32x4_##Name),
     UINT32X4_FUNCTION_LIST(SIMD_UINT32X4_FUNCTION_ITEM)
 #undef SIMD_UINT32X4_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Bool8x16Defn::Methods[] = {
 #define SIMD_BOOL8X16_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_bool8x16_##Name, Operands, 0),
+    JS_INLINABLE_FN(#Name, js::simd_bool8x16_##Name, Operands, 0, SimdBool8x16_##Name),
     BOOL8X16_FUNCTION_LIST(SIMD_BOOL8X16_FUNCTION_ITEM)
 #undef SIMD_BOOL8X16_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Bool16x8Defn::Methods[] = {
 #define SIMD_BOOL16X8_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_FN(#Name, js::simd_bool16x8_##Name, Operands, 0),
+    JS_INLINABLE_FN(#Name, js::simd_bool16x8_##Name, Operands, 0, SimdBool16x8_##Name),
     BOOL16X8_FUNCTION_LIST(SIMD_BOOL16X8_FUNCTION_ITEM)
 #undef SIMD_BOOL16X8_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Bool32x4Defn::Methods[] = {
 #define SIMD_BOOL32X4_FUNCTION_ITEM(Name, Func, Operands) \
     JS_INLINABLE_FN(#Name, js::simd_bool32x4_##Name, Operands, 0, SimdBool32x4_##Name),
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -5418,19 +5418,25 @@ GetTemplateObjectForSimd(JSContext* cx, 
 {
     const JSJitInfo* jitInfo = target->jitInfo();
     if (!jitInfo || jitInfo->type() != JSJitInfo::InlinableNative)
         return false;
 
     // Check if this is a native inlinable SIMD operation.
     SimdType ctrlType;
     switch (jitInfo->inlinableNative) {
+      case InlinableNative::SimdInt8x16:   ctrlType = SimdType::Int8x16;   break;
+      case InlinableNative::SimdUint8x16:  ctrlType = SimdType::Uint8x16;  break;
+      case InlinableNative::SimdInt16x8:   ctrlType = SimdType::Int16x8;   break;
+      case InlinableNative::SimdUint16x8:  ctrlType = SimdType::Uint16x8;  break;
       case InlinableNative::SimdInt32x4:   ctrlType = SimdType::Int32x4;   break;
       case InlinableNative::SimdUint32x4:  ctrlType = SimdType::Uint32x4;  break;
       case InlinableNative::SimdFloat32x4: ctrlType = SimdType::Float32x4; break;
+      case InlinableNative::SimdBool8x16:  ctrlType = SimdType::Bool8x16;  break;
+      case InlinableNative::SimdBool16x8:  ctrlType = SimdType::Bool16x8;  break;
       case InlinableNative::SimdBool32x4:  ctrlType = SimdType::Bool32x4;  break;
       // This is not an inlinable SIMD operation.
       default: return false;
     }
 
     // The controlling type is not necessarily the return type.
     // Check the actual operation.
     SimdOperation simdOp = SimdOperation(jitInfo->nativeOp);
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -79,18 +79,24 @@
                                     \
     _(IntrinsicStringReplaceString) \
     _(IntrinsicStringSplitString)   \
                                     \
     _(ObjectCreate)                 \
                                     \
     _(SimdInt32x4)                  \
     _(SimdUint32x4)                 \
+    _(SimdInt16x8)                  \
+    _(SimdUint16x8)                 \
+    _(SimdInt8x16)                  \
+    _(SimdUint8x16)                 \
     _(SimdFloat32x4)                \
     _(SimdBool32x4)                 \
+    _(SimdBool16x8)                 \
+    _(SimdBool8x16)                 \
                                     \
     _(TestBailout)                  \
     _(TestAssertFloat32)            \
     _(TestAssertRecoveredOnBailout) \
                                     \
     _(IntrinsicUnsafeSetReservedSlot) \
     _(IntrinsicUnsafeGetReservedSlot) \
     _(IntrinsicUnsafeGetObjectFromReservedSlot) \
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -211,20 +211,32 @@ IonBuilder::inlineNativeCall(CallInfo& c
       case InlinableNative::ObjectCreate:
         return inlineObjectCreate(callInfo);
 
       // SIMD natives.
       case InlinableNative::SimdInt32x4:
         return inlineSimd(callInfo, target, SimdType::Int32x4);
       case InlinableNative::SimdUint32x4:
         return inlineSimd(callInfo, target, SimdType::Uint32x4);
+      case InlinableNative::SimdInt16x8:
+        return inlineSimd(callInfo, target, SimdType::Int16x8);
+      case InlinableNative::SimdUint16x8:
+        return inlineSimd(callInfo, target, SimdType::Uint16x8);
+      case InlinableNative::SimdInt8x16:
+        return inlineSimd(callInfo, target, SimdType::Int8x16);
+      case InlinableNative::SimdUint8x16:
+        return inlineSimd(callInfo, target, SimdType::Uint8x16);
       case InlinableNative::SimdFloat32x4:
         return inlineSimd(callInfo, target, SimdType::Float32x4);
       case InlinableNative::SimdBool32x4:
         return inlineSimd(callInfo, target, SimdType::Bool32x4);
+      case InlinableNative::SimdBool16x8:
+        return inlineSimd(callInfo, target, SimdType::Bool16x8);
+      case InlinableNative::SimdBool8x16:
+        return inlineSimd(callInfo, target, SimdType::Bool8x16);
 
       // Testing functions.
       case InlinableNative::TestBailout:
         return inlineBailout(callInfo);
       case InlinableNative::TestAssertFloat32:
         return inlineAssertFloat32(callInfo);
       case InlinableNative::TestAssertRecoveredOnBailout:
         return inlineAssertRecoveredOnBailout(callInfo);
@@ -3323,26 +3335,28 @@ IonBuilder::inlineSimd(CallInfo& callInf
       case SimdOperation::Fn_store1:
         return inlineSimdStore(callInfo, native, type, 1);
       case SimdOperation::Fn_store2:
         return inlineSimdStore(callInfo, native, type, 2);
       case SimdOperation::Fn_store3:
         return inlineSimdStore(callInfo, native, type, 3);
 
         // Bitcasts. One for each type with a memory representation.
-      case SimdOperation::Fn_fromInt8x16Bits:
-      case SimdOperation::Fn_fromInt16x8Bits:
-        return InliningStatus_NotInlined;
       case SimdOperation::Fn_fromInt32x4Bits:
         return inlineSimdConvert(callInfo, native, true, SimdType::Int32x4, type);
       case SimdOperation::Fn_fromUint32x4Bits:
         return inlineSimdConvert(callInfo, native, true, SimdType::Uint32x4, type);
-      case SimdOperation::Fn_fromUint8x16Bits:
+      case SimdOperation::Fn_fromInt16x8Bits:
+        return inlineSimdConvert(callInfo, native, true, SimdType::Int16x8, type);
       case SimdOperation::Fn_fromUint16x8Bits:
-        return InliningStatus_NotInlined;
+        return inlineSimdConvert(callInfo, native, true, SimdType::Uint16x8, type);
+      case SimdOperation::Fn_fromInt8x16Bits:
+        return inlineSimdConvert(callInfo, native, true, SimdType::Int8x16, type);
+      case SimdOperation::Fn_fromUint8x16Bits:
+        return inlineSimdConvert(callInfo, native, true, SimdType::Uint8x16, type);
       case SimdOperation::Fn_fromFloat32x4Bits:
         return inlineSimdConvert(callInfo, native, true, SimdType::Float32x4, type);
       case SimdOperation::Fn_fromFloat64x2Bits:
         return InliningStatus_NotInlined;
     }
 
     MOZ_CRASH("Unexpected SIMD opcode");
 }
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -1349,49 +1349,49 @@ bool
 RSimdBox::recover(JSContext* cx, SnapshotIterator& iter) const
 {
     JSObject* resultObject = nullptr;
     RValueAllocation a = iter.readAllocation();
     MOZ_ASSERT(iter.allocationReadable(a));
     MOZ_ASSERT_IF(a.mode() == RValueAllocation::ANY_FLOAT_REG, a.fpuReg().isSimd128());
     const FloatRegisters::RegisterContent* raw = iter.floatAllocationPointer(a);
     switch (SimdType(type_)) {
+      case SimdType::Bool8x16:
+        resultObject = js::CreateSimd<Bool8x16>(cx, (const Bool8x16::Elem*) raw);
+        break;
+      case SimdType::Int8x16:
+        resultObject = js::CreateSimd<Int8x16>(cx, (const Int8x16::Elem*) raw);
+        break;
+      case SimdType::Uint8x16:
+        resultObject = js::CreateSimd<Uint8x16>(cx, (const Uint8x16::Elem*) raw);
+        break;
+      case SimdType::Bool16x8:
+        resultObject = js::CreateSimd<Bool16x8>(cx, (const Bool16x8::Elem*) raw);
+        break;
+      case SimdType::Int16x8:
+        resultObject = js::CreateSimd<Int16x8>(cx, (const Int16x8::Elem*) raw);
+        break;
+      case SimdType::Uint16x8:
+        resultObject = js::CreateSimd<Uint16x8>(cx, (const Uint16x8::Elem*) raw);
+        break;
       case SimdType::Bool32x4:
         resultObject = js::CreateSimd<Bool32x4>(cx, (const Bool32x4::Elem*) raw);
         break;
       case SimdType::Int32x4:
         resultObject = js::CreateSimd<Int32x4>(cx, (const Int32x4::Elem*) raw);
         break;
       case SimdType::Uint32x4:
         resultObject = js::CreateSimd<Uint32x4>(cx, (const Uint32x4::Elem*) raw);
         break;
       case SimdType::Float32x4:
         resultObject = js::CreateSimd<Float32x4>(cx, (const Float32x4::Elem*) raw);
         break;
       case SimdType::Float64x2:
         MOZ_CRASH("NYI, RSimdBox of Float64x2");
         break;
-      case SimdType::Int8x16:
-        MOZ_CRASH("NYI, RSimdBox of Int8x16");
-        break;
-      case SimdType::Int16x8:
-        MOZ_CRASH("NYI, RSimdBox of Int16x8");
-        break;
-      case SimdType::Uint8x16:
-        MOZ_CRASH("NYI, RSimdBox of UInt8x16");
-        break;
-      case SimdType::Uint16x8:
-        MOZ_CRASH("NYI, RSimdBox of UInt16x8");
-        break;
-      case SimdType::Bool8x16:
-        MOZ_CRASH("NYI, RSimdBox of Bool8x16");
-        break;
-      case SimdType::Bool16x8:
-        MOZ_CRASH("NYI, RSimdBox of Bool16x8");
-        break;
       case SimdType::Bool64x2:
         MOZ_CRASH("NYI, RSimdBox of Bool64x2");
         break;
       case SimdType::Count:
         MOZ_CRASH("RSimdBox of Count is unreachable");
     }
 
     if (!resultObject)
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -453,19 +453,23 @@ CodeGeneratorShared::encodeAllocation(LS
             alloc = RValueAllocation::Typed(valueType, ToStackIndex(payload));
         else if (payload->isGeneralReg())
             alloc = RValueAllocation::Typed(valueType, ToRegister(payload));
         else if (payload->isFloatReg())
             alloc = RValueAllocation::Double(ToFloatRegister(payload));
         break;
       }
       case MIRType::Float32:
-      case MIRType::Bool32x4:
+      case MIRType::Int8x16:
+      case MIRType::Int16x8:
       case MIRType::Int32x4:
       case MIRType::Float32x4:
+      case MIRType::Bool8x16:
+      case MIRType::Bool16x8:
+      case MIRType::Bool32x4:
       {
         LAllocation* payload = snapshot->payloadOfSlot(*allocIndex);
         if (payload->isConstant()) {
             MConstant* constant = mir->toConstant();
             uint32_t index;
             masm.propagateOOM(graph.addConstantToPool(constant->toJSValue(), &index));
             alloc = RValueAllocation::ConstantPool(index);
             break;