Bug 1238679 - Provide per-operation JSJitInfo for the SIMD functions. r=bbouvier
authorJakob Stoklund Olesen <jolesen@mozilla.com>
Wed, 20 Jan 2016 12:50:06 -0800
changeset 315954 4b183a8cf314cb474607994710e7532836586b82
parent 315953 f3a2bda1e5318e877ebbefe990610c6dc14ffac1
child 315955 01c1a62a453c77b7ba92a48c4398233e749e5dfe
push id5703
push userraliiev@mozilla.com
push dateMon, 07 Mar 2016 14:18:41 +0000
treeherdermozilla-beta@31e373ad5b5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1238679
milestone46.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 1238679 - Provide per-operation JSJitInfo for the SIMD functions. r=bbouvier The InlinableNative enumeration doesn't have an enumerator for every SIMD function, it only enumerates the SIMD types supported by the jit, and Ion uses the JSNative function pointer to identify functions when inlining. Use the uint16_t .nativeOp field in JSJitInfo as a sub-opcode, and give each inlinable SIMD operation its own JSJitInfo with a sub-opcode that identifies the operation. Use the old JSJitInfo SIMD structs from MCallOptimize.cpp to represent the constructor calls. They all have .nativeOp = 0 which corresponds to SimdOperation::Constructor. This will make it easier to identify inlinable SIMD functions in Ion.
js/src/builtin/SIMD.cpp
js/src/jit/MCallOptimize.cpp
--- a/js/src/builtin/SIMD.cpp
+++ b/js/src/builtin/SIMD.cpp
@@ -180,19 +180,60 @@ static const JSFunctionSpec TypeDescript
 };
 
 // Shared TypedObject methods for all SIMD types.
 static const JSFunctionSpec SimdTypedObjectMethods[] = {
     JS_SELF_HOSTED_FN("toSource", "SimdToSource", 0, 0),
     JS_FS_END
 };
 
+// Provide JSJitInfo structs for those types that are supported by Ion.
+// The controlling SIMD type is encoded as the InlinableNative primary opcode.
+// The SimdOperation within the type is encoded in the .depth field.
+//
+// The JS_INLINABLE_FN macro refers to js::JitInfo_##native which we provide as
+// Simd##Type##_##Operation
+
+namespace js {
+namespace jit {
+
+// See also JitInfo_* in MCallOptimize.cpp. We provide a JSJitInfo for all the
+// named functions here. The default JitInfo_SimdInt32x4 etc structs represent the
+// SimdOperation::Constructor.
+#define DEFN(TYPE, OP) const JSJitInfo JitInfo_Simd##TYPE##_##OP = {                             \
+     /* .getter, unused for inlinable natives. */                                                \
+    { nullptr },                                                                                 \
+    /* .inlinableNative, but we have to init first union member: .protoID. */                    \
+    { uint16_t(InlinableNative::Simd##TYPE) },                                                   \
+    /* .nativeOp. Actually initializing first union member .depth. */                            \
+    { uint16_t(SimdOperation::Fn_##OP) },                                                        \
+    /* .type_ bitfield says this in an inlinable native function. */                             \
+    JSJitInfo::InlinableNative                                                                   \
+    /* 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(Int32x4, Name)
+INT32X4_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[] = {
 #define SIMD_FLOAT32X4_FUNCTION_ITEM(Name, Func, Operands) \
-    JS_INLINABLE_FN(#Name, js::simd_float32x4_##Name, Operands, 0, SimdFloat32x4),
+    JS_INLINABLE_FN(#Name, js::simd_float32x4_##Name, Operands, 0, SimdFloat32x4_##Name),
     FLOAT32X4_FUNCTION_LIST(SIMD_FLOAT32X4_FUNCTION_ITEM)
 #undef SIMD_FLOAT32x4_FUNCTION_ITEM
     JS_FS_END
 };
 
 const JSFunctionSpec Float64x2Defn::Methods[]  = {
 #define SIMD_FLOAT64X2_FUNCTION_ITEM(Name, Func, Operands) \
     JS_FN(#Name, js::simd_float64x2_##Name, Operands, 0),
@@ -214,17 +255,17 @@ const JSFunctionSpec Int16x8Defn::Method
     JS_FN(#Name, js::simd_int16x8_##Name, Operands, 0),
     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),
+    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),
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -3690,15 +3690,20 @@ IonBuilder::inlineSimdStore(CallInfo& ca
     callInfo.setImplicitlyUsedUnchecked();
 
     if (!resumeAfter(store))
         return InliningStatus_Error;
 
     return InliningStatus_Inlined;
 }
 
+// Note that SIMD.cpp provides its own JSJitInfo objects for SIMD.foo.* functions.
+// The Simd* objects defined here represent SIMD.foo() constructor calls.
+// They are encoded with .nativeOp = 0. That is the sub-opcode within the SIMD type.
+static_assert(uint16_t(SimdOperation::Constructor) == 0, "Constructor opcode must be 0");
+
 #define ADD_NATIVE(native) const JSJitInfo JitInfo_##native { \
     { nullptr }, { uint16_t(InlinableNative::native) }, { 0 }, JSJitInfo::InlinableNative };
     INLINABLE_NATIVE_LIST(ADD_NATIVE)
 #undef ADD_NATIVE
 
 } // namespace jit
 } // namespace js