Bug 1275248 - IonMonkey: Use MustAlias in Alias Analysis, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Thu, 02 Jun 2016 12:21:44 +0200
changeset 339166 67b41b80d37cf367ef746f2370c9ff947dead5f0
parent 339165 539bcdf33f32803be87f4d60faf6864277c13cba
child 339167 130a21afe56281e8b876f7fa6c63335458bdeba1
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: Use MustAlias in Alias Analysis, r=jandem
js/src/jit/MIR.cpp
js/src/jit/MIR.h
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -265,32 +265,63 @@ MDefinition::mightBeMagicType() const
 
     if (MIRType::Value != type())
         return false;
 
     return !resultTypeSet() || resultTypeSet()->hasType(TypeSet::MagicArgType());
 }
 
 MDefinition*
-MInstruction::foldsToStoredValue(TempAllocator& alloc, MDefinition* loaded)
-{
+MInstruction::foldsToStore(TempAllocator& alloc)
+{
+    if (!dependency())
+        return nullptr;
+
+    MDefinition* store = dependency();
+    if (mightAlias(store) != AliasType::MustAlias)
+        return nullptr;
+
+    if (!store->block()->dominates(block()))
+        return nullptr;
+
+    MDefinition* value;
+    switch (store->op()) {
+      case Op_StoreFixedSlot:
+        value = store->toStoreFixedSlot()->value();
+        break;
+      case Op_StoreSlot:
+        value = store->toStoreSlot()->value();
+        break;
+      case Op_StoreElement:
+        value = store->toStoreElement()->value();
+        break;
+      case Op_StoreUnboxedObjectOrNull:
+        value = store->toStoreUnboxedObjectOrNull()->value();
+        break;
+      default:
+        MOZ_CRASH("unknown store");
+    }
+
     // If the type are matching then we return the value which is used as
     // argument of the store.
-    if (loaded->type() != type()) {
+    if (value->type() != type()) {
         // If we expect to read a type which is more generic than the type seen
         // by the store, then we box the value used by the store.
         if (type() != MIRType::Value)
-            return this;
-
-        MOZ_ASSERT(loaded->type() < MIRType::Value);
-        MBox* box = MBox::New(alloc, loaded);
-        loaded = box;
-    }
-
-    return loaded;
+            return nullptr;
+        // We cannot unbox ObjectOrNull yet.
+        if (value->type() == MIRType::ObjectOrNull)
+            return nullptr;
+
+        MOZ_ASSERT(value->type() < MIRType::Value);
+        MBox* box = MBox::New(alloc, value);
+        value = box;
+    }
+
+    return value;
 }
 
 void
 MDefinition::analyzeEdgeCasesForward()
 {
 }
 
 void
@@ -4802,48 +4833,59 @@ MNewArray::MNewArray(CompilerConstraintL
             setResultTypeSet(types);
             if (types->convertDoubleElements(constraints) == TemporaryTypeSet::AlwaysConvertToDoubles)
                 convertDoubleElements_ = true;
         }
     }
 }
 
 MDefinition::AliasType
-MLoadFixedSlot::mightAlias(const MDefinition* store) const
-{
-    if (store->isStoreFixedSlot() && store->toStoreFixedSlot()->slot() != slot())
-        return AliasType::NoAlias;
-    return AliasType::MayAlias;
-}
-
-MDefinition::AliasType
-MLoadFixedSlotAndUnbox::mightAlias(const MDefinition* store) const
-{
-    if (store->isStoreFixedSlot() && store->toStoreFixedSlot()->slot() != slot())
-        return AliasType::NoAlias;
+MLoadFixedSlot::mightAlias(const MDefinition* def) const
+{
+    if (def->isStoreFixedSlot()) {
+        const MStoreFixedSlot* store = def->toStoreFixedSlot();
+        if (store->slot() != slot())
+            return AliasType::NoAlias;
+        if (store->object() != object())
+            return AliasType::MayAlias;
+        return AliasType::MustAlias;
+    }
     return AliasType::MayAlias;
 }
 
 MDefinition*
 MLoadFixedSlot::foldsTo(TempAllocator& alloc)
 {
-    if (!dependency() || !dependency()->isStoreFixedSlot())
-        return this;
-
-    MStoreFixedSlot* store = dependency()->toStoreFixedSlot();
-    if (!store->block()->dominates(block()))
-        return this;
-
-    if (store->object() != object())
-        return this;
-
-    if (store->slot() != slot())
-        return this;
-
-    return foldsToStoredValue(alloc, store->value());
+    if (MDefinition* def = foldsToStore(alloc))
+        return def;
+
+    return this;
+}
+
+MDefinition::AliasType
+MLoadFixedSlotAndUnbox::mightAlias(const MDefinition* def) const
+{
+    if (def->isStoreFixedSlot()) {
+        const MStoreFixedSlot* store = def->toStoreFixedSlot();
+        if (store->slot() != slot())
+            return AliasType::NoAlias;
+        if (store->object() != object())
+            return AliasType::MayAlias;
+        return AliasType::MustAlias;
+    }
+    return AliasType::MayAlias;
+}
+
+MDefinition*
+MLoadFixedSlotAndUnbox::foldsTo(TempAllocator& alloc)
+{
+    if (MDefinition* def = foldsToStore(alloc))
+        return def;
+
+    return this;
 }
 
 MDefinition::AliasType
 MAsmJSLoadHeap::mightAlias(const MDefinition* def) const
 {
     if (def->isAsmJSStoreHeap()) {
         const MAsmJSStoreHeap* store = def->toAsmJSStoreHeap();
         if (store->accessType() != accessType())
@@ -4951,101 +4993,108 @@ MAsmJSLoadFFIFunc::congruentTo(const MDe
     if (ins->isAsmJSLoadFFIFunc()) {
         const MAsmJSLoadFFIFunc* load = ins->toAsmJSLoadFFIFunc();
         return globalDataOffset_ == load->globalDataOffset_;
     }
     return false;
 }
 
 MDefinition::AliasType
-MLoadSlot::mightAlias(const MDefinition* store) const
-{
-    if (store->isStoreSlot() && store->toStoreSlot()->slot() != slot())
-        return AliasType::NoAlias;
+MLoadSlot::mightAlias(const MDefinition* def) const
+{
+    if (def->isStoreSlot()) {
+        const MStoreSlot* store = def->toStoreSlot();
+        if (store->slot() != slot())
+            return AliasType::NoAlias;
+
+        if (store->slots() != slots())
+            return AliasType::MayAlias;
+
+        return AliasType::MustAlias;
+    }
     return AliasType::MayAlias;
 }
 
 HashNumber
 MLoadSlot::valueHash() const
 {
     HashNumber hash = MDefinition::valueHash();
     hash = addU32ToHash(hash, slot_);
     return hash;
 }
 
 MDefinition*
 MLoadSlot::foldsTo(TempAllocator& alloc)
 {
-    if (!dependency() || !dependency()->isStoreSlot())
-        return this;
-
-    MStoreSlot* store = dependency()->toStoreSlot();
-    if (!store->block()->dominates(block()))
-        return this;
-
-    if (store->slots() != slots())
-        return this;
-
-    if (store->slot() != slot())
-        return this;
-
-    return foldsToStoredValue(alloc, store->value());
+    if (MDefinition* def = foldsToStore(alloc))
+        return def;
+
+    return this;
 }
 
 MDefinition*
 MFunctionEnvironment::foldsTo(TempAllocator& alloc)
 {
     if (!input()->isLambda())
         return this;
 
     return input()->toLambda()->scopeChain();
 }
 
+MDefinition::AliasType
+MLoadElement::mightAlias(const MDefinition* def) const
+{
+    if (def->isStoreElement()) {
+        const MStoreElement* store = def->toStoreElement();
+        if (store->index() != index())
+            return AliasType::MayAlias;
+
+        if (store->elements() != elements())
+            return AliasType::MayAlias;
+
+        return AliasType::MustAlias;
+    }
+    return AliasType::MayAlias;
+}
+
 MDefinition*
 MLoadElement::foldsTo(TempAllocator& alloc)
 {
-    if (!dependency() || !dependency()->isStoreElement())
-        return this;
-
-    MStoreElement* store = dependency()->toStoreElement();
-    if (!store->block()->dominates(block()))
-        return this;
-
-    if (store->elements() != elements())
-        return this;
-
-    if (store->index() != index())
-        return this;
-
-    return foldsToStoredValue(alloc, store->value());
+    if (MDefinition* def = foldsToStore(alloc))
+        return def;
+
+    return this;
+}
+
+MDefinition::AliasType
+MLoadUnboxedObjectOrNull::mightAlias(const MDefinition* def) const
+{
+    if (def->isStoreUnboxedObjectOrNull()) {
+        const MStoreUnboxedObjectOrNull* store = def->toStoreUnboxedObjectOrNull();
+        if (store->index() != index())
+            return AliasType::MayAlias;
+
+        if (store->elements() != elements())
+            return AliasType::MayAlias;
+
+        if (store->offsetAdjustment() != offsetAdjustment())
+            return AliasType::MayAlias;
+
+        return AliasType::MustAlias;
+    }
+    return AliasType::MayAlias;
 }
 
 MDefinition*
 MLoadUnboxedObjectOrNull::foldsTo(TempAllocator& alloc)
 {
-    if (!dependency() || !dependency()->isStoreUnboxedObjectOrNull())
-        return this;
-
-    MStoreUnboxedObjectOrNull* store = dependency()->toStoreUnboxedObjectOrNull();
-    if (!store->block()->dominates(block()))
-        return this;
-
-    if (store->elements() != elements())
-        return this;
-
-    if (store->index() != index())
-        return this;
-
-    if (store->value()->type() == MIRType::ObjectOrNull)
-        return this;
-
-    if (store->offsetAdjustment() != offsetAdjustment())
-        return this;
-
-    return foldsToStoredValue(alloc, store->value());
+    if (MDefinition* def = foldsToStore(alloc))
+        return def;
+
+    return this;
 }
 
 bool
 MGuardReceiverPolymorphic::congruentTo(const MDefinition* ins) const
 {
     if (!ins->isGuardReceiverPolymorphic())
         return false;
 
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1027,20 +1027,17 @@ class MInstruction
     // Copying an instruction leaves the block and resume point as empty.
     explicit MInstruction(const MInstruction& other)
       : MDefinition(other),
         resumePoint_(nullptr)
     { }
 
     // Convenient function used for replacing a load by the value of the store
     // if the types are match, and boxing the value if they do not match.
-    //
-    // Note: There is no need for such function in AsmJS functions as they do
-    // not use any MIRType::Value.
-    MDefinition* foldsToStoredValue(TempAllocator& alloc, MDefinition* loaded);
+    MDefinition* foldsToStore(TempAllocator& alloc);
 
     void setResumePoint(MResumePoint* resumePoint);
 
     // Used to transfer the resume point to the rewritten instruction.
     void stealResumePoint(MInstruction* ins);
     void moveResumePointAsEntry();
     void clearResumePoint();
     MResumePoint* resumePoint() const {
@@ -9534,16 +9531,17 @@ class MLoadElement
         if (needsHoleCheck() != other->needsHoleCheck())
             return false;
         if (loadDoubles() != other->loadDoubles())
             return false;
         if (offsetAdjustment() != other->offsetAdjustment())
             return false;
         return congruentIfOperandsEqual(other);
     }
+    AliasType mightAlias(const MDefinition* store) const override;
     MDefinition* foldsTo(TempAllocator& alloc) override;
     AliasSet getAliasSet() const override {
         return AliasSet::Load(AliasSet::Element);
     }
 
     ALLOW_CLONE(MLoadElement)
 };
 
@@ -9693,16 +9691,17 @@ class MLoadUnboxedObjectOrNull
             return false;
         if (offsetAdjustment() != other->offsetAdjustment())
             return false;
         return congruentIfOperandsEqual(other);
     }
     AliasSet getAliasSet() const override {
         return AliasSet::Load(AliasSet::UnboxedElement);
     }
+    AliasType mightAlias(const MDefinition* store) const override;
     MDefinition* foldsTo(TempAllocator& alloc) override;
 
     ALLOW_CLONE(MLoadUnboxedObjectOrNull)
 };
 
 class MLoadUnboxedString
   : public MBinaryInstruction,
     public SingleObjectPolicy::Data
@@ -10936,16 +10935,18 @@ class MLoadFixedSlotAndUnbox
             slot() != ins->toLoadFixedSlotAndUnbox()->slot() ||
             mode() != ins->toLoadFixedSlotAndUnbox()->mode())
         {
             return false;
         }
         return congruentIfOperandsEqual(ins);
     }
 
+    MDefinition* foldsTo(TempAllocator& alloc) override;
+
     AliasSet getAliasSet() const override {
         return AliasSet::Load(AliasSet::FixedSlot);
     }
 
     AliasType mightAlias(const MDefinition* store) const override;
 
     ALLOW_CLONE(MLoadFixedSlotAndUnbox);
 };