Bug 1275248 - IonMonkey: Don't alias loading of elements with different indexes, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Thu, 02 Jun 2016 12:21:46 +0200
changeset 339167 130a21afe56281e8b876f7fa6c63335458bdeba1
parent 339166 67b41b80d37cf367ef746f2370c9ff947dead5f0
child 339168 29fc4a93e85c4110604e590d5069339b1e4b40f2
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1275248
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1275248 - IonMonkey: Don't alias loading of elements with different indexes, r=jandem
js/src/jit/MIR.cpp
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -5034,23 +5034,77 @@ MDefinition*
 MFunctionEnvironment::foldsTo(TempAllocator& alloc)
 {
     if (!input()->isLambda())
         return this;
 
     return input()->toLambda()->scopeChain();
 }
 
+static bool
+AddIsANonZeroAdditionOf(MAdd* add, MDefinition* ins)
+{
+    if (add->lhs() != ins && add->rhs() != ins)
+        return false;
+    MDefinition* other = (add->lhs() == ins) ? add->rhs() : add->lhs();
+    if (!IsNumberType(other->type()))
+        return false;
+    if (!other->isConstant())
+        return false;
+    if (other->toConstant()->numberToDouble() == 0)
+        return false;
+    return true;
+}
+
+static bool
+DefinitelyDifferentValue(MDefinition* ins1, MDefinition* ins2)
+{
+    if (ins1 == ins2)
+        return false;
+
+    // Drop the MToInt32 added by the TypePolicy for double and float values.
+    if (ins1->isToInt32())
+        return DefinitelyDifferentValue(ins1->toToInt32()->input(), ins2);
+    if (ins2->isToInt32())
+        return DefinitelyDifferentValue(ins2->toToInt32()->input(), ins1);
+
+    // Ignore the bounds check, which in most cases will contain the same info.
+    if (ins1->isBoundsCheck())
+        return DefinitelyDifferentValue(ins1->toBoundsCheck()->index(), ins2);
+    if (ins2->isBoundsCheck())
+        return DefinitelyDifferentValue(ins2->toBoundsCheck()->index(), ins1);
+
+    // For constants check they are not equal.
+    if (ins1->isConstant() && ins2->isConstant())
+        return !ins1->toConstant()->equals(ins2->toConstant());
+
+    // Check if "ins1 = ins2 + cte", which would make both instructions
+    // have different values.
+    if (ins1->isAdd()) {
+        if (AddIsANonZeroAdditionOf(ins1->toAdd(), ins2))
+            return true;
+    }
+    if (ins2->isAdd()) {
+        if (AddIsANonZeroAdditionOf(ins2->toAdd(), ins1))
+            return true;
+    }
+
+    return false;
+}
+
 MDefinition::AliasType
 MLoadElement::mightAlias(const MDefinition* def) const
 {
     if (def->isStoreElement()) {
         const MStoreElement* store = def->toStoreElement();
-        if (store->index() != index())
+        if (store->index() != index()) {
+            if (DefinitelyDifferentValue(store->index(), index()))
+                return AliasType::NoAlias;
             return AliasType::MayAlias;
+        }
 
         if (store->elements() != elements())
             return AliasType::MayAlias;
 
         return AliasType::MustAlias;
     }
     return AliasType::MayAlias;
 }
@@ -5064,18 +5118,21 @@ MLoadElement::foldsTo(TempAllocator& all
     return this;
 }
 
 MDefinition::AliasType
 MLoadUnboxedObjectOrNull::mightAlias(const MDefinition* def) const
 {
     if (def->isStoreUnboxedObjectOrNull()) {
         const MStoreUnboxedObjectOrNull* store = def->toStoreUnboxedObjectOrNull();
-        if (store->index() != index())
+        if (store->index() != index()) {
+            if (DefinitelyDifferentValue(store->index(), index()))
+                return AliasType::NoAlias;
             return AliasType::MayAlias;
+        }
 
         if (store->elements() != elements())
             return AliasType::MayAlias;
 
         if (store->offsetAdjustment() != offsetAdjustment())
             return AliasType::MayAlias;
 
         return AliasType::MustAlias;