Bug 898021 - Mark values written to integer typed arrays as truncated, r=jandem.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 26 Jul 2013 11:29:48 -0600
changeset 140192 01bf6add1d1fbb7349dce9f2b481ab245ba25cd6
parent 140191 d2967ea984a7aa53c54e79ab638cbfd72f6cb1e2
child 140193 b8791c396e52684d09a4df2fa144c8c22f396d3c
push id1945
push userryanvm@gmail.com
push dateSat, 27 Jul 2013 02:27:26 +0000
treeherderfx-team@4874fa438b1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs898021
milestone25.0a1
Bug 898021 - Mark values written to integer typed arrays as truncated, r=jandem.
js/src/ion/MIR.h
js/src/ion/RangeAnalysis.cpp
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -5228,16 +5228,17 @@ class MStoreTypedArrayElement
         return AliasSet::Store(AliasSet::TypedArrayElement);
     }
     bool racy() const {
         return racy_;
     }
     void setRacy() {
         racy_ = true;
     }
+    bool isOperandTruncated(size_t index) const;
 };
 
 class MStoreTypedArrayElementHole
   : public MAryInstruction<4>,
     public StoreTypedArrayHolePolicy
 {
     int arrayType_;
 
@@ -5290,16 +5291,17 @@ class MStoreTypedArrayElementHole
         return getOperand(2);
     }
     MDefinition *value() const {
         return getOperand(3);
     }
     AliasSet getAliasSet() const {
         return AliasSet::Store(AliasSet::TypedArrayElement);
     }
+    bool isOperandTruncated(size_t index) const;
 };
 
 // Store a value infallibly to a statically known typed array.
 class MStoreTypedArrayElementStatic :
     public MBinaryInstruction
   , public StoreTypedArrayElementStaticPolicy
 {
     MStoreTypedArrayElementStatic(TypedArrayObject *typedArray, MDefinition *ptr, MDefinition *v)
@@ -5317,24 +5319,30 @@ class MStoreTypedArrayElementStatic :
         return new MStoreTypedArrayElementStatic(typedArray, ptr, v);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     ArrayBufferView::ViewType viewType() const { return JS_GetArrayBufferViewType(typedArray_); }
+    bool isFloatArray() const {
+        return (viewType() == TypedArrayObject::TYPE_FLOAT32 ||
+                viewType() == TypedArrayObject::TYPE_FLOAT64);
+    }
+
     void *base() const;
     size_t length() const;
 
     MDefinition *ptr() const { return getOperand(0); }
     MDefinition *value() const { return getOperand(1); }
     AliasSet getAliasSet() const {
         return AliasSet::Store(AliasSet::TypedArrayElement);
     }
+    bool isOperandTruncated(size_t index) const;
 };
 
 // Compute an "effective address", i.e., a compound computation of the form:
 //   base + index * scale + displacement
 class MEffectiveAddress : public MBinaryInstruction
 {
     MEffectiveAddress(MDefinition *base, MDefinition *index, Scale scale, int32_t displacement)
       : MBinaryInstruction(base, index), scale_(scale), displacement_(displacement)
--- a/js/src/ion/RangeAnalysis.cpp
+++ b/js/src/ion/RangeAnalysis.cpp
@@ -1819,16 +1819,34 @@ MMul::isOperandTruncated(size_t index) c
 bool
 MToDouble::isOperandTruncated(size_t index) const
 {
     // The return type is used to flag that we are replacing this Double by a
     // Truncate of its operand if needed.
     return type() == MIRType_Int32;
 }
 
+bool
+MStoreTypedArrayElement::isOperandTruncated(size_t index) const
+{
+    return index == 2 && !isFloatArray();
+}
+
+bool
+MStoreTypedArrayElementHole::isOperandTruncated(size_t index) const
+{
+    return index == 3 && !isFloatArray();
+}
+
+bool
+MStoreTypedArrayElementStatic::isOperandTruncated(size_t index) const
+{
+    return index == 1 && !isFloatArray();
+}
+
 // Ensure that all observables uses can work with a truncated
 // version of the |candidate|'s result.
 static bool
 AllUsesTruncate(MInstruction *candidate)
 {
     for (MUseIterator use(candidate->usesBegin()); use != candidate->usesEnd(); use++) {
         if (!use->consumer()->isDefinition()) {
             // We can only skip testing resume points, if all original uses are still present.