Bug 1135038: Inline SIMD.check as guard unbox; r=nbp

This commit is contained in:
Benjamin Bouvier 2015-02-27 09:33:34 +01:00
parent e02a8345ce
commit 869e4462f1
5 changed files with 60 additions and 3 deletions

View File

@ -240,7 +240,8 @@
_(select) \
_(splat) \
_(not) \
_(neg)
_(neg) \
_(check)
#define FOREACH_COMMONX4_SIMD_OP(_) \
ION_COMMONX4_SIMD_OP(_) \
COMP_COMMONX4_TO_INT32X4_SIMD_OP(_) \
@ -253,8 +254,7 @@
_(store) \
_(storeX) \
_(storeXY) \
_(storeXYZ) \
_(check)
_(storeXYZ)
#define FORALL_SIMD_OP(_) \
FOREACH_INT32X4_SIMD_OP(_) \
FOREACH_FLOAT32X4_SIMD_OP(_) \

View File

@ -22,6 +22,13 @@ function assertNear(a, b) {
assertEq((a != a && b != b) || Math.abs(a - b) < 0.001, true);
}
function assertEqVec(v, w) {
assertEq(v.x, w.x);
assertEq(v.y, w.y);
assertEq(v.z, w.z);
assertEq(v.w, w.w);
}
function assertEqX4(vec, arr, ...opts) {
var assertFunc;

View File

@ -0,0 +1,25 @@
load(libdir + 'simd.js');
setJitCompilerOption("ion.warmup.trigger", 50);
function f() {
var f1 = SIMD.float32x4(1, 2, 3, 4);
var i1 = SIMD.int32x4(1, 2, -3, 4);
var i = 0;
try {
for (; i < 150; i++) {
if (i > 148)
i1 = f1;
assertEqVec(SIMD.int32x4.check(i1), i1);
assertEqVec(SIMD.float32x4.check(f1), f1);
}
} catch (ex) {
assertEq(i, 149);
assertEq(ex instanceof TypeError, true);
}
}
f();

View File

@ -827,6 +827,7 @@ class IonBuilder
InliningStatus inlineSimdWith(CallInfo &callInfo, JSNative native, SimdLane lane,
SimdTypeDescr::Type type);
InliningStatus inlineSimdSplat(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type);
InliningStatus inlineSimdCheck(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type);
InliningStatus inlineSimdConvert(CallInfo &callInfo, JSNative native, bool isCast,
SimdTypeDescr::Type from, SimdTypeDescr::Type to);
InliningStatus inlineSimdSelect(CallInfo &callInfo, JSNative native, bool isElementWise,

View File

@ -336,6 +336,11 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSFunction *target)
if (native == js::simd_float32x4_splat)
return inlineSimdSplat(callInfo, native, SimdTypeDescr::TYPE_FLOAT32);
if (native == js::simd_int32x4_check)
return inlineSimdCheck(callInfo, native, SimdTypeDescr::TYPE_INT32);
if (native == js::simd_float32x4_check)
return inlineSimdCheck(callInfo, native, SimdTypeDescr::TYPE_FLOAT32);
typedef bool IsElementWise;
if (native == js::simd_int32x4_select)
return inlineSimdSelect(callInfo, native, IsElementWise(true), SimdTypeDescr::TYPE_INT32);
@ -3075,5 +3080,24 @@ IonBuilder::inlineSimdSelect(CallInfo &callInfo, JSNative native, bool isElement
return boxSimd(callInfo, ins, templateObj);
}
IonBuilder::InliningStatus
IonBuilder::inlineSimdCheck(CallInfo &callInfo, JSNative native, SimdTypeDescr::Type type)
{
InlineTypedObject *templateObj = nullptr;
if (!checkInlineSimd(callInfo, native, type, 1, &templateObj))
return InliningStatus_NotInlined;
MIRType mirType = SimdTypeDescrToMIRType(type);
MSimdUnbox *unbox = MSimdUnbox::New(alloc(), callInfo.getArg(0), mirType);
// Make sure not to remove this unbox!
unbox->setGuard();
current->add(unbox);
current->push(callInfo.getArg(0));
callInfo.setImplicitlyUsedUnchecked();
return InliningStatus_Inlined;
}
} // namespace jit
} // namespace js