Bug 845068 - IonMonkey: GVN: Implement congruentTo and valueHash for more load nodes, exposing more congruences and reducing collisions r=nbp
authorDan Gohman <sunfish@mozilla.com>
Wed, 16 Jul 2014 10:53:38 -0700
changeset 215299 f92f0477237f73dcb6f7c0985e363a75feb9a14c
parent 215298 e0c6d4eb2d4ad55e681b7ba3822c11323767dd47
child 215300 2b6ec15fea1bcb566f85419db246dbca9be5aa70
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs845068
milestone33.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 845068 - IonMonkey: GVN: Implement congruentTo and valueHash for more load nodes, exposing more congruences and reducing collisions r=nbp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -170,23 +170,27 @@ EvaluateExactReciprocal(TempAllocator &a
 void
 MDefinition::printName(FILE *fp) const
 {
     PrintOpcodeName(fp, op());
     fprintf(fp, "%u", id());
 }
 
 HashNumber
+MDefinition::addU32ToHash(HashNumber hash, uint32_t data)
+{
+    return data + (hash << 6) + (hash << 16) - hash;
+}
+
+HashNumber
 MDefinition::valueHash() const
 {
     HashNumber out = op();
-    for (size_t i = 0, e = numOperands(); i < e; i++) {
-        uint32_t valueNumber = getOperand(i)->id();
-        out = valueNumber + (out << 6) + (out << 16) - out;
-    }
+    for (size_t i = 0, e = numOperands(); i < e; i++)
+        out = addU32ToHash(out, getOperand(i)->id());
     return out;
 }
 
 bool
 MDefinition::congruentIfOperandsEqual(const MDefinition *ins) const
 {
     if (op() != ins->op())
         return false;
@@ -681,17 +685,19 @@ MParameter::printOpcode(FILE *fp) const
         fprintf(fp, " THIS_SLOT");
     else
         fprintf(fp, " %d", index());
 }
 
 HashNumber
 MParameter::valueHash() const
 {
-    return index_; // Why not?
+    HashNumber hash = MDefinition::valueHash();
+    hash = addU32ToHash(hash, index_);
+    return hash;
 }
 
 bool
 MParameter::congruentTo(const MDefinition *ins) const
 {
     if (!ins->isParameter())
         return false;
 
@@ -2861,34 +2867,86 @@ MAsmJSLoadGlobalVar::mightAlias(const MD
 {
     if (def->isAsmJSStoreGlobalVar()) {
         const MAsmJSStoreGlobalVar *store = def->toAsmJSStoreGlobalVar();
         return store->globalDataOffset() == globalDataOffset_;
     }
     return true;
 }
 
+HashNumber
+MAsmJSLoadGlobalVar::valueHash() const
+{
+    HashNumber hash = MDefinition::valueHash();
+    hash = addU32ToHash(hash, globalDataOffset_);
+    return hash;
+}
+
 bool
 MAsmJSLoadGlobalVar::congruentTo(const MDefinition *ins) const
 {
     if (ins->isAsmJSLoadGlobalVar()) {
         const MAsmJSLoadGlobalVar *load = ins->toAsmJSLoadGlobalVar();
         return globalDataOffset_ == load->globalDataOffset_;
     }
     return false;
 }
 
+HashNumber
+MAsmJSLoadFuncPtr::valueHash() const
+{
+    HashNumber hash = MDefinition::valueHash();
+    hash = addU32ToHash(hash, globalDataOffset_);
+    return hash;
+}
+
+bool
+MAsmJSLoadFuncPtr::congruentTo(const MDefinition *ins) const
+{
+    if (ins->isAsmJSLoadFuncPtr()) {
+        const MAsmJSLoadFuncPtr *load = ins->toAsmJSLoadFuncPtr();
+        return globalDataOffset_ == load->globalDataOffset_;
+    }
+    return false;
+}
+
+HashNumber
+MAsmJSLoadFFIFunc::valueHash() const
+{
+    HashNumber hash = MDefinition::valueHash();
+    hash = addU32ToHash(hash, globalDataOffset_);
+    return hash;
+}
+
+bool
+MAsmJSLoadFFIFunc::congruentTo(const MDefinition *ins) const
+{
+    if (ins->isAsmJSLoadFFIFunc()) {
+        const MAsmJSLoadFFIFunc *load = ins->toAsmJSLoadFFIFunc();
+        return globalDataOffset_ == load->globalDataOffset_;
+    }
+    return false;
+}
+
 bool
 MLoadSlot::mightAlias(const MDefinition *store) const
 {
     if (store->isStoreSlot() && store->toStoreSlot()->slot() != slot())
         return false;
     return true;
 }
 
+HashNumber
+MLoadSlot::valueHash() const
+{
+    HashNumber hash = MDefinition::valueHash();
+    hash = addU32ToHash(hash, slot_);
+    return hash;
+}
+
 bool
 MGuardShapePolymorphic::congruentTo(const MDefinition *ins) const
 {
     if (!ins->isGuardShapePolymorphic())
         return false;
 
     const MGuardShapePolymorphic *other = ins->toGuardShapePolymorphic();
     if (numShapes() != other->numShapes())
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -355,16 +355,18 @@ class MDefinition : public MNode
         flags_ |= flags;
     }
 
   protected:
     virtual void setBlock(MBasicBlock *block) {
         block_ = block;
     }
 
+    static HashNumber addU32ToHash(HashNumber hash, uint32_t data);
+
   public:
     MDefinition()
       : id_(0),
         range_(nullptr),
         resultType_(MIRType_None),
         resultTypeSet_(nullptr),
         flags_(0),
         dependency_(nullptr),
@@ -8106,16 +8108,17 @@ class MLoadSlot
     }
     MDefinition *slots() const {
         return getOperand(0);
     }
     uint32_t slot() const {
         return slot_;
     }
 
+    HashNumber valueHash() const;
     bool congruentTo(const MDefinition *ins) const {
         if (!ins->isLoadSlot())
             return false;
         if (slot() != ins->toLoadSlot()->slot())
             return false;
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
@@ -10397,16 +10400,17 @@ class MAsmJSLoadGlobalVar : public MNull
     static MAsmJSLoadGlobalVar *New(TempAllocator &alloc, MIRType type, unsigned globalDataOffset,
                                     bool isConstant)
     {
         return new(alloc) MAsmJSLoadGlobalVar(type, globalDataOffset, isConstant);
     }
 
     unsigned globalDataOffset() const { return globalDataOffset_; }
 
+    HashNumber valueHash() const;
     bool congruentTo(const MDefinition *ins) const;
 
     AliasSet getAliasSet() const {
         return isConstant_ ? AliasSet::None() : AliasSet::Load(AliasSet::AsmJSGlobalVar);
     }
 
     bool mightAlias(const MDefinition *def) const;
 };
@@ -10450,16 +10454,19 @@ class MAsmJSLoadFuncPtr : public MUnaryI
     static MAsmJSLoadFuncPtr *New(TempAllocator &alloc, unsigned globalDataOffset,
                                   MDefinition *index)
     {
         return new(alloc) MAsmJSLoadFuncPtr(globalDataOffset, index);
     }
 
     unsigned globalDataOffset() const { return globalDataOffset_; }
     MDefinition *index() const { return getOperand(0); }
+
+    HashNumber valueHash() const;
+    bool congruentTo(const MDefinition *ins) const;
 };
 
 class MAsmJSLoadFFIFunc : public MNullaryInstruction
 {
     explicit MAsmJSLoadFFIFunc(unsigned globalDataOffset)
       : globalDataOffset_(globalDataOffset)
     {
         setResultType(MIRType_Pointer);
@@ -10471,16 +10478,19 @@ class MAsmJSLoadFFIFunc : public MNullar
     INSTRUCTION_HEADER(AsmJSLoadFFIFunc);
 
     static MAsmJSLoadFFIFunc *New(TempAllocator &alloc, unsigned globalDataOffset)
     {
         return new(alloc) MAsmJSLoadFFIFunc(globalDataOffset);
     }
 
     unsigned globalDataOffset() const { return globalDataOffset_; }
+
+    HashNumber valueHash() const;
+    bool congruentTo(const MDefinition *ins) const;
 };
 
 class MAsmJSParameter : public MNullaryInstruction
 {
     ABIArg abi_;
 
     MAsmJSParameter(ABIArg abi, MIRType mirType)
       : abi_(abi)