From 71d94d71fd777f7cf5294f25330ceeee089d1b89 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Tue, 3 Mar 2015 11:07:49 +0100 Subject: [PATCH] Bug 1135042: Share more code between StoreTypedArray* classes; r=bhackett --- js/src/jit/Lowering.cpp | 12 ++--- js/src/jit/MIR.h | 99 +++++++++++++++++++++--------------- js/src/jit/RangeAnalysis.cpp | 6 +-- 3 files changed, 66 insertions(+), 51 deletions(-) diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 3e21c0e9a2d..56bdc193ff6 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2984,9 +2984,9 @@ LIRGenerator::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins) if (ins->isSimdWrite()) { MOZ_ASSERT_IF(ins->writeType() == Scalar::Float32x4, ins->value()->type() == MIRType_Float32x4); MOZ_ASSERT_IF(ins->writeType() == Scalar::Int32x4, ins->value()->type() == MIRType_Int32x4); - } else if (ins->isFloatArray()) { - MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float32, ins->value()->type() == MIRType_Float32); - MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float64, ins->value()->type() == MIRType_Double); + } else if (ins->isFloatWrite()) { + MOZ_ASSERT_IF(ins->writeType() == Scalar::Float32, ins->value()->type() == MIRType_Float32); + MOZ_ASSERT_IF(ins->writeType() == Scalar::Float64, ins->value()->type() == MIRType_Double); } else { MOZ_ASSERT(ins->value()->type() == MIRType_Int32); } @@ -2996,7 +2996,7 @@ LIRGenerator::visitStoreTypedArrayElement(MStoreTypedArrayElement *ins) LAllocation value; // For byte arrays, the value has to be in a byte register on x86. - if (ins->isByteArray() && !ins->isSimdWrite()) + if (ins->isByteWrite()) value = useByteOpRegisterOrNonDoubleConstant(ins->value()); else value = useRegisterOrNonDoubleConstant(ins->value()); @@ -3023,7 +3023,7 @@ LIRGenerator::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins) MOZ_ASSERT(ins->index()->type() == MIRType_Int32); MOZ_ASSERT(ins->length()->type() == MIRType_Int32); - if (ins->isFloatArray()) { + if (ins->isFloatWrite()) { MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float32, ins->value()->type() == MIRType_Float32); MOZ_ASSERT_IF(ins->arrayType() == Scalar::Float64, ins->value()->type() == MIRType_Double); } else { @@ -3036,7 +3036,7 @@ LIRGenerator::visitStoreTypedArrayElementHole(MStoreTypedArrayElementHole *ins) LAllocation value; // For byte arrays, the value has to be in a byte register on x86. - if (ins->isByteArray()) + if (ins->isByteWrite()) value = useByteOpRegisterOrNonDoubleConstant(ins->value()); else value = useRegisterOrNonDoubleConstant(ins->value()); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 4ea8989b43b..ea47ebd7f7b 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9062,12 +9062,52 @@ class MLoadTypedArrayElementStatic void collectRangeInfoPreTrunc() MOZ_OVERRIDE; }; +// Base class for MIR ops that write to typed arrays. +class StoreTypedArrayBase +{ + Scalar::Type writeType_; + + protected: + StoreTypedArrayBase(Scalar::Type writeType) + : writeType_(writeType) + { + MOZ_ASSERT(isIntegerWrite() || isFloatWrite() || isSimdWrite()); + } + + public: + void setWriteType(Scalar::Type type) { + writeType_ = type; + } + Scalar::Type writeType() const { + return writeType_; + } + bool isByteWrite() const { + return writeType_ == Scalar::Int8 || + writeType_ == Scalar::Uint8 || + writeType_ == Scalar::Uint8Clamped; + } + bool isIntegerWrite() const { + return isByteWrite () || + writeType_ == Scalar::Int16 || + writeType_ == Scalar::Uint16 || + writeType_ == Scalar::Int32 || + writeType_ == Scalar::Uint32; + } + bool isFloatWrite() const { + return writeType_ == Scalar::Float32 || + writeType_ == Scalar::Float64; + } + bool isSimdWrite() const { + return Scalar::isSimdType(writeType()); + } +}; + class MStoreTypedArrayElement : public MTernaryInstruction, + public StoreTypedArrayBase, public StoreTypedArrayPolicy::Data { Scalar::Type arrayType_; - Scalar::Type writeType_; bool requiresBarrier_; int32_t offsetAdjustment_; @@ -9078,8 +9118,8 @@ class MStoreTypedArrayElement Scalar::Type arrayType, MemoryBarrierRequirement requiresBarrier, int32_t offsetAdjustment) : MTernaryInstruction(elements, index, value), + StoreTypedArrayBase(arrayType), arrayType_(arrayType), - writeType_(arrayType), requiresBarrier_(requiresBarrier == DoesRequireMemoryBarrier), offsetAdjustment_(offsetAdjustment), racy_(false) @@ -9105,27 +9145,9 @@ class MStoreTypedArrayElement requiresBarrier, offsetAdjustment); } - void setWriteType(Scalar::Type type) { - writeType_ = type; - } - Scalar::Type writeType() const { - return writeType_; - } Scalar::Type arrayType() const { return arrayType_; } - bool isSimdWrite() const { - return Scalar::isSimdType(writeType()); - } - bool isByteArray() const { - return arrayType_ == Scalar::Int8 || - arrayType_ == Scalar::Uint8 || - arrayType_ == Scalar::Uint8Clamped; - } - bool isFloatArray() const { - return arrayType_ == Scalar::Float32 || - arrayType_ == Scalar::Float64; - } MDefinition *elements() const { return getOperand(0); } @@ -9161,13 +9183,13 @@ class MStoreTypedArrayElement class MStoreTypedArrayElementHole : public MAryInstruction<4>, + public StoreTypedArrayBase, public StoreTypedArrayHolePolicy::Data { - Scalar::Type arrayType_; - MStoreTypedArrayElementHole(MDefinition *elements, MDefinition *length, MDefinition *index, MDefinition *value, Scalar::Type arrayType) - : MAryInstruction<4>(), arrayType_(arrayType) + : MAryInstruction<4>(), + StoreTypedArrayBase(arrayType) { initOperand(0, elements); initOperand(1, length); @@ -9191,16 +9213,9 @@ class MStoreTypedArrayElementHole } Scalar::Type arrayType() const { - return arrayType_; - } - bool isByteArray() const { - return arrayType_ == Scalar::Int8 || - arrayType_ == Scalar::Uint8 || - arrayType_ == Scalar::Uint8Clamped; - } - bool isFloatArray() const { - return arrayType_ == Scalar::Float32 || - arrayType_ == Scalar::Float64; + MOZ_ASSERT(!Scalar::isSimdType(writeType()), + "arrayType == writeType iff the write type isn't SIMD"); + return writeType(); } MDefinition *elements() const { return getOperand(0); @@ -9220,7 +9235,7 @@ class MStoreTypedArrayElementHole TruncateKind operandTruncateKind(size_t index) const MOZ_OVERRIDE; bool canConsumeFloat32(MUse *use) const MOZ_OVERRIDE { - return use == getUseFor(3) && arrayType_ == Scalar::Float32; + return use == getUseFor(3) && arrayType() == Scalar::Float32; } ALLOW_CLONE(MStoreTypedArrayElementHole) @@ -9228,16 +9243,20 @@ class MStoreTypedArrayElementHole // Store a value infallibly to a statically known typed array. class MStoreTypedArrayElementStatic : - public MBinaryInstruction - , public StoreTypedArrayElementStaticPolicy::Data + public MBinaryInstruction, + public StoreTypedArrayBase, + public StoreTypedArrayElementStaticPolicy::Data { MStoreTypedArrayElementStatic(JSObject *someTypedArray, MDefinition *ptr, MDefinition *v, int32_t offset, bool needsBoundsCheck) - : MBinaryInstruction(ptr, v), someTypedArray_(someTypedArray), + : MBinaryInstruction(ptr, v), + StoreTypedArrayBase(AnyTypedArrayType(someTypedArray_)), + someTypedArray_(someTypedArray), offset_(offset), needsBoundsCheck_(needsBoundsCheck) {} AlwaysTenured someTypedArray_; + // An offset to be encoded in the store instruction - taking advantage of the // addressing modes. This is only non-zero when the access is proven to be // within bounds. @@ -9257,11 +9276,7 @@ class MStoreTypedArrayElementStatic : } Scalar::Type accessType() const { - return AnyTypedArrayType(someTypedArray_); - } - bool isFloatArray() const { - return accessType() == Scalar::Float32 || - accessType() == Scalar::Float64; + return writeType(); } void *base() const; diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index 9807dfee7dd..7e28da6e455 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -2645,21 +2645,21 @@ MDefinition::TruncateKind MStoreTypedArrayElement::operandTruncateKind(size_t index) const { // An integer store truncates the stored value. - return index == 2 && !isFloatArray() && !isSimdWrite() ? Truncate : NoTruncate; + return index == 2 && isIntegerWrite() ? Truncate : NoTruncate; } MDefinition::TruncateKind MStoreTypedArrayElementHole::operandTruncateKind(size_t index) const { // An integer store truncates the stored value. - return index == 3 && !isFloatArray() ? Truncate : NoTruncate; + return index == 3 && isIntegerWrite() ? Truncate : NoTruncate; } MDefinition::TruncateKind MStoreTypedArrayElementStatic::operandTruncateKind(size_t index) const { // An integer store truncates the stored value. - return index == 1 && !isFloatArray() ? Truncate : NoTruncate; + return index == 1 && isIntegerWrite() ? Truncate : NoTruncate; } MDefinition::TruncateKind