Bug 1136226 - Add 16x8 and 8x16 MIRTypes. r=sunfish

This adds 8x16 and 16x8 types to MIRType, but it does not enable inlining of
the corresponding SIMD operations yet.

Explicitly disable the inlining of non-4-lane constructor calls until we have
support for them.
This commit is contained in:
Jakob Olesen 2016-05-09 16:48:30 -07:00
Родитель 14fa218985
Коммит b6fedab1e8
4 изменённых файлов: 93 добавлений и 76 удалений

Просмотреть файл

@ -2525,9 +2525,13 @@ IsResumableMIRType(MIRType type)
case MIRType::MagicOptimizedOut:
case MIRType::MagicUninitializedLexical:
case MIRType::Value:
case MIRType::Float32x4:
case MIRType::Int32x4:
case MIRType::Int16x8:
case MIRType::Int8x16:
case MIRType::Float32x4:
case MIRType::Bool32x4:
case MIRType::Bool16x8:
case MIRType::Bool8x16:
return true;
case MIRType::MagicHole:

Просмотреть файл

@ -259,7 +259,7 @@ BailoutKindString(BailoutKind kind)
static const uint32_t ELEMENT_TYPE_BITS = 5;
static const uint32_t ELEMENT_TYPE_SHIFT = 0;
static const uint32_t ELEMENT_TYPE_MASK = (1 << ELEMENT_TYPE_BITS) - 1;
static const uint32_t VECTOR_SCALE_BITS = 2;
static const uint32_t VECTOR_SCALE_BITS = 3;
static const uint32_t VECTOR_SCALE_SHIFT = ELEMENT_TYPE_BITS + ELEMENT_TYPE_SHIFT;
static const uint32_t VECTOR_SCALE_MASK = (1 << VECTOR_SCALE_BITS) - 1;
@ -430,13 +430,56 @@ enum class MIRType
Shape, // A Shape pointer.
ObjectGroup, // An ObjectGroup pointer.
Last = ObjectGroup,
Float32x4 = Float32 | (2 << VECTOR_SCALE_SHIFT),
// Representing both SIMD.Int32x4 and SIMD.Uint32x4.
// Representing both SIMD.IntBxN and SIMD.UintBxN.
Int8x16 = Int32 | (4 << VECTOR_SCALE_SHIFT),
Int16x8 = Int32 | (3 << VECTOR_SCALE_SHIFT),
Int32x4 = Int32 | (2 << VECTOR_SCALE_SHIFT),
Float32x4 = Float32 | (2 << VECTOR_SCALE_SHIFT),
Bool8x16 = Boolean | (4 << VECTOR_SCALE_SHIFT),
Bool16x8 = Boolean | (3 << VECTOR_SCALE_SHIFT),
Bool32x4 = Boolean | (2 << VECTOR_SCALE_SHIFT),
Doublex2 = Double | (1 << VECTOR_SCALE_SHIFT)
};
static inline bool
IsSimdType(MIRType type)
{
return ((unsigned(type) >> VECTOR_SCALE_SHIFT) & VECTOR_SCALE_MASK) != 0;
}
// Returns the number of vector elements (hereby called "length") for a given
// SIMD kind. It is the Y part of the name "Foo x Y".
static inline unsigned
SimdTypeToLength(MIRType type)
{
MOZ_ASSERT(IsSimdType(type));
return 1 << ((unsigned(type) >> VECTOR_SCALE_SHIFT) & VECTOR_SCALE_MASK);
}
// Get the type of the individual lanes in a SIMD type.
// For example, Int32x4 -> Int32, Float32x4 -> Float32 etc.
static inline MIRType
SimdTypeToLaneType(MIRType type)
{
MOZ_ASSERT(IsSimdType(type));
static_assert(unsigned(MIRType::Last) <= ELEMENT_TYPE_MASK,
"ELEMENT_TYPE_MASK should be larger than the last MIRType");
return MIRType((unsigned(type) >> ELEMENT_TYPE_SHIFT) & ELEMENT_TYPE_MASK);
}
// Get the type expected when inserting a lane into a SIMD type.
// This is the argument type expected by the MSimdValue constructors as well as
// MSimdSplat and MSimdInsertElement.
static inline MIRType
SimdTypeToLaneArgumentType(MIRType type)
{
MIRType laneType = SimdTypeToLaneType(type);
// Boolean lanes should be pre-converted to an Int32 with the values 0 or -1.
// All other lane types are inserted directly.
return laneType == MIRType::Boolean ? MIRType::Int32 : laneType;
}
static inline MIRType
MIRTypeFromValueType(JSValueType type)
{
@ -555,12 +598,20 @@ StringFromMIRType(MIRType type)
return "Shape";
case MIRType::ObjectGroup:
return "ObjectGroup";
case MIRType::Float32x4:
return "Float32x4";
case MIRType::Int32x4:
return "Int32x4";
case MIRType::Int16x8:
return "Int16x8";
case MIRType::Int8x16:
return "Int8x16";
case MIRType::Float32x4:
return "Float32x4";
case MIRType::Bool32x4:
return "Bool32x4";
case MIRType::Bool16x8:
return "Bool16x8";
case MIRType::Bool8x16:
return "Bool8x16";
case MIRType::Doublex2:
return "Doublex2";
}
@ -602,12 +653,6 @@ IsNullOrUndefined(MIRType type)
return type == MIRType::Null || type == MIRType::Undefined;
}
static inline bool
IsSimdType(MIRType type)
{
return type == MIRType::Int32x4 || type == MIRType::Float32x4 || type == MIRType::Bool32x4;
}
static inline bool
IsFloatingPointSimdType(MIRType type)
{
@ -617,13 +662,13 @@ IsFloatingPointSimdType(MIRType type)
static inline bool
IsIntegerSimdType(MIRType type)
{
return type == MIRType::Int32x4;
return IsSimdType(type) && SimdTypeToLaneType(type) == MIRType::Int32;
}
static inline bool
IsBooleanSimdType(MIRType type)
{
return type == MIRType::Bool32x4;
return IsSimdType(type) && SimdTypeToLaneType(type) == MIRType::Boolean;
}
static inline bool
@ -636,15 +681,6 @@ IsMagicType(MIRType type)
type == MIRType::MagicUninitializedLexical;
}
// Returns the number of vector elements (hereby called "length") for a given
// SIMD kind. It is the Y part of the name "Foo x Y".
static inline unsigned
SimdTypeToLength(MIRType type)
{
MOZ_ASSERT(IsSimdType(type));
return 1 << ((unsigned(type) >> VECTOR_SCALE_SHIFT) & VECTOR_SCALE_MASK);
}
static inline MIRType
ScalarTypeToMIRType(Scalar::Type type)
{
@ -694,30 +730,6 @@ ScalarTypeToLength(Scalar::Type type)
MOZ_CRASH("unexpected SIMD kind");
}
// Get the type of the individual lanes in a SIMD type.
// For example, Int32x4 -> Int32, Float32x4 -> Float32 etc.
static inline MIRType
SimdTypeToLaneType(MIRType type)
{
MOZ_ASSERT(IsSimdType(type));
static_assert(unsigned(MIRType::Last) <= ELEMENT_TYPE_MASK,
"ELEMENT_TYPE_MASK should be larger than the last MIRType");
return MIRType((unsigned(type) >> ELEMENT_TYPE_SHIFT) & ELEMENT_TYPE_MASK);
}
// Get the type expected when inserting a lane into a SIMD type.
// This is the argument type expected by the MSimdValue constructors as well as
// MSimdSplat and MSimdInsertElement.
static inline MIRType
SimdTypeToLaneArgumentType(MIRType type)
{
MIRType laneType = SimdTypeToLaneType(type);
// Boolean lanes should be pre-converted to an Int32 with the values 0 or -1.
// All other lane types are inserted directly.
return laneType == MIRType::Boolean ? MIRType::Int32 : laneType;
}
#ifdef DEBUG
// Track the pipeline of opcodes which has produced a snapshot.

Просмотреть файл

@ -3397,6 +3397,12 @@ IonBuilder::inlineConstructSimdObject(CallInfo& callInfo, SimdTypeDescr* descr)
return InliningStatus_NotInlined;
}
// NYI, this will be removed by a bug 1136226 patch.
if (SimdTypeToLength(simdType) != 4) {
trackOptimizationOutcome(TrackedOutcome::SimdTypeNotOptimized);
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);

Просмотреть файл

@ -76,8 +76,14 @@ bool MaybeSimdTypeToMIRType(SimdType type, MIRType* mirType)
switch (type) {
case SimdType::Uint32x4:
case SimdType::Int32x4: *mirType = MIRType::Int32x4; return true;
case SimdType::Uint16x8:
case SimdType::Int16x8: *mirType = MIRType::Int16x8; return true;
case SimdType::Uint8x16:
case SimdType::Int8x16: *mirType = MIRType::Int8x16; return true;
case SimdType::Float32x4: *mirType = MIRType::Float32x4; return true;
case SimdType::Bool32x4: *mirType = MIRType::Bool32x4; return true;
case SimdType::Bool16x8: *mirType = MIRType::Bool16x8; return true;
case SimdType::Bool8x16: *mirType = MIRType::Bool8x16; return true;
default: return false;
}
}
@ -98,14 +104,25 @@ static inline
SimdType MIRTypeToSimdType(MIRType type)
{
switch (type) {
case MIRType::Float32x4: return SimdType::Float32x4;
case MIRType::Int32x4: return SimdType::Int32x4;
case MIRType::Int16x8: return SimdType::Int16x8;
case MIRType::Int8x16: return SimdType::Int8x16;
case MIRType::Float32x4: return SimdType::Float32x4;
case MIRType::Bool32x4: return SimdType::Bool32x4;
case MIRType::Bool16x8: return SimdType::Bool16x8;
case MIRType::Bool8x16: return SimdType::Bool8x16;
default: break;
}
MOZ_CRASH("unhandled MIRType");
}
// Get the boolean MIRType with the same shape as type.
static inline
MIRType MIRTypeToBooleanSimdType(MIRType type)
{
return SimdTypeToMIRType(GetBooleanSimdType(MIRTypeToSimdType(type)));
}
#define MIR_FLAG_LIST(_) \
_(InWorklist) \
_(EmittedAtUses) \
@ -2189,7 +2206,7 @@ class MSimdUnaryArith
{
MIRType type = def->type();
MOZ_ASSERT(IsSimdType(type));
MOZ_ASSERT_IF(type == MIRType::Int32x4, op == neg || op == not_);
MOZ_ASSERT_IF(IsIntegerSimdType(type), op == neg || op == not_);
setResultType(type);
setMovable();
}
@ -2254,7 +2271,7 @@ class MSimdBinaryComp
MOZ_ASSERT(IsSimdType(opType));
MOZ_ASSERT((sign != SimdSign::NotApplicable) == IsIntegerSimdType(opType),
"Signedness must be specified for integer SIMD compares");
setResultType(MIRType::Bool32x4);
setResultType(MIRTypeToBooleanSimdType(opType));
specialization_ = opType;
setMovable();
if (op == equal || op == notEqual)
@ -2344,8 +2361,8 @@ class MSimdBinaryArith
{
MOZ_ASSERT(left->type() == right->type());
MIRType type = left->type();
MOZ_ASSERT_IF(type == MIRType::Int32x4, op == Op_add || op == Op_sub || op == Op_mul);
MOZ_ASSERT(IsSimdType(type));
MOZ_ASSERT_IF(IsIntegerSimdType(type), op == Op_add || op == Op_sub || op == Op_mul);
setResultType(type);
setMovable();
if (op == Op_add || op == Op_mul || op == Op_min || op == Op_max)
@ -14135,31 +14152,9 @@ class MAsmJSLoadHeap
else
setMovable();
switch (access.accessType()) {
case Scalar::Int8:
case Scalar::Uint8:
case Scalar::Int16:
case Scalar::Uint16:
case Scalar::Int32:
case Scalar::Uint32:
setResultType(MIRType::Int32);
break;
case Scalar::Float32:
setResultType(MIRType::Float32);
break;
case Scalar::Float64:
setResultType(MIRType::Double);
break;
case Scalar::Float32x4:
setResultType(MIRType::Float32x4);
break;
case Scalar::Int32x4:
setResultType(MIRType::Int32x4);
break;
case Scalar::Uint8Clamped:
case Scalar::MaxTypedArrayViewType:
MOZ_CRASH("unexpected load heap in asm.js");
}
MOZ_ASSERT(access.accessType() != Scalar::Uint8Clamped,
"unexpected load heap in asm.js");
setResultType(ScalarTypeToMIRType(access.accessType()));
}
public: