Backed out changeset d7e148db2e85 (bug 1321521) for build bustage a=backout CLOSED TREE
authorWes Kocher <wkocher@mozilla.com>
Fri, 13 Jan 2017 10:35:23 -0800
changeset 374360 a55032f495c449466fd07430d76c541cd5039ca2
parent 374359 d7e148db2e85f74bef3680e2ad1797c1af5d28f3
child 374361 4ef05cc6af4ec1ff02dc6ceb0e85c1ee3a3f9e86
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1321521
milestone53.0a1
backs outd7e148db2e85f74bef3680e2ad1797c1af5d28f3
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
Backed out changeset d7e148db2e85 (bug 1321521) for build bustage a=backout CLOSED TREE MozReview-Commit-ID: By0dyqjsVJb
js/src/jit/BacktrackingAllocator.cpp
js/src/jit/CodeGenerator.cpp
js/src/jit/RegisterSets.h
js/src/jit/Registers.h
js/src/jit/StupidAllocator.cpp
js/src/jit/arm/Architecture-arm.h
js/src/jit/arm64/Architecture-arm64.h
js/src/jit/mips-shared/Architecture-mips-shared.h
js/src/jit/shared/Architecture-shared.h
js/src/jit/x86-shared/Architecture-x86-shared.h
js/src/jsapi-tests/testJitRegisterSet.cpp
js/src/wasm/WasmBaselineCompile.cpp
--- a/js/src/jit/BacktrackingAllocator.cpp
+++ b/js/src/jit/BacktrackingAllocator.cpp
@@ -414,17 +414,17 @@ BacktrackingAllocator::init()
     }
 
     LiveRegisterSet remainingRegisters(allRegisters_.asLiveSet());
     while (!remainingRegisters.emptyGeneral()) {
         AnyRegister reg = AnyRegister(remainingRegisters.takeAnyGeneral());
         registers[reg.code()].allocatable = true;
     }
     while (!remainingRegisters.emptyFloat()) {
-        AnyRegister reg = AnyRegister(remainingRegisters.takeAnyFloat<RegTypeName::Any>());
+        AnyRegister reg = AnyRegister(remainingRegisters.takeAnyFloat());
         registers[reg.code()].allocatable = true;
     }
 
     LifoAlloc* lifoAlloc = mir->alloc().lifoAlloc();
     for (size_t i = 0; i < AnyRegister::Total; i++) {
         registers[i].reg = AnyRegister::FromCode(i);
         registers[i].allocations.setAllocator(lifoAlloc);
     }
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4681,17 +4681,17 @@ CodeGenerator::generateArgumentsChecks(b
     // before entering the function and bailout when arguments don't match.
     // For debug purpose, this is can also be used to force/check that the
     // arguments are correct. Upon fail it will hit a breakpoint.
 
     MIRGraph& mir = gen->graph();
     MResumePoint* rp = mir.entryResumePoint();
 
     // No registers are allocated yet, so it's safe to grab anything.
-    Register temp = AllocatableGeneralRegisterSet(EntryTempMask).getAny();
+    Register temp = GeneralRegisterSet(EntryTempMask).getAny();
 
     const CompileInfo& info = gen->info();
 
     Label miss;
     for (uint32_t i = info.startArgSlot(); i < info.endArgSlot(); i++) {
         // All initial parameters are guaranteed to be MParameters.
         MParameter* param = rp->getOperand(i)->toParameter();
         const TypeSet* types = param->resultTypeSet();
--- a/js/src/jit/RegisterSets.h
+++ b/js/src/jit/RegisterSets.h
@@ -387,32 +387,32 @@ class TypedRegisterSet
 
     void takeRegisterIndex(T reg) {
         bits_ &= ~(SetType(1) << reg.code());
     }
     void takeAllocatable(T reg) {
         bits_ &= ~reg.alignedOrDominatedAliasedSet();
     }
 
-    static constexpr enum RegTypeName DefaultType = RegType::DefaultType;
-
-    template <enum RegTypeName Name>
-    SetType allLive() const {
-        return T::template LiveAsIndexableSet<Name>(bits_);
+    T getAny() const {
+        // The choice of first or last here is mostly arbitrary, as they are
+        // about the same speed on popular architectures. We choose first, as
+        // it has the advantage of using the "lower" registers more often. These
+        // registers are sometimes more efficient (e.g. optimized encodings for
+        // EAX on x86).
+        return getFirst();
     }
-    template <enum RegTypeName Name>
-    SetType allAllocatable() const {
-        return T::template AllocatableAsIndexableSet<Name>(bits_);
+    T getFirst() const {
+        MOZ_ASSERT(!empty());
+        return T::FromCode(T::FirstBit(bits_));
     }
-
-    static RegType FirstRegister(SetType set) {
-        return RegType::FromCode(RegType::FirstBit(set));
-    }
-    static RegType LastRegister(SetType set) {
-        return RegType::FromCode(RegType::LastBit(set));
+    T getLast() const {
+        MOZ_ASSERT(!empty());
+        int ireg = T::LastBit(bits_);
+        return T::FromCode(ireg);
     }
 
     SetType bits() const {
         return bits_;
     }
     uint32_t size() const {
         return T::SetSize(bits_);
     }
@@ -476,19 +476,16 @@ class RegisterSet {
         gpr_.clear();
     }
     bool emptyGeneral() const {
         return gpr_.empty();
     }
     bool emptyFloat() const {
         return fpu_.empty();
     }
-
-    static constexpr enum RegTypeName DefaultType = RegTypeName::GPR;
-
     constexpr GeneralRegisterSet gprs() const {
         return gpr_;
     }
     GeneralRegisterSet& gprs() {
         return gpr_;
     }
     constexpr FloatRegisterSet fpus() const {
         return fpu_;
@@ -538,19 +535,16 @@ template <typename RegisterSet>
 class AllocatableSet;
 
 template <typename RegisterSet>
 class LiveSet;
 
 // Base accessors classes have the minimal set of raw methods to manipulate the register set
 // given as parameter in a consistent manner.  These methods are:
 //
-//    - all<Type>: Returns a bit-set of all the register of a specific type
-//      which are present.
-//
 //    - has: Returns if all the bits needed to take a register are present.
 //
 //    - takeUnchecked: Subtracts the bits used to represent the register in the
 //      register set.
 //
 //    - addUnchecked: Adds the bits used to represent the register in the
 //      register set.
 
@@ -574,35 +568,25 @@ class AllocatableSetAccessors
   public:
     typedef Set RegSet;
     typedef typename RegSet::RegType RegType;
     typedef typename RegSet::SetType SetType;
 
   protected:
     RegSet set_;
 
-    template <enum RegTypeName Name>
-    SetType all() const {
-        return set_.template allAllocatable<Name>();
-    }
-
   public:
     AllocatableSetAccessors() : set_() {}
     explicit constexpr AllocatableSetAccessors(SetType set) : set_(set) {}
     explicit constexpr AllocatableSetAccessors(RegSet set) : set_(set) {}
 
     bool has(RegType reg) const {
         return set_.hasAllocatable(reg);
     }
 
-    template <enum RegTypeName Name>
-    bool hasAny(RegType reg) const {
-        return all<Name>() != 0;
-    }
-
     void addUnchecked(RegType reg) {
         set_.addAllocatable(reg);
     }
 
     void takeUnchecked(RegType reg) {
         set_.takeAllocatable(reg);
     }
 };
@@ -614,25 +598,16 @@ class AllocatableSetAccessors<RegisterSe
   public:
     typedef RegisterSet RegSet;
     typedef AnyRegister RegType;
     typedef char SetType;
 
   protected:
     RegisterSet set_;
 
-    template <enum RegTypeName Name>
-    GeneralRegisterSet::SetType allGpr() const {
-        return set_.gprs().allAllocatable<Name>();
-    }
-    template <enum RegTypeName Name>
-    FloatRegisterSet::SetType allFpu() const {
-        return set_.fpus().allAllocatable<Name>();
-    }
-
   public:
     AllocatableSetAccessors() : set_() {}
     explicit constexpr AllocatableSetAccessors(SetType) = delete;
     explicit constexpr AllocatableSetAccessors(RegisterSet set) : set_(set) {}
 
     bool has(Register reg) const {
         return set_.gprs().hasAllocatable(reg);
     }
@@ -675,21 +650,16 @@ class LiveSetAccessors
   public:
     typedef Set RegSet;
     typedef typename RegSet::RegType RegType;
     typedef typename RegSet::SetType SetType;
 
   protected:
     RegSet set_;
 
-    template <enum RegTypeName Name>
-    SetType all() const {
-        return set_.template allLive<Name>();
-    }
-
   public:
     LiveSetAccessors() : set_() {}
     explicit constexpr LiveSetAccessors(SetType set) : set_(set) {}
     explicit constexpr LiveSetAccessors(RegSet set) : set_(set) {}
 
     bool has(RegType reg) const {
         return set_.hasRegisterIndex(reg);
     }
@@ -710,25 +680,16 @@ class LiveSetAccessors<RegisterSet>
   public:
     typedef RegisterSet RegSet;
     typedef AnyRegister RegType;
     typedef char SetType;
 
   protected:
     RegisterSet set_;
 
-    template <enum RegTypeName Name>
-    GeneralRegisterSet::SetType allGpr() const {
-        return set_.gprs().allLive<Name>();
-    }
-    template <enum RegTypeName Name>
-    FloatRegisterSet::SetType allFpu() const {
-        return set_.fpus().allLive<Name>();
-    }
-
   public:
     LiveSetAccessors() : set_() {}
     explicit constexpr LiveSetAccessors(SetType) = delete;
     explicit constexpr LiveSetAccessors(RegisterSet set) : set_(set) {}
 
     bool has(Register reg) const {
         return set_.gprs().hasRegisterIndex(reg);
     }
@@ -785,94 +746,72 @@ class SpecializedRegSet : public Accesso
     }
 
     using Parent::takeUnchecked;
     void take(RegType reg) {
         MOZ_ASSERT(has(reg));
         takeUnchecked(reg);
     }
 
-    template <enum RegTypeName Name>
-    bool hasAny() const {
-        return Parent::template all<Name>() != 0;
+    RegType getAny() const {
+        return this->Parent::set_.getAny();
+    }
+    RegType getFirst() const {
+        return this->Parent::set_.getFirst();
+    }
+    RegType getLast() const {
+        return this->Parent::set_.getLast();
     }
 
-    template <enum RegTypeName Name = RegSet::DefaultType>
-    RegType getFirst() const {
-        SetType set = Parent::template all<Name>();
-        MOZ_ASSERT(set);
-        return RegSet::FirstRegister(set);
-    }
-    template <enum RegTypeName Name = RegSet::DefaultType>
-    RegType getLast() const {
-        SetType set = Parent::template all<Name>();
-        MOZ_ASSERT(set);
-        return RegSet::LastRegister(set);
-    }
-    template <enum RegTypeName Name = RegSet::DefaultType>
-    RegType getAny() const {
-        // The choice of first or last here is mostly arbitrary, as they are
-        // about the same speed on popular architectures. We choose first, as
-        // it has the advantage of using the "lower" registers more often. These
-        // registers are sometimes more efficient (e.g. optimized encodings for
-        // EAX on x86).
-        return getFirst<Name>();
-    }
-
-    template <enum RegTypeName Name = RegSet::DefaultType>
     RegType getAnyExcluding(RegType preclude) {
         if (!has(preclude))
-            return getAny<Name>();
+            return getAny();
 
         take(preclude);
-        RegType result = getAny<Name>();
+        RegType result = getAny();
         add(preclude);
         return result;
     }
 
-    template <enum RegTypeName Name = RegSet::DefaultType>
     RegType takeAny() {
-        RegType reg = getAny<Name>();
+        RegType reg = getAny();
         take(reg);
         return reg;
     }
-    template <enum RegTypeName Name = RegSet::DefaultType>
     RegType takeFirst() {
-        RegType reg = getFirst<Name>();
+        RegType reg = getFirst();
         take(reg);
         return reg;
     }
-    template <enum RegTypeName Name = RegSet::DefaultType>
     RegType takeLast() {
-        RegType reg = getLast<Name>();
+        RegType reg = getLast();
         take(reg);
         return reg;
     }
 
     ValueOperand takeAnyValue() {
 #if defined(JS_NUNBOX32)
-        return ValueOperand(takeAny<RegTypeName::GPR>(), takeAny<RegTypeName::GPR>());
+        return ValueOperand(takeAny(), takeAny());
 #elif defined(JS_PUNBOX64)
-        return ValueOperand(takeAny<RegTypeName::GPR>());
+        return ValueOperand(takeAny());
 #else
 #error "Bad architecture"
 #endif
     }
 
     bool aliases(ValueOperand v) const {
 #ifdef JS_NUNBOX32
         return has(v.typeReg()) || has(v.payloadReg());
 #else
         return has(v.valueReg());
 #endif
     }
 
-    template <enum RegTypeName Name = RegSet::DefaultType>
     RegType takeAnyExcluding(RegType preclude) {
-        RegType reg = getAnyExcluding<Name>(preclude);
+        RegType reg = getAnyExcluding(preclude);
         take(reg);
         return reg;
     }
 };
 
 // Specialization of the accessors for the RegisterSet aggregate.
 template <class Accessors>
 class SpecializedRegSet<Accessors, RegisterSet> : public Accessors
@@ -897,27 +836,22 @@ class SpecializedRegSet<Accessors, Regis
 
     bool emptyGeneral() const {
         return this->Parent::set_.emptyGeneral();
     }
     bool emptyFloat() const {
         return this->Parent::set_.emptyFloat();
     }
 
+
     using Parent::has;
     bool has(AnyRegister reg) const {
         return reg.isFloat() ? has(reg.fpu()) : has(reg.gpr());
     }
 
-    template <enum RegTypeName Name>
-    bool hasAny() const {
-        if (Name == RegTypeName::GPR)
-            return Parent::template allGpr<RegTypeName::GPR>() != 0;
-        return Parent::template allFpu<Name>() != 0;
-    }
 
     using Parent::addUnchecked;
     void addUnchecked(AnyRegister reg) {
         if (reg.isFloat())
             addUnchecked(reg.fpu());
         else
             addUnchecked(reg.gpr());
     }
@@ -956,35 +890,29 @@ class SpecializedRegSet<Accessors, Regis
     void take(AnyRegister reg) {
         if (reg.isFloat())
             take(reg.fpu());
         else
             take(reg.gpr());
     }
 
     Register getAnyGeneral() const {
-        GeneralRegisterSet::SetType set = Parent::template allGpr<RegTypeName::GPR>();
-        MOZ_ASSERT(set);
-        return GeneralRegisterSet::FirstRegister(set);
+        return this->Parent::set_.gprs().getAny();
     }
-    template <enum RegTypeName Name = RegTypeName::Float64>
     FloatRegister getAnyFloat() const {
-        FloatRegisterSet::SetType set = Parent::template allFpu<Name>();
-        MOZ_ASSERT(set);
-        return FloatRegisterSet::FirstRegister(set);
+        return this->Parent::set_.fpus().getAny();
     }
 
     Register takeAnyGeneral() {
         Register reg = getAnyGeneral();
         take(reg);
         return reg;
     }
-    template <enum RegTypeName Name = RegTypeName::Float64>
     FloatRegister takeAnyFloat() {
-        FloatRegister reg = getAnyFloat<Name>();
+        FloatRegister reg = getAnyFloat();
         take(reg);
         return reg;
     }
     ValueOperand takeAnyValue() {
 #if defined(JS_NUNBOX32)
         return ValueOperand(takeAnyGeneral(), takeAnyGeneral());
 #elif defined(JS_PUNBOX64)
         return ValueOperand(takeAnyGeneral());
@@ -1172,21 +1100,21 @@ class TypedRegisterIterator
     { }
     TypedRegisterIterator(const TypedRegisterIterator& other) : regset_(other.regset_)
     { }
 
     bool more() const {
         return !regset_.empty();
     }
     TypedRegisterIterator<T>& operator ++() {
-        regset_.template takeAny<RegTypeName::Any>();
+        regset_.takeAny();
         return *this;
     }
     T operator*() const {
-        return regset_.template getAny<RegTypeName::Any>();
+        return regset_.getAny();
     }
 };
 
 // iterates backwards, that is, rn to r0
 template <typename T>
 class TypedRegisterBackwardIterator
 {
     LiveSet<TypedRegisterSet<T>> regset_;
@@ -1199,21 +1127,21 @@ class TypedRegisterBackwardIterator
     TypedRegisterBackwardIterator(const TypedRegisterBackwardIterator& other)
       : regset_(other.regset_)
     { }
 
     bool more() const {
         return !regset_.empty();
     }
     TypedRegisterBackwardIterator<T>& operator ++() {
-        regset_.template takeLast<RegTypeName::Any>();
+        regset_.takeLast();
         return *this;
     }
     T operator*() const {
-        return regset_.template getLast<RegTypeName::Any>();
+        return regset_.getLast();
     }
 };
 
 // iterates forwards, that is r0 to rn
 template <typename T>
 class TypedRegisterForwardIterator
 {
     LiveSet<TypedRegisterSet<T>> regset_;
@@ -1225,21 +1153,21 @@ class TypedRegisterForwardIterator
     { }
     TypedRegisterForwardIterator(const TypedRegisterForwardIterator& other) : regset_(other.regset_)
     { }
 
     bool more() const {
         return !regset_.empty();
     }
     TypedRegisterForwardIterator<T>& operator ++() {
-        regset_.template takeFirst<RegTypeName::Any>();
+        regset_.takeFirst();
         return *this;
     }
     T operator*() const {
-        return regset_.template getFirst<RegTypeName::Any>();
+        return regset_.getFirst();
     }
 };
 
 typedef TypedRegisterIterator<Register> GeneralRegisterIterator;
 typedef TypedRegisterIterator<FloatRegister> FloatRegisterIterator;
 typedef TypedRegisterBackwardIterator<Register> GeneralRegisterBackwardIterator;
 typedef TypedRegisterBackwardIterator<FloatRegister> FloatRegisterBackwardIterator;
 typedef TypedRegisterForwardIterator<Register> GeneralRegisterForwardIterator;
--- a/js/src/jit/Registers.h
+++ b/js/src/jit/Registers.h
@@ -83,58 +83,27 @@ struct Register {
         MOZ_ASSERT(aliasIdx == 0);
         *ret = *this;
     }
 
     SetType alignedOrDominatedAliasedSet() const {
         return SetType(1) << code();
     }
 
-    static constexpr enum RegTypeName DefaultType = RegTypeName::GPR;
-
-    template <enum RegTypeName = DefaultType>
-    static SetType LiveAsIndexableSet(SetType s) {
-        return SetType(0);
-    }
-
-    template <enum RegTypeName Name = DefaultType>
-    static SetType AllocatableAsIndexableSet(SetType s) {
-        static_assert(Name != RegTypeName::Any, "Allocatable set are not iterable");
-        return SetType(0);
-    }
-
     static uint32_t SetSize(SetType x) {
         return Codes::SetSize(x);
     }
     static uint32_t FirstBit(SetType x) {
         return Codes::FirstBit(x);
     }
     static uint32_t LastBit(SetType x) {
         return Codes::LastBit(x);
     }
 };
 
-template <> inline Register::SetType
-Register::LiveAsIndexableSet<RegTypeName::GPR>(SetType set)
-{
-    return set;
-}
-
-template <> inline Register::SetType
-Register::LiveAsIndexableSet<RegTypeName::Any>(SetType set)
-{
-    return set;
-}
-
-template <> inline Register::SetType
-Register::AllocatableAsIndexableSet<RegTypeName::GPR>(SetType set)
-{
-    return set;
-}
-
 #if defined(JS_NUNBOX32)
 static const uint32_t INT64LOW_OFFSET = 0 * sizeof(int32_t);
 static const uint32_t INT64HIGH_OFFSET = 1 * sizeof(int32_t);
 #endif
 
 struct Register64
 {
 #ifdef JS_PUNBOX64
--- a/js/src/jit/StupidAllocator.cpp
+++ b/js/src/jit/StupidAllocator.cpp
@@ -76,18 +76,17 @@ StupidAllocator::init()
     // Assign physical registers to the tracked allocation.
     {
         registerCount = 0;
         LiveRegisterSet remainingRegisters(allRegisters_.asLiveSet());
         while (!remainingRegisters.emptyGeneral())
             registers[registerCount++].reg = AnyRegister(remainingRegisters.takeAnyGeneral());
 
         while (!remainingRegisters.emptyFloat())
-            registers[registerCount++].reg =
-                AnyRegister(remainingRegisters.takeAnyFloat<RegTypeName::Any>());
+            registers[registerCount++].reg = AnyRegister(remainingRegisters.takeAnyFloat());
 
         MOZ_ASSERT(registerCount <= MAX_REGISTERS);
     }
 
     return true;
 }
 
 bool
--- a/js/src/jit/arm/Architecture-arm.h
+++ b/js/src/jit/arm/Architecture-arm.h
@@ -7,18 +7,16 @@
 #ifndef jit_arm_Architecture_arm_h
 #define jit_arm_Architecture_arm_h
 
 #include "mozilla/MathAlgorithms.h"
 
 #include <limits.h>
 #include <stdint.h>
 
-#include "jit/shared/Architecture-shared.h"
-
 #include "js/Utility.h"
 
 // GCC versions 4.6 and above define __ARM_PCS_VFP to denote a hard-float
 // ABI target. The iOS toolchain doesn't define anything specific here,
 // but iOS always supports VFP.
 #if defined(__ARM_PCS_VFP) || defined(XP_IOS)
 #define JS_CODEGEN_ARM_HARDFP
 #endif
@@ -282,47 +280,16 @@ class FloatRegisters
     static const uint32_t Total = 48;
     static const uint32_t TotalDouble = 16;
     static const uint32_t TotalSingle = 32;
     static const uint32_t Allocatable = 45;
     // There are only 32 places that we can put values.
     static const uint32_t TotalPhys = 32;
     static uint32_t ActualTotalPhys();
 
-    // ARM float registers overlap in a way that for 1 double registers, in the
-    // range d0-d15, we have 2 singles register in the range s0-s31. d16-d31
-    // have no single register aliases.  The aliasing rule state that d{n}
-    // aliases s{2n} and s{2n+1}, for n in [0 .. 15].
-    //
-    // The register set is used to represent either allocatable register or live
-    // registers. The register maps d0-d15 and s0-s31 to a single bit each. The
-    // registers d16-d31 are not used at the moment.
-    //
-    // uuuu uuuu uuuu uuuu dddd dddd dddd dddd ssss ssss ssss ssss ssss ssss ssss ssss
-    //                     ^                 ^ ^                                     ^
-    //                     '-- d15      d0 --' '-- s31                          s0 --'
-    //
-    // LiveSet are handled by adding the bit of each register without
-    // considering the aliases.
-    //
-    // AllocatableSet are handled by adding and removing the bit of each
-    // aligned-or-dominated-aliased registers.
-    //
-    //     ...0...00... : s{2n}, s{2n+1} and d{n} are not available
-    //     ...1...01... : s{2n} is available (*)
-    //     ...0...10... : s{2n+1} is available
-    //     ...1...11... : s{2n}, s{2n+1} and d{n} are available
-    //
-    // (*) Note that d{n} bit is set, but is not available because s{2n+1} bit
-    // is not set, which is required as d{n} dominates s{2n+1}. The d{n} bit is
-    // set, because s{2n} is aligned.
-    //
-    //        |        d{n}       |
-    //        | s{2n+1} |  s{2n}  |
-    //
     typedef uint64_t SetType;
     static const SetType AllSingleMask = (1ull << TotalSingle) - 1;
     static const SetType AllDoubleMask = ((1ull << TotalDouble) - 1) << TotalSingle;
     static const SetType AllMask = AllDoubleMask | AllSingleMask;
 
     // d15 is the ScratchFloatReg.
     static const SetType NonVolatileDoubleMask =
          ((1ULL << d8) |
@@ -385,27 +352,30 @@ class VFPRegister
     };
 
     typedef FloatRegisters Codes;
     typedef Codes::Code Code;
     typedef Codes::Encoding Encoding;
 
   protected:
     RegType kind : 2;
+    // ARM doesn't have more than 32 registers. Don't take more bits than we'll
+    // need. Presently, we don't have plans to address the upper and lower
+    // halves of the double registers seprately, so 5 bits should suffice. If we
+    // do decide to address them seprately (vmov, I'm looking at you), we will
+    // likely specify it as a separate field.
   public:
-    // ARM doesn't have more than 32 registers of each type, so 5 bits should
-    // suffice.
     uint32_t code_ : 5;
   protected:
     bool _isInvalid : 1;
     bool _isMissing : 1;
 
   public:
     constexpr VFPRegister(uint32_t r, RegType k)
-      : kind(k), code_(Code(r)), _isInvalid(false), _isMissing(false)
+      : kind(k), code_ (Code(r)), _isInvalid(false), _isMissing(false)
     { }
     constexpr VFPRegister()
       : kind(Double), code_(Code(0)), _isInvalid(true), _isMissing(false)
     { }
 
     constexpr VFPRegister(RegType k, uint32_t id, bool invalid, bool missing) :
         kind(k), code_(Code(id)), _isInvalid(invalid), _isMissing(missing) {
     }
@@ -558,17 +528,17 @@ class VFPRegister
     // This function is used to ensure that Register set can take all Single
     // registers, even if we are taking a mix of either double or single
     // registers.
     //
     //   s0.alignedOrDominatedAliasedSet() == s0 | d0.
     //   s1.alignedOrDominatedAliasedSet() == s1.
     //   d0.alignedOrDominatedAliasedSet() == s0 | s1 | d0.
     //
-    // This way the Allocatable register set does not have to do any arithmetics
+    // This way the Allocator register set does not have to do any arithmetics
     // to know if a register is available or not, as we have the following
     // relations:
     //
     //   d0.alignedOrDominatedAliasedSet() ==
     //       s0.alignedOrDominatedAliasedSet() | s1.alignedOrDominatedAliasedSet()
     //
     //   s0.alignedOrDominatedAliasedSet() & s1.alignedOrDominatedAliasedSet() == 0
     //
@@ -578,29 +548,16 @@ class VFPRegister
                 return SetType(1) << code_;
             return (SetType(1) << code_) | (SetType(1) << (32 + code_ / 2));
         }
 
         MOZ_ASSERT(isDouble());
         return (SetType(0b11) << (code_ * 2)) | (SetType(1) << (32 + code_));
     }
 
-    static constexpr enum RegTypeName DefaultType = RegTypeName::Float64;
-
-    template <enum RegTypeName = DefaultType>
-    static SetType LiveAsIndexableSet(SetType s) {
-        return SetType(0);
-    }
-
-    template <enum RegTypeName Name = DefaultType>
-    static SetType AllocatableAsIndexableSet(SetType s) {
-        static_assert(Name != RegTypeName::Any, "Allocatable set are not iterable");
-        return SetType(0);
-    }
-
     static uint32_t SetSize(SetType x) {
         static_assert(sizeof(SetType) == 8, "SetType must be 64 bits");
         return mozilla::CountPopulation32(x);
     }
     static Code FromName(const char* name) {
         return FloatRegisters::FromName(name);
     }
     static TypedRegisterSet<VFPRegister> ReduceSetForPush(const TypedRegisterSet<VFPRegister>& s);
@@ -610,89 +567,16 @@ class VFPRegister
         return mozilla::CountTrailingZeroes64(x);
     }
     static uint32_t LastBit(SetType x) {
         return 63 - mozilla::CountLeadingZeroes64(x);
     }
 
 };
 
-template <> inline VFPRegister::SetType
-VFPRegister::LiveAsIndexableSet<RegTypeName::Float32>(SetType set)
-{
-    return set & FloatRegisters::AllSingleMask;
-}
-
-template <> inline VFPRegister::SetType
-VFPRegister::LiveAsIndexableSet<RegTypeName::Float64>(SetType set)
-{
-    return set & FloatRegisters::AllDoubleMask;
-}
-
-template <> inline VFPRegister::SetType
-VFPRegister::LiveAsIndexableSet<RegTypeName::Any>(SetType set)
-{
-    return set;
-}
-
-template <> inline VFPRegister::SetType
-VFPRegister::AllocatableAsIndexableSet<RegTypeName::Float32>(SetType set)
-{
-    // Single registers are not dominating any smaller registers, thus masking
-    // is enough to convert an allocatable set into a set of register list all
-    // single register available.
-    return set & FloatRegisters::AllSingleMask;
-}
-
-template <> inline VFPRegister::SetType
-VFPRegister::AllocatableAsIndexableSet<RegTypeName::Float64>(SetType set)
-{
-    // An allocatable float register set is represented as follow:
-    //
-    // uuuu uuuu uuuu uuuu dddd dddd dddd dddd ssss ssss ssss ssss ssss ssss ssss ssss
-    //                     ^                 ^ ^                                     ^
-    //                     '-- d15      d0 --' '-- s31                          s0 --'
-    //
-    //     ...0...00... : s{2n}, s{2n+1} and d{n} are not available
-    //     ...1...01... : s{2n} is available
-    //     ...0...10... : s{2n+1} is available
-    //     ...1...11... : s{2n}, s{2n+1} and d{n} are available
-    //
-    // The goal of this function is to return the set of double registers which
-    // are available as an indexable bit set. This implies that iff a double bit
-    // is set in the returned set, then the register is available.
-    //
-    // To do so, this functions converts the 32 bits set of single registers
-    // into a 16 bits set of equivalent double registers. Then, we mask out
-    // double registers which do not have all the single register that compose
-    // them. As d{n} bit is set when s{2n} is available, we only need to take
-    // s{2n+1} into account.
-
-    // Convert  s7s6s5s4 s3s2s1s0  into  s7s5s3s1, for all s0-s31.
-    SetType s2d = AllocatableAsIndexableSet<RegTypeName::Float32>(set);
-    static_assert(FloatRegisters::TotalSingle == 32, "Wrong mask");
-    s2d = (0xaaaaaaaa & s2d) >> 1; // Filter s{2n+1} registers.
-    // Group adjacent bits as follow:
-    //     0.0.s3.s1 == ((0.s3.0.s1) >> 1 | (0.s3.0.s1)) & 0b0011;
-    s2d = ((s2d >> 1) | s2d) & 0x33333333; // 0a0b --> 00ab
-    s2d = ((s2d >> 2) | s2d) & 0x0f0f0f0f; // 00ab00cd --> 0000abcd
-    s2d = ((s2d >> 4) | s2d) & 0x00ff00ff;
-    s2d = ((s2d >> 8) | s2d) & 0x0000ffff;
-    // Move the s7s5s3s1 to the aliased double positions.
-    s2d = s2d << FloatRegisters::TotalSingle;
-
-    // Note: We currently do not use any representation for d16-d31.
-    static_assert(FloatRegisters::TotalDouble == 16,
-        "d16-d31 do not have a single register mapping");
-
-    // Filter out any double register which are not allocatable due to
-    // non-aligned dominated single registers.
-    return set & s2d;
-}
-
 // The only floating point register set that we work with are the VFP Registers.
 typedef VFPRegister FloatRegister;
 
 uint32_t GetARMFlags();
 bool HasARMv7();
 bool HasMOVWT();
 bool HasLDSTREXBHD();           // {LD,ST}REX{B,H,D}
 bool HasDMBDSBISB();            // DMB, DSB, and ISB
--- a/js/src/jit/arm64/Architecture-arm64.h
+++ b/js/src/jit/arm64/Architecture-arm64.h
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_arm64_Architecture_arm64_h
 #define jit_arm64_Architecture_arm64_h
 
 #include "mozilla/Assertions.h"
 #include "mozilla/MathAlgorithms.h"
 
-#include "jit/shared/Architecture-shared.h"
-
 #include "js/Utility.h"
 
 namespace js {
 namespace jit {
 
 // AArch64 has 32 64-bit integer registers, x0 though x31.
 //  x31 is special and functions as both the stack pointer and a zero register.
 //  The bottom 32 bits of each of the X registers is accessible as w0 through w31.
@@ -266,18 +264,18 @@ class FloatRegisters
                 (1 << FloatRegisters::d20) | (1 << FloatRegisters::d21) |
                 (1 << FloatRegisters::d22) | (1 << FloatRegisters::d23) |
                 (1 << FloatRegisters::d24) | (1 << FloatRegisters::d25) |
                 (1 << FloatRegisters::d26) | (1 << FloatRegisters::d27) |
                 (1 << FloatRegisters::d28) | (1 << FloatRegisters::d29) |
                 (1 << FloatRegisters::d30)) * SpreadCoefficient;
 
     static const SetType VolatileMask = AllMask & ~NonVolatileMask;
-    static const SetType AllDoubleMask = AllPhysMask << TotalPhys;
-    static const SetType AllSingleMask = AllPhysMask;
+    static const SetType AllDoubleMask = AllMask;
+    static const SetType AllSingleMask = AllMask;
 
     static const SetType WrapperMask = VolatileMask;
 
     // d31 is the ScratchFloatReg.
     static const SetType NonAllocatableMask = (SetType(1) << FloatRegisters::d31) * SpreadCoefficient;
 
     // Registers that can be allocated without being saved, generally.
     static const SetType TempMask = VolatileMask & ~NonAllocatableMask;
@@ -427,57 +425,26 @@ struct FloatRegister
         JS_STATIC_ASSERT(sizeof(SetType) == 8);
         return mozilla::CountTrailingZeroes64(x);
     }
     static uint32_t LastBit(SetType x) {
         JS_STATIC_ASSERT(sizeof(SetType) == 8);
         return 63 - mozilla::CountLeadingZeroes64(x);
     }
 
-    static constexpr enum RegTypeName DefaultType = RegTypeName::Float64;
-
-    template <enum RegTypeName = DefaultType>
-    static SetType LiveAsIndexableSet(SetType s) {
-        return SetType(0);
-    }
-
-    template <enum RegTypeName Name = DefaultType>
-    static SetType AllocatableAsIndexableSet(SetType s) {
-        static_assert(Name != RegTypeName::Any, "Allocatable set are not iterable");
-        return LiveAsIndexableSet<Name>(s);
-    }
-
     static TypedRegisterSet<FloatRegister> ReduceSetForPush(const TypedRegisterSet<FloatRegister>& s);
     static uint32_t GetSizeInBytes(const TypedRegisterSet<FloatRegister>& s);
     static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister>& s);
     uint32_t getRegisterDumpOffsetInBytes();
 
   public:
     Code code_ : 8;
     FloatRegisters::Kind k_ : 1;
 };
 
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Float32>(SetType set)
-{
-    return set & FloatRegisters::AllSingleMask;
-}
-
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Float64>(SetType set)
-{
-    return set & FloatRegisters::AllDoubleMask;
-}
-
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Any>(SetType set)
-{
-    return set;
-}
-
 // ARM/D32 has double registers that cannot be treated as float32.
 // Luckily, ARMv8 doesn't have the same misfortune.
 inline bool
 hasUnaliasedDouble()
 {
     return false;
 }
 
--- a/js/src/jit/mips-shared/Architecture-mips-shared.h
+++ b/js/src/jit/mips-shared/Architecture-mips-shared.h
@@ -7,18 +7,16 @@
 #ifndef jit_mips_shared_Architecture_mips_shared_h
 #define jit_mips_shared_Architecture_mips_shared_h
 
 #include "mozilla/MathAlgorithms.h"
 
 #include <limits.h>
 #include <stdint.h>
 
-#include "jit/shared/Architecture-shared.h"
-
 #include "js/Utility.h"
 
 // gcc appears to use _mips_hard_float to denote
 // that the target is a hard-float target.
 #ifdef _mips_hard_float
 #define JS_CODEGEN_MIPS_HARDFP
 #endif
 
deleted file mode 100644
--- a/js/src/jit/shared/Architecture-shared.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef jit_shared_Architecture_shared_h
-#define jit_shared_Architecture_shared_h
-
-namespace js {
-namespace jit {
-
-enum class RegTypeName {
-    GPR,
-    Float32,
-    Float64,
-    Vector128,
-    Any
-};
-
-} // namespace jit
-} // namespace js
-
-#endif /* jit_shared_Architecture_shared_h */
--- a/js/src/jit/x86-shared/Architecture-x86-shared.h
+++ b/js/src/jit/x86-shared/Architecture-x86-shared.h
@@ -10,18 +10,16 @@
 #if !defined(JS_CODEGEN_X86) && !defined(JS_CODEGEN_X64)
 # error "Unsupported architecture!"
 #endif
 
 #include "mozilla/MathAlgorithms.h"
 
 #include <string.h>
 
-#include "jit/shared/Architecture-shared.h"
-
 #include "jit/x86-shared/Constants-x86-shared.h"
 
 namespace js {
 namespace jit {
 
 // Does this architecture support SIMD conversions between Uint32x4 and Float32x4?
 static constexpr bool SupportsUint32x4FloatConversions = false;
 
@@ -259,17 +257,16 @@ class FloatRegisters {
     static const SetType SpreadScalar = SpreadSingle | SpreadDouble;
     static const SetType SpreadVector = SpreadSimd128;
     static const SetType Spread = SpreadScalar | SpreadVector;
 
     static const SetType AllPhysMask = ((1 << TotalPhys) - 1);
     static const SetType AllMask = AllPhysMask * Spread;
     static const SetType AllDoubleMask = AllPhysMask * SpreadDouble;
     static const SetType AllSingleMask = AllPhysMask * SpreadSingle;
-    static const SetType AllVector128Mask = AllPhysMask * SpreadSimd128;
 
 #if defined(JS_CODEGEN_X86)
     static const SetType NonAllocatableMask =
         Spread * (1 << X86Encoding::xmm7);     // This is ScratchDoubleReg.
 
 #elif defined(JS_CODEGEN_X64)
     static const SetType NonAllocatableMask =
         Spread * (1 << X86Encoding::xmm15);    // This is ScratchDoubleReg.
@@ -434,58 +431,21 @@ struct FloatRegister {
     void alignedAliased(uint32_t aliasIdx, FloatRegister* ret) const {
         aliased(aliasIdx, ret);
     }
 
     SetType alignedOrDominatedAliasedSet() const {
         return Codes::Spread << reg_;
     }
 
-    static constexpr enum RegTypeName DefaultType = RegTypeName::Float64;
-
-    template <enum RegTypeName = DefaultType>
-    static SetType LiveAsIndexableSet(SetType s) {
-        return SetType(0);
-    }
-
-    template <enum RegTypeName Name = DefaultType>
-    static SetType AllocatableAsIndexableSet(SetType s) {
-        static_assert(Name != RegTypeName::Any, "Allocatable set are not iterable");
-        return LiveAsIndexableSet<Name>(s);
-    }
-
     static TypedRegisterSet<FloatRegister> ReduceSetForPush(const TypedRegisterSet<FloatRegister>& s);
     static uint32_t GetPushSizeInBytes(const TypedRegisterSet<FloatRegister>& s);
     uint32_t getRegisterDumpOffsetInBytes();
 };
 
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Float32>(SetType set)
-{
-    return set & FloatRegisters::AllSingleMask;
-}
-
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Float64>(SetType set)
-{
-    return set & FloatRegisters::AllDoubleMask;
-}
-
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Vector128>(SetType set)
-{
-    return set & FloatRegisters::AllVector128Mask;
-}
-
-template <> inline FloatRegister::SetType
-FloatRegister::LiveAsIndexableSet<RegTypeName::Any>(SetType set)
-{
-    return set;
-}
-
 // Arm/D32 has double registers that can NOT be treated as float32
 // and this requires some dances in lowering.
 inline bool
 hasUnaliasedDouble()
 {
     return false;
 }
 
--- a/js/src/jsapi-tests/testJitRegisterSet.cpp
+++ b/js/src/jsapi-tests/testJitRegisterSet.cpp
@@ -30,22 +30,16 @@ CoPrime(size_t a, size_t b)
             continue;                                       \
         for (size_t start = 0; start < RegTotal; start++) { \
             size_t index = start;
 
 #define END_INDEX_WALK                                      \
         }                                                   \
     }
 
-#define BEGIN_All_WALK(RegTotal)                            \
-    static const size_t Total = RegTotal;                   \
-    size_t walk = 1;                                        \
-    size_t start = 0;                                       \
-    size_t index = start;
-
 #define FOR_ALL_REGISTERS(Register, reg)            \
     do {                                            \
         Register reg = Register::FromCode(index);
 
 #define END_FOR_ALL_REGISTERS                    \
         index = (index + walk) % Total;          \
     } while(index != start)
 
@@ -137,75 +131,8 @@ BEGIN_TEST(testJitRegisterSet_FPU)
 
     CHECK(liveRegs.empty());
     CHECK(pool.set() == FloatRegisterSet::All());
 
     END_INDEX_WALK
     return true;
 }
 END_TEST(testJitRegisterSet_FPU)
-
-void pullAllFpus(AllocatableFloatRegisterSet& set, uint32_t& max_bits, uint32_t bits) {
-    FloatRegisterSet allocSet(set.bits());
-    FloatRegisterSet available_f32(allocSet.allAllocatable<RegTypeName::Float32>());
-    FloatRegisterSet available_f64(allocSet.allAllocatable<RegTypeName::Float64>());
-    FloatRegisterSet available_v128(allocSet.allAllocatable<RegTypeName::Vector128>());
-    for (FloatRegisterIterator it(available_f32); it.more(); ++it) {
-        FloatRegister tmp = *it;
-        set.take(tmp);
-        pullAllFpus(set, max_bits, bits + 32);
-        set.add(tmp);
-    }
-    for (FloatRegisterIterator it(available_f64); it.more(); ++it) {
-        FloatRegister tmp = *it;
-        set.take(tmp);
-        pullAllFpus(set, max_bits, bits + 64);
-        set.add(tmp);
-    }
-    for (FloatRegisterIterator it(available_v128); it.more(); ++it) {
-        FloatRegister tmp = *it;
-        set.take(tmp);
-        pullAllFpus(set, max_bits, bits + 128);
-        set.add(tmp);
-    }
-    if (bits >= max_bits)
-        max_bits = bits;
-}
-
-BEGIN_TEST(testJitRegisterSet_FPU_Aliases)
-{
-    BEGIN_All_WALK(FloatRegisters::Total);
-    FOR_ALL_REGISTERS(FloatRegister, reg) {
-        AllocatableFloatRegisterSet pool;
-        pool.add(reg);
-
-        uint32_t alias_bits = 0;
-        for (uint32_t i = 0; i < reg.numAlignedAliased(); i++) {
-            FloatRegister alias;
-            reg.alignedAliased(i, &alias);
-
-            if (alias.isSingle()) {
-                if (alias_bits <= 32)
-                    alias_bits = 32;
-            } else if (alias.isDouble()) {
-                if (alias_bits <= 64)
-                    alias_bits = 64;
-            } else if (alias.isSimd128()) {
-                if (alias_bits <= 128)
-                    alias_bits = 128;
-            }
-        }
-
-        uint32_t max_bits = 0;
-        pullAllFpus(pool, max_bits, 0);
-
-        // By adding one register, we expect that we should not be able to pull
-        // more than any of its aligned aliases.  This rule should hold for both
-        // x64 and ARM.
-        CHECK(max_bits <= alias_bits);
-
-        // We added one register, we expect to be able to pull it back.
-        CHECK(max_bits > 0);
-    } END_FOR_ALL_REGISTERS;
-
-    return true;
-}
-END_TEST(testJitRegisterSet_FPU_Aliases)
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -201,28 +201,16 @@ static const Register FuncPtrCallTemp = 
 // worth it yet.  CallTempReg2 seems safe.
 static const Register ScratchRegARM = CallTempReg2;
 
 # define INT_DIV_I64_CALLOUT
 # define I64_TO_FLOAT_CALLOUT
 # define FLOAT_TO_I64_CALLOUT
 #endif
 
-template<MIRType t>
-struct RegTypeOf {
-    static_assert(t == MIRType::Float32 || t == MIRType::Double, "Float mask type");
-};
-
-template<> struct RegTypeOf<MIRType::Float32> {
-    static constexpr RegTypeName value = RegTypeName::Float32;
-};
-template<> struct RegTypeOf<MIRType::Double> {
-    static constexpr RegTypeName value = RegTypeName::Float64;
-};
-
 class BaseCompiler
 {
     // We define our own ScratchRegister abstractions, deferring to
     // the platform's when possible.
 
 #if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
     typedef ScratchDoubleScope ScratchF64;
 #else
@@ -798,32 +786,45 @@ class BaseCompiler
     // ScratchFloat32Register is the same as ScratchDoubleRegister.
     //
     // It's a basic invariant of the AllocatableRegisterSet that it
     // deals properly with aliasing of registers: if s0 or s1 are
     // allocated then d0 is not allocatable; if s0 and s1 are freed
     // individually then d0 becomes allocatable.
 
     template<MIRType t>
+    FloatRegisters::SetType maskFromTypeFPU() {
+        static_assert(t == MIRType::Float32 || t == MIRType::Double, "Float mask type");
+        if (t == MIRType::Float32)
+            return FloatRegisters::AllSingleMask;
+        return FloatRegisters::AllDoubleMask;
+    }
+
+    template<MIRType t>
     bool hasFPU() {
-        return availFPU_.hasAny<RegTypeOf<t>::value>();
+        return !!(availFPU_.bits() & maskFromTypeFPU<t>());
     }
 
     bool isAvailable(FloatRegister r) {
         return availFPU_.has(r);
     }
 
     void allocFPU(FloatRegister r) {
         MOZ_ASSERT(isAvailable(r));
         availFPU_.take(r);
     }
 
     template<MIRType t>
     FloatRegister allocFPU() {
-        return availFPU_.takeAny<RegTypeOf<t>::value>();
+        MOZ_ASSERT(hasFPU<t>());
+        FloatRegister r =
+            FloatRegisterSet::Intersect(FloatRegisterSet(availFPU_.bits()),
+                                        FloatRegisterSet(maskFromTypeFPU<t>())).getAny();
+        availFPU_.take(r);
+        return r;
     }
 
     void freeFPU(FloatRegister r) {
         availFPU_.add(r);
     }
 
     ////////////////////////////////////////////////////////////
     //