Bug 950716 - IonMonkey: Optimize BitSet a little r=nbp
authorDan Gohman <sunfish@google.com>
Mon, 16 Dec 2013 11:13:29 -0800
changeset 160666 4361abf1909a0ed422a318c186f684c90255fabb
parent 160665 b63e9c3e67ac4fefd4e4e95ed323dc60f2aead5a
child 160667 cf2cf0c496101e26837c1024b8ed4153526c1799
push id37669
push usersunfish@google.com
push dateMon, 16 Dec 2013 19:13:54 +0000
treeherdermozilla-inbound@cf2cf0c49610 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs950716
milestone29.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 950716 - IonMonkey: Optimize BitSet a little r=nbp
js/src/jit/BitSet.cpp
js/src/jit/BitSet.h
js/src/jit/Safepoints.cpp
--- a/js/src/jit/BitSet.cpp
+++ b/js/src/jit/BitSet.cpp
@@ -31,83 +31,94 @@ BitSet::init(TempAllocator &alloc)
 
     return true;
 }
 
 bool
 BitSet::empty() const
 {
     JS_ASSERT(bits_);
-    for (unsigned int i = 0; i < numWords(); i++) {
-        if (bits_[i])
+    const uint32_t *bits = bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++) {
+        if (bits[i])
             return false;
     }
     return true;
 }
 
 void
 BitSet::insertAll(const BitSet *other)
 {
     JS_ASSERT(bits_);
     JS_ASSERT(other->numBits_ == numBits_);
     JS_ASSERT(other->bits_);
 
-    for (unsigned int i = 0; i < numWords(); i++)
-        bits_[i] |= other->bits_[i];
+    uint32_t *bits = bits_;
+    const uint32_t *otherBits = other->bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++)
+        bits[i] |= otherBits[i];
 }
 
 void
 BitSet::removeAll(const BitSet *other)
 {
     JS_ASSERT(bits_);
     JS_ASSERT(other->numBits_ == numBits_);
     JS_ASSERT(other->bits_);
 
-    for (unsigned int i = 0; i < numWords(); i++)
-        bits_[i] &= ~other->bits_[i];
+    uint32_t *bits = bits_;
+    const uint32_t *otherBits = other->bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++)
+        bits[i] &= ~otherBits[i];
 }
 
 void
 BitSet::intersect(const BitSet *other)
 {
     JS_ASSERT(bits_);
     JS_ASSERT(other->numBits_ == numBits_);
     JS_ASSERT(other->bits_);
 
-    for (unsigned int i = 0; i < numWords(); i++)
-        bits_[i] &= other->bits_[i];
+    uint32_t *bits = bits_;
+    const uint32_t *otherBits = other->bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++)
+        bits[i] &= otherBits[i];
 }
 
 // returns true if the intersection caused the contents of the set to change.
 bool
 BitSet::fixedPointIntersect(const BitSet *other)
 {
     JS_ASSERT(bits_);
     JS_ASSERT(other->numBits_ == numBits_);
     JS_ASSERT(other->bits_);
 
     bool changed = false;
 
-    for (unsigned int i = 0; i < numWords(); i++) {
-        uint32_t old = bits_[i];
-        bits_[i] &= other->bits_[i];
+    uint32_t *bits = bits_;
+    const uint32_t *otherBits = other->bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++) {
+        uint32_t old = bits[i];
+        bits[i] &= otherBits[i];
 
-        if (!changed && old != bits_[i])
+        if (!changed && old != bits[i])
             changed = true;
     }
     return changed;
 }
 
 void
 BitSet::complement()
 {
     JS_ASSERT(bits_);
-    for (unsigned int i = 0; i < numWords(); i++)
-        bits_[i] = ~bits_[i];
+    uint32_t *bits = bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++)
+        bits[i] = ~bits[i];
 }
 
 void
 BitSet::clear()
 {
     JS_ASSERT(bits_);
-    for (unsigned int i = 0; i < numWords(); i++)
-        bits_[i] = 0;
+    uint32_t *bits = bits_;
+    for (unsigned int i = 0, e = numWords(); i < e; i++)
+        bits[i] = 0;
 }
--- a/js/src/jit/BitSet.h
+++ b/js/src/jit/BitSet.h
@@ -117,24 +117,26 @@ class BitSet::Iterator
   private:
     BitSet &set_;
     unsigned index_;
     unsigned word_;
     uint32_t value_;
 
     void skipEmpty() {
         // Skip words containing only zeros.
+        unsigned numWords = set_.numWords();
+        const uint32_t *bits = set_.bits_;
         while (value_ == 0) {
             word_++;
-            if (!more())
+            if (word_ == numWords)
                 return;
 
             JS_STATIC_ASSERT(sizeof(value_) * 8 == BitSet::BitsPerWord);
             index_ = word_ * sizeof(value_) * 8;
-            value_ = set_.bits_[word_];
+            value_ = bits[word_];
         }
 
         // Be careful: the result of CountTrailingZeroes32 is undefined if the
         // input is 0.
         int numZeros = mozilla::CountTrailingZeroes32(value_);
         index_ += numZeros;
         value_ >>= numZeros;
 
--- a/js/src/jit/Safepoints.cpp
+++ b/js/src/jit/Safepoints.cpp
@@ -101,17 +101,17 @@ MapSlotsToBitset(BitSet *set, CompactBuf
     for (uint32_t i = 0; i < nslots; i++) {
         // Slots are represented at a distance from |fp|. Since the stack grows
         // down, this means slots start at index 1, so we subtract 1 to pack
         // the bitset.
         set->insert(slots[i] - 1);
     }
 
     size_t count = set->rawLength();
-    uint32_t *words = set->raw();
+    const uint32_t *words = set->raw();
     for (size_t i = 0; i < count; i++)
         stream.writeUnsigned(words[i]);
 }
 
 void
 SafepointWriter::writeGcSlots(LSafepoint *safepoint)
 {
     LSafepoint::SlotList &slots = safepoint->gcSlots();