зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
14fa218985
Коммит
b6fedab1e8
|
@ -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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче