Bug 1392530 part 1 - Make MDefinition::Opcode an enum class. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 22 Aug 2017 16:37:48 +0200
changeset 376178 8eb6c914f4e0cb6f53108753105ba8f924eb7fce
parent 376177 5ba4dfac42cb422839bf54ced6929aff080870e7
child 376179 0e9fad014b5b144ec9fb296246ee5e7f100770de
push id32376
push userkwierso@gmail.com
push dateWed, 23 Aug 2017 00:07:40 +0000
treeherdermozilla-central@64a45ee1731c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1392530
milestone57.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 1392530 part 1 - Make MDefinition::Opcode an enum class. r=nbp
js/src/jit/AliasAnalysisShared.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
js/src/jit/RangeAnalysis.cpp
js/src/jit/ScalarReplacement.cpp
js/src/jit/WasmBCE.cpp
js/src/jit/shared/CodeGenerator-shared.cpp
--- a/js/src/jit/AliasAnalysisShared.cpp
+++ b/js/src/jit/AliasAnalysisShared.cpp
@@ -69,93 +69,93 @@ GetObject(const MDefinition* ins)
 {
     if (!ins->getAliasSet().isStore() && !ins->getAliasSet().isLoad())
         return nullptr;
 
     // Note: only return the object if that objects owns that property.
     // I.e. the poperty isn't on the prototype chain.
     const MDefinition* object = nullptr;
     switch (ins->op()) {
-      case MDefinition::Op_InitializedLength:
-      case MDefinition::Op_LoadElement:
-      case MDefinition::Op_LoadUnboxedScalar:
-      case MDefinition::Op_LoadUnboxedObjectOrNull:
-      case MDefinition::Op_LoadUnboxedString:
-      case MDefinition::Op_StoreElement:
-      case MDefinition::Op_StoreUnboxedObjectOrNull:
-      case MDefinition::Op_StoreUnboxedString:
-      case MDefinition::Op_StoreUnboxedScalar:
-      case MDefinition::Op_SetInitializedLength:
-      case MDefinition::Op_ArrayLength:
-      case MDefinition::Op_SetArrayLength:
-      case MDefinition::Op_StoreElementHole:
-      case MDefinition::Op_FallibleStoreElement:
-      case MDefinition::Op_TypedObjectDescr:
-      case MDefinition::Op_Slots:
-      case MDefinition::Op_Elements:
-      case MDefinition::Op_MaybeCopyElementsForWrite:
-      case MDefinition::Op_MaybeToDoubleElement:
-      case MDefinition::Op_UnboxedArrayLength:
-      case MDefinition::Op_UnboxedArrayInitializedLength:
-      case MDefinition::Op_IncrementUnboxedArrayInitializedLength:
-      case MDefinition::Op_SetUnboxedArrayInitializedLength:
-      case MDefinition::Op_TypedArrayLength:
-      case MDefinition::Op_SetTypedObjectOffset:
-      case MDefinition::Op_SetDisjointTypedElements:
-      case MDefinition::Op_ArrayPopShift:
-      case MDefinition::Op_ArrayPush:
-      case MDefinition::Op_ArraySlice:
-      case MDefinition::Op_LoadTypedArrayElementHole:
-      case MDefinition::Op_StoreTypedArrayElementHole:
-      case MDefinition::Op_LoadFixedSlot:
-      case MDefinition::Op_LoadFixedSlotAndUnbox:
-      case MDefinition::Op_StoreFixedSlot:
-      case MDefinition::Op_GetPropertyPolymorphic:
-      case MDefinition::Op_SetPropertyPolymorphic:
-      case MDefinition::Op_GuardShape:
-      case MDefinition::Op_GuardReceiverPolymorphic:
-      case MDefinition::Op_GuardObjectGroup:
-      case MDefinition::Op_GuardObjectIdentity:
-      case MDefinition::Op_GuardClass:
-      case MDefinition::Op_GuardUnboxedExpando:
-      case MDefinition::Op_LoadUnboxedExpando:
-      case MDefinition::Op_LoadSlot:
-      case MDefinition::Op_StoreSlot:
-      case MDefinition::Op_InArray:
-      case MDefinition::Op_LoadElementHole:
-      case MDefinition::Op_TypedArrayElements:
-      case MDefinition::Op_TypedObjectElements:
-      case MDefinition::Op_CopyLexicalEnvironmentObject:
-      case MDefinition::Op_IsPackedArray:
+      case MDefinition::Opcode::InitializedLength:
+      case MDefinition::Opcode::LoadElement:
+      case MDefinition::Opcode::LoadUnboxedScalar:
+      case MDefinition::Opcode::LoadUnboxedObjectOrNull:
+      case MDefinition::Opcode::LoadUnboxedString:
+      case MDefinition::Opcode::StoreElement:
+      case MDefinition::Opcode::StoreUnboxedObjectOrNull:
+      case MDefinition::Opcode::StoreUnboxedString:
+      case MDefinition::Opcode::StoreUnboxedScalar:
+      case MDefinition::Opcode::SetInitializedLength:
+      case MDefinition::Opcode::ArrayLength:
+      case MDefinition::Opcode::SetArrayLength:
+      case MDefinition::Opcode::StoreElementHole:
+      case MDefinition::Opcode::FallibleStoreElement:
+      case MDefinition::Opcode::TypedObjectDescr:
+      case MDefinition::Opcode::Slots:
+      case MDefinition::Opcode::Elements:
+      case MDefinition::Opcode::MaybeCopyElementsForWrite:
+      case MDefinition::Opcode::MaybeToDoubleElement:
+      case MDefinition::Opcode::UnboxedArrayLength:
+      case MDefinition::Opcode::UnboxedArrayInitializedLength:
+      case MDefinition::Opcode::IncrementUnboxedArrayInitializedLength:
+      case MDefinition::Opcode::SetUnboxedArrayInitializedLength:
+      case MDefinition::Opcode::TypedArrayLength:
+      case MDefinition::Opcode::SetTypedObjectOffset:
+      case MDefinition::Opcode::SetDisjointTypedElements:
+      case MDefinition::Opcode::ArrayPopShift:
+      case MDefinition::Opcode::ArrayPush:
+      case MDefinition::Opcode::ArraySlice:
+      case MDefinition::Opcode::LoadTypedArrayElementHole:
+      case MDefinition::Opcode::StoreTypedArrayElementHole:
+      case MDefinition::Opcode::LoadFixedSlot:
+      case MDefinition::Opcode::LoadFixedSlotAndUnbox:
+      case MDefinition::Opcode::StoreFixedSlot:
+      case MDefinition::Opcode::GetPropertyPolymorphic:
+      case MDefinition::Opcode::SetPropertyPolymorphic:
+      case MDefinition::Opcode::GuardShape:
+      case MDefinition::Opcode::GuardReceiverPolymorphic:
+      case MDefinition::Opcode::GuardObjectGroup:
+      case MDefinition::Opcode::GuardObjectIdentity:
+      case MDefinition::Opcode::GuardClass:
+      case MDefinition::Opcode::GuardUnboxedExpando:
+      case MDefinition::Opcode::LoadUnboxedExpando:
+      case MDefinition::Opcode::LoadSlot:
+      case MDefinition::Opcode::StoreSlot:
+      case MDefinition::Opcode::InArray:
+      case MDefinition::Opcode::LoadElementHole:
+      case MDefinition::Opcode::TypedArrayElements:
+      case MDefinition::Opcode::TypedObjectElements:
+      case MDefinition::Opcode::CopyLexicalEnvironmentObject:
+      case MDefinition::Opcode::IsPackedArray:
         object = ins->getOperand(0);
         break;
-      case MDefinition::Op_GetPropertyCache:
-      case MDefinition::Op_LoadTypedArrayElementStatic:
-      case MDefinition::Op_StoreTypedArrayElementStatic:
-      case MDefinition::Op_GetDOMProperty:
-      case MDefinition::Op_GetDOMMember:
-      case MDefinition::Op_Call:
-      case MDefinition::Op_Compare:
-      case MDefinition::Op_GetArgumentsObjectArg:
-      case MDefinition::Op_SetArgumentsObjectArg:
-      case MDefinition::Op_GetFrameArgument:
-      case MDefinition::Op_SetFrameArgument:
-      case MDefinition::Op_CompareExchangeTypedArrayElement:
-      case MDefinition::Op_AtomicExchangeTypedArrayElement:
-      case MDefinition::Op_AtomicTypedArrayElementBinop:
-      case MDefinition::Op_AsmJSLoadHeap:
-      case MDefinition::Op_AsmJSStoreHeap:
-      case MDefinition::Op_WasmLoadTls:
-      case MDefinition::Op_WasmLoad:
-      case MDefinition::Op_WasmStore:
-      case MDefinition::Op_AsmJSCompareExchangeHeap:
-      case MDefinition::Op_AsmJSAtomicBinopHeap:
-      case MDefinition::Op_WasmLoadGlobalVar:
-      case MDefinition::Op_WasmStoreGlobalVar:
-      case MDefinition::Op_ArrayJoin:
+      case MDefinition::Opcode::GetPropertyCache:
+      case MDefinition::Opcode::LoadTypedArrayElementStatic:
+      case MDefinition::Opcode::StoreTypedArrayElementStatic:
+      case MDefinition::Opcode::GetDOMProperty:
+      case MDefinition::Opcode::GetDOMMember:
+      case MDefinition::Opcode::Call:
+      case MDefinition::Opcode::Compare:
+      case MDefinition::Opcode::GetArgumentsObjectArg:
+      case MDefinition::Opcode::SetArgumentsObjectArg:
+      case MDefinition::Opcode::GetFrameArgument:
+      case MDefinition::Opcode::SetFrameArgument:
+      case MDefinition::Opcode::CompareExchangeTypedArrayElement:
+      case MDefinition::Opcode::AtomicExchangeTypedArrayElement:
+      case MDefinition::Opcode::AtomicTypedArrayElementBinop:
+      case MDefinition::Opcode::AsmJSLoadHeap:
+      case MDefinition::Opcode::AsmJSStoreHeap:
+      case MDefinition::Opcode::WasmLoadTls:
+      case MDefinition::Opcode::WasmLoad:
+      case MDefinition::Opcode::WasmStore:
+      case MDefinition::Opcode::AsmJSCompareExchangeHeap:
+      case MDefinition::Opcode::AsmJSAtomicBinopHeap:
+      case MDefinition::Opcode::WasmLoadGlobalVar:
+      case MDefinition::Opcode::WasmStoreGlobalVar:
+      case MDefinition::Opcode::ArrayJoin:
         return nullptr;
       default:
 #ifdef DEBUG
         // Crash when the default aliasSet is overriden, but when not added in the list above.
         if (!ins->getAliasSet().isStore() || ins->getAliasSet().flags() != AliasSet::Flag::Any)
             MOZ_CRASH("Overridden getAliasSet without updating AliasAnalysisShared GetObject");
 #endif
 
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3458,37 +3458,37 @@ TryOptimizeLoadObjectOrNull(MDefinition*
     if (types->baseFlags() & ~(TYPE_FLAG_NULL | TYPE_FLAG_ANYOBJECT))
         return true;
 
     MDefinitionVector eliminateList(def->block()->graph().alloc());
 
     for (MUseDefIterator iter(def); iter; ++iter) {
         MDefinition* ndef = iter.def();
         switch (ndef->op()) {
-          case MDefinition::Op_Compare:
+          case MDefinition::Opcode::Compare:
             if (ndef->toCompare()->compareType() != MCompare::Compare_Null)
                 return true;
             break;
-          case MDefinition::Op_Test:
+          case MDefinition::Opcode::Test:
             break;
-          case MDefinition::Op_PostWriteBarrier:
+          case MDefinition::Opcode::PostWriteBarrier:
             break;
-          case MDefinition::Op_StoreFixedSlot:
+          case MDefinition::Opcode::StoreFixedSlot:
             break;
-          case MDefinition::Op_StoreSlot:
+          case MDefinition::Opcode::StoreSlot:
             break;
-          case MDefinition::Op_ToObjectOrNull:
+          case MDefinition::Opcode::ToObjectOrNull:
             if (!eliminateList.append(ndef->toToObjectOrNull()))
                 return false;
             break;
-          case MDefinition::Op_Unbox:
+          case MDefinition::Opcode::Unbox:
             if (ndef->type() != MIRType::Object)
                 return true;
             break;
-          case MDefinition::Op_TypeBarrier:
+          case MDefinition::Opcode::TypeBarrier:
             // For now, only handle type barriers which are not consumed
             // anywhere and only test that the value is null.
             if (ndef->hasUses() || ndef->resultTypeSet()->getKnownMIRType() != MIRType::Null)
                 return true;
             break;
           default:
             return true;
         }
@@ -3591,27 +3591,27 @@ jit::EliminateRedundantChecks(MIRGraph& 
         }
 
         for (MDefinitionIterator iter(block); iter; ) {
             MDefinition* def = *iter++;
 
             bool eliminated = false;
 
             switch (def->op()) {
-              case MDefinition::Op_BoundsCheck:
+              case MDefinition::Opcode::BoundsCheck:
                 if (!TryEliminateBoundsCheck(checks, index, def->toBoundsCheck(), &eliminated))
                     return false;
                 break;
-              case MDefinition::Op_TypeBarrier:
+              case MDefinition::Opcode::TypeBarrier:
                 if (!TryEliminateTypeBarrier(def->toTypeBarrier(), &eliminated))
                     return false;
                 break;
-              case MDefinition::Op_LoadFixedSlot:
-              case MDefinition::Op_LoadSlot:
-              case MDefinition::Op_LoadUnboxedObjectOrNull:
+              case MDefinition::Opcode::LoadFixedSlot:
+              case MDefinition::Opcode::LoadSlot:
+              case MDefinition::Opcode::LoadUnboxedObjectOrNull:
                 if (!TryOptimizeLoadObjectOrNull(def, &eliminateList))
                     return false;
                 break;
               default:
                 // Now that code motion passes have finished, replace
                 // instructions which pass through one of their operands
                 // (and perform additional checks) with that operand.
                 if (MDefinition* passthrough = PassthroughOperand(def))
@@ -3649,29 +3649,29 @@ NeedsKeepAlive(MInstruction* slotsOrElem
     MOZ_ASSERT(*iter == slotsOrElements);
     ++iter;
 
     while (true) {
         if (*iter == use)
             return false;
 
         switch (iter->op()) {
-          case MDefinition::Op_Nop:
-          case MDefinition::Op_Constant:
-          case MDefinition::Op_KeepAliveObject:
-          case MDefinition::Op_Unbox:
-          case MDefinition::Op_LoadSlot:
-          case MDefinition::Op_StoreSlot:
-          case MDefinition::Op_LoadFixedSlot:
-          case MDefinition::Op_StoreFixedSlot:
-          case MDefinition::Op_LoadElement:
-          case MDefinition::Op_StoreElement:
-          case MDefinition::Op_InitializedLength:
-          case MDefinition::Op_ArrayLength:
-          case MDefinition::Op_BoundsCheck:
+          case MDefinition::Opcode::Nop:
+          case MDefinition::Opcode::Constant:
+          case MDefinition::Opcode::KeepAliveObject:
+          case MDefinition::Opcode::Unbox:
+          case MDefinition::Opcode::LoadSlot:
+          case MDefinition::Opcode::StoreSlot:
+          case MDefinition::Opcode::LoadFixedSlot:
+          case MDefinition::Opcode::StoreFixedSlot:
+          case MDefinition::Opcode::LoadElement:
+          case MDefinition::Opcode::StoreElement:
+          case MDefinition::Opcode::InitializedLength:
+          case MDefinition::Opcode::ArrayLength:
+          case MDefinition::Opcode::BoundsCheck:
             iter++;
             break;
           default:
             return true;
         }
     }
 
     MOZ_CRASH("Unreachable");
@@ -3685,29 +3685,29 @@ jit::AddKeepAliveInstructions(MIRGraph& 
 
         for (MInstructionIterator insIter(block->begin()); insIter != block->end(); insIter++) {
             MInstruction* ins = *insIter;
             if (ins->type() != MIRType::Elements && ins->type() != MIRType::Slots)
                 continue;
 
             MDefinition* ownerObject;
             switch (ins->op()) {
-              case MDefinition::Op_ConstantElements:
+              case MDefinition::Opcode::ConstantElements:
                 continue;
-              case MDefinition::Op_ConvertElementsToDoubles:
+              case MDefinition::Opcode::ConvertElementsToDoubles:
                 // EliminateRedundantChecks should have replaced all uses.
                 MOZ_ASSERT(!ins->hasUses());
                 continue;
-              case MDefinition::Op_Elements:
-              case MDefinition::Op_TypedArrayElements:
-              case MDefinition::Op_TypedObjectElements:
+              case MDefinition::Opcode::Elements:
+              case MDefinition::Opcode::TypedArrayElements:
+              case MDefinition::Opcode::TypedObjectElements:
                 MOZ_ASSERT(ins->numOperands() == 1);
                 ownerObject = ins->getOperand(0);
                 break;
-              case MDefinition::Op_Slots:
+              case MDefinition::Opcode::Slots:
                 ownerObject = ins->toSlots()->object();
                 break;
               default:
                 MOZ_CRASH("Unexpected op");
             }
 
             MOZ_ASSERT(ownerObject->type() == MIRType::Object);
 
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -2792,19 +2792,19 @@ IonBuilder::improveTypesAtTest(MDefiniti
     // as possible.
 
     // All branches of this switch that don't want to fall through to the
     // default behavior must return.  The default behavior assumes that a true
     // test means the incoming ins is not null or undefined and that a false
     // tests means it's one of null, undefined, false, 0, "", and objects
     // emulating undefined
     switch (ins->op()) {
-      case MDefinition::Op_Not:
+      case MDefinition::Opcode::Not:
         return improveTypesAtTest(ins->toNot()->getOperand(0), !trueBranch, test);
-      case MDefinition::Op_IsObject: {
+      case MDefinition::Opcode::IsObject: {
         MDefinition* subject = ins->getOperand(0);
         TemporaryTypeSet* oldType = subject->resultTypeSet();
 
         // Create temporary typeset equal to the type if there is no resultTypeSet.
         TemporaryTypeSet tmp;
         if (!oldType) {
             if (subject->type() == MIRType::Value)
                 return Ok();
@@ -2821,17 +2821,17 @@ IonBuilder::improveTypesAtTest(MDefiniti
         else
             type = oldType->cloneWithoutObjects(alloc_->lifoAlloc());
 
         if (!type)
             return abort(AbortReason::Alloc);
 
         return replaceTypeSet(subject, type, test);
       }
-      case MDefinition::Op_Phi: {
+      case MDefinition::Opcode::Phi: {
         bool branchIsAnd = true;
         if (!detectAndOrStructure(ins->toPhi(), &branchIsAnd)) {
             // Just fall through to the default behavior.
             break;
         }
 
         // Now we have detected the triangular structure and determined if it
         // was an AND or an OR.
@@ -2859,17 +2859,17 @@ IonBuilder::improveTypesAtTest(MDefiniti
             if (!trueBranch) {
                 MOZ_TRY(improveTypesAtTest(ins->toPhi()->getOperand(0), false, test));
                 MOZ_TRY(improveTypesAtTest(ins->toPhi()->getOperand(1), false, test));
             }
         }
         return Ok();
       }
 
-      case MDefinition::Op_Compare:
+      case MDefinition::Opcode::Compare:
         return improveTypesAtCompare(ins->toCompare(), trueBranch, test);
 
       default:
         break;
     }
 
     // By default MTest tests ToBoolean(input). As a result in the true branch we can filter
     // undefined and null. In false branch we can only encounter undefined, null, false, 0, ""
@@ -3307,25 +3307,25 @@ IonBuilder::jsop_bitop(JSOp op)
     return Ok();
 }
 
 MDefinition::Opcode
 JSOpToMDefinition(JSOp op)
 {
     switch (op) {
       case JSOP_ADD:
-        return MDefinition::Op_Add;
+        return MDefinition::Opcode::Add;
       case JSOP_SUB:
-        return MDefinition::Op_Sub;
+        return MDefinition::Opcode::Sub;
       case JSOP_MUL:
-        return MDefinition::Op_Mul;
+        return MDefinition::Opcode::Mul;
       case JSOP_DIV:
-        return MDefinition::Op_Div;
+        return MDefinition::Opcode::Div;
       case JSOP_MOD:
-        return MDefinition::Op_Mod;
+        return MDefinition::Opcode::Mod;
       default:
         MOZ_CRASH("unexpected binary opcode");
     }
 }
 
 AbortReasonOr<Ok>
 IonBuilder::binaryArithTryConcat(bool* emitted, JSOp op, MDefinition* left, MDefinition* right)
 {
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -71,17 +71,17 @@ void
 MDefinition::PrintOpcodeName(GenericPrinter& out, MDefinition::Opcode op)
 {
     static const char * const names[] =
     {
 #define NAME(x) #x,
         MIR_OPCODE_LIST(NAME)
 #undef NAME
     };
-    const char* name = names[op];
+    const char* name = names[unsigned(op)];
     size_t len = strlen(name);
     for (size_t i = 0; i < len; i++)
         out.printf("%c", tolower(name[i]));
 }
 
 static MConstant*
 EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* ptypeChange = nullptr)
 {
@@ -94,57 +94,57 @@ EvaluateConstantOperands(TempAllocator& 
     if (!left->isConstant() || !right->isConstant())
         return nullptr;
 
     MConstant* lhs = left->toConstant();
     MConstant* rhs = right->toConstant();
     double ret = JS::GenericNaN();
 
     switch (ins->op()) {
-      case MDefinition::Op_BitAnd:
+      case MDefinition::Opcode::BitAnd:
         ret = double(lhs->toInt32() & rhs->toInt32());
         break;
-      case MDefinition::Op_BitOr:
+      case MDefinition::Opcode::BitOr:
         ret = double(lhs->toInt32() | rhs->toInt32());
         break;
-      case MDefinition::Op_BitXor:
+      case MDefinition::Opcode::BitXor:
         ret = double(lhs->toInt32() ^ rhs->toInt32());
         break;
-      case MDefinition::Op_Lsh:
+      case MDefinition::Opcode::Lsh:
         ret = double(uint32_t(lhs->toInt32()) << (rhs->toInt32() & 0x1F));
         break;
-      case MDefinition::Op_Rsh:
+      case MDefinition::Opcode::Rsh:
         ret = double(lhs->toInt32() >> (rhs->toInt32() & 0x1F));
         break;
-      case MDefinition::Op_Ursh:
+      case MDefinition::Opcode::Ursh:
         ret = double(uint32_t(lhs->toInt32()) >> (rhs->toInt32() & 0x1F));
         break;
-      case MDefinition::Op_Add:
+      case MDefinition::Opcode::Add:
         ret = lhs->numberToDouble() + rhs->numberToDouble();
         break;
-      case MDefinition::Op_Sub:
+      case MDefinition::Opcode::Sub:
         ret = lhs->numberToDouble() - rhs->numberToDouble();
         break;
-      case MDefinition::Op_Mul:
+      case MDefinition::Opcode::Mul:
         ret = lhs->numberToDouble() * rhs->numberToDouble();
         break;
-      case MDefinition::Op_Div:
+      case MDefinition::Opcode::Div:
         if (ins->toDiv()->isUnsigned()) {
             if (rhs->isInt32(0)) {
                 if (ins->toDiv()->trapOnError())
                     return nullptr;
                 ret = 0.0;
             } else {
                 ret = double(uint32_t(lhs->toInt32()) / uint32_t(rhs->toInt32()));
             }
         } else {
             ret = NumberDiv(lhs->numberToDouble(), rhs->numberToDouble());
         }
         break;
-      case MDefinition::Op_Mod:
+      case MDefinition::Opcode::Mod:
         if (ins->toMod()->isUnsigned()) {
             if (rhs->isInt32(0)) {
                 if (ins->toMod()->trapOnError())
                     return nullptr;
                 ret = 0.0;
             } else {
                 ret = double(uint32_t(lhs->toInt32()) % uint32_t(rhs->toInt32()));
             }
@@ -227,17 +227,17 @@ HashNumber
 MDefinition::addU32ToHash(HashNumber hash, uint32_t data)
 {
     return data + (hash << 6) + (hash << 16) - hash;
 }
 
 HashNumber
 MDefinition::valueHash() const
 {
-    HashNumber out = op();
+    HashNumber out = HashNumber(op());
     for (size_t i = 0, e = numOperands(); i < e; i++)
         out = addU32ToHash(out, getOperand(i)->id());
     if (MDefinition* dep = dependency())
         out = addU32ToHash(out, dep->id());
     return out;
 }
 
 bool
@@ -292,26 +292,26 @@ MInstruction::foldsToStore(TempAllocator
     if (mightAlias(store) != AliasType::MustAlias)
         return nullptr;
 
     if (!store->block()->dominates(block()))
         return nullptr;
 
     MDefinition* value;
     switch (store->op()) {
-      case Op_StoreFixedSlot:
+      case Opcode::StoreFixedSlot:
         value = store->toStoreFixedSlot()->value();
         break;
-      case Op_StoreSlot:
+      case Opcode::StoreSlot:
         value = store->toStoreSlot()->value();
         break;
-      case Op_StoreElement:
+      case Opcode::StoreElement:
         value = store->toStoreElement()->value();
         break;
-      case Op_StoreUnboxedObjectOrNull:
+      case Opcode::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.
@@ -2931,26 +2931,26 @@ MUrsh::infer(BaselineInspector* inspecto
 }
 
 static inline bool
 CanProduceNegativeZero(MDefinition* def)
 {
     // Test if this instruction can produce negative zero even when bailing out
     // and changing types.
     switch (def->op()) {
-        case MDefinition::Op_Constant:
+        case MDefinition::Opcode::Constant:
             if (def->type() == MIRType::Double && def->toConstant()->toDouble() == -0.0)
                 return true;
             MOZ_FALLTHROUGH;
-        case MDefinition::Op_BitAnd:
-        case MDefinition::Op_BitOr:
-        case MDefinition::Op_BitXor:
-        case MDefinition::Op_BitNot:
-        case MDefinition::Op_Lsh:
-        case MDefinition::Op_Rsh:
+        case MDefinition::Opcode::BitAnd:
+        case MDefinition::Opcode::BitOr:
+        case MDefinition::Opcode::BitXor:
+        case MDefinition::Opcode::BitNot:
+        case MDefinition::Opcode::Lsh:
+        case MDefinition::Opcode::Rsh:
             return false;
         default:
             return true;
     }
 }
 
 static inline bool
 NeedNegativeZeroCheck(MDefinition* def)
@@ -2960,17 +2960,17 @@ NeedNegativeZeroCheck(MDefinition* def)
 
     // Test if all uses have the same semantics for -0 and 0
     for (MUseIterator use = def->usesBegin(); use != def->usesEnd(); use++) {
         if (use->consumer()->isResumePoint())
             continue;
 
         MDefinition* use_def = use->consumer()->toDefinition();
         switch (use_def->op()) {
-          case MDefinition::Op_Add: {
+          case MDefinition::Opcode::Add: {
             // If add is truncating -0 and 0 are observed as the same.
             if (use_def->toAdd()->isTruncated())
                 break;
 
             // x + y gives -0, when both x and y are -0
 
             // Figure out the order in which the addition's operands will
             // execute. EdgeCaseAnalysis::analyzeLate has renumbered the MIR
@@ -2996,17 +2996,17 @@ NeedNegativeZeroCheck(MDefinition* def)
             if (def == first && CanProduceNegativeZero(second))
                 return true;
 
             // The negative zero check can always be removed on the second
             // executed operand; by the time this executes the first will have
             // been evaluated as int32 and the addition's result cannot be -0.
             break;
           }
-          case MDefinition::Op_Sub: {
+          case MDefinition::Opcode::Sub: {
             // If sub is truncating -0 and 0 are observed as the same
             if (use_def->toSub()->isTruncated())
                 break;
 
             // x + y gives -0, when x is -0 and y is 0
 
             // We can remove the negative zero check on the rhs, only if we
             // are sure the lhs isn't negative zero.
@@ -3018,47 +3018,47 @@ NeedNegativeZeroCheck(MDefinition* def)
             // optimized to not make a difference between zero and negative zero.
             MDefinition* lhs = use_def->toSub()->lhs();
             MDefinition* rhs = use_def->toSub()->rhs();
             if (rhs->id() < lhs->id() && CanProduceNegativeZero(lhs))
                 return true;
 
             MOZ_FALLTHROUGH;
           }
-          case MDefinition::Op_StoreElement:
-          case MDefinition::Op_StoreElementHole:
-          case MDefinition::Op_FallibleStoreElement:
-          case MDefinition::Op_LoadElement:
-          case MDefinition::Op_LoadElementHole:
-          case MDefinition::Op_LoadUnboxedScalar:
-          case MDefinition::Op_LoadTypedArrayElementHole:
-          case MDefinition::Op_CharCodeAt:
-          case MDefinition::Op_Mod:
+          case MDefinition::Opcode::StoreElement:
+          case MDefinition::Opcode::StoreElementHole:
+          case MDefinition::Opcode::FallibleStoreElement:
+          case MDefinition::Opcode::LoadElement:
+          case MDefinition::Opcode::LoadElementHole:
+          case MDefinition::Opcode::LoadUnboxedScalar:
+          case MDefinition::Opcode::LoadTypedArrayElementHole:
+          case MDefinition::Opcode::CharCodeAt:
+          case MDefinition::Opcode::Mod:
             // Only allowed to remove check when definition is the second operand
             if (use_def->getOperand(0) == def)
                 return true;
             for (size_t i = 2, e = use_def->numOperands(); i < e; i++) {
                 if (use_def->getOperand(i) == def)
                     return true;
             }
             break;
-          case MDefinition::Op_BoundsCheck:
+          case MDefinition::Opcode::BoundsCheck:
             // Only allowed to remove check when definition is the first operand
             if (use_def->toBoundsCheck()->getOperand(1) == def)
                 return true;
             break;
-          case MDefinition::Op_ToString:
-          case MDefinition::Op_FromCharCode:
-          case MDefinition::Op_TableSwitch:
-          case MDefinition::Op_Compare:
-          case MDefinition::Op_BitAnd:
-          case MDefinition::Op_BitOr:
-          case MDefinition::Op_BitXor:
-          case MDefinition::Op_Abs:
-          case MDefinition::Op_TruncateToInt32:
+          case MDefinition::Opcode::ToString:
+          case MDefinition::Opcode::FromCharCode:
+          case MDefinition::Opcode::TableSwitch:
+          case MDefinition::Opcode::Compare:
+          case MDefinition::Opcode::BitAnd:
+          case MDefinition::Opcode::BitOr:
+          case MDefinition::Opcode::BitXor:
+          case MDefinition::Opcode::Abs:
+          case MDefinition::Opcode::TruncateToInt32:
             // Always allowed to remove check. No matter which operand.
             break;
           default:
             return true;
         }
     }
     return false;
 }
@@ -3096,25 +3096,25 @@ MBinaryArithInstruction::printOpcode(Gen
     }
 }
 
 MBinaryArithInstruction*
 MBinaryArithInstruction::New(TempAllocator& alloc, Opcode op,
                              MDefinition* left, MDefinition* right)
 {
     switch (op) {
-      case Op_Add:
+      case Opcode::Add:
         return MAdd::New(alloc, left, right);
-      case Op_Sub:
+      case Opcode::Sub:
         return MSub::New(alloc, left, right);
-      case Op_Mul:
+      case Opcode::Mul:
         return MMul::New(alloc, left, right);
-      case Op_Div:
+      case Opcode::Div:
         return MDiv::New(alloc, left, right);
-      case Op_Mod:
+      case Opcode::Mod:
         return MMod::New(alloc, left, right);
       default:
         MOZ_CRASH("unexpected binary opcode");
     }
 }
 
 void
 MBinaryArithInstruction::setNumberSpecialization(TempAllocator& alloc, BaselineInspector* inspector,
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -490,21 +490,20 @@ class StoreDependency : public TempObjec
 };
 
 // An MDefinition is an SSA name.
 class MDefinition : public MNode
 {
     friend class MBasicBlock;
 
   public:
-    enum Opcode {
-#   define DEFINE_OPCODES(op) Op_##op,
+    enum class Opcode : uint16_t {
+#   define DEFINE_OPCODES(op) op,
         MIR_OPCODE_LIST(DEFINE_OPCODES)
 #   undef DEFINE_OPCODES
-        Op_Invalid
     };
 
   private:
     InlineList<MUse> uses_;        // Use chain.
     uint32_t id_;                  // Instruction ID, which after block re-ordering
                                    // is sorted within a basic block.
     uint32_t flags_;               // Bit flags.
     Range* range_;                 // Any computed range for this def.
@@ -1199,17 +1198,17 @@ class MInstruction
 
     // Instructions needing to hook into type analysis should return a
     // TypePolicy.
     virtual TypePolicy* typePolicy() = 0;
     virtual MIRType typePolicySpecialization() = 0;
 };
 
 #define INSTRUCTION_HEADER_WITHOUT_TYPEPOLICY(opcode)                       \
-    static const Opcode classOpcode = MDefinition::Op_##opcode;             \
+    static const Opcode classOpcode = Opcode::opcode;                       \
     using MThisOpcode = M##opcode;                                          \
     Opcode op() const override {                                            \
         return classOpcode;                                                 \
     }                                                                       \
     const char* opName() const override {                                   \
         return #opcode;                                                     \
     }                                                                       \
     void accept(MDefinitionVisitor* visitor) override {                     \
@@ -1357,17 +1356,17 @@ class MBinaryInstruction : public MAryIn
     }
 
   protected:
     HashNumber valueHash() const
     {
         MDefinition* lhs = getOperand(0);
         MDefinition* rhs = getOperand(1);
 
-        return op() + lhs->id() + rhs->id();
+        return HashNumber(op()) + lhs->id() + rhs->id();
     }
     bool binaryCongruentTo(const MDefinition* ins) const
     {
         if (op() != ins->op())
             return false;
 
         if (type() != ins->type())
             return false;
@@ -1420,17 +1419,17 @@ class MTernaryInstruction : public MAryI
 
   protected:
     HashNumber valueHash() const
     {
         MDefinition* first = getOperand(0);
         MDefinition* second = getOperand(1);
         MDefinition* third = getOperand(2);
 
-        return op() + first->id() + second->id() + third->id();
+        return HashNumber(op()) + first->id() + second->id() + third->id();
     }
 };
 
 class MQuaternaryInstruction : public MAryInstruction<4>
 {
   protected:
     MQuaternaryInstruction(MDefinition* first, MDefinition* second,
                            MDefinition* third, MDefinition* fourth)
@@ -1444,18 +1443,18 @@ class MQuaternaryInstruction : public MA
   protected:
     HashNumber valueHash() const
     {
         MDefinition* first = getOperand(0);
         MDefinition* second = getOperand(1);
         MDefinition* third = getOperand(2);
         MDefinition* fourth = getOperand(3);
 
-        return op() + first->id() + second->id() +
-                      third->id() + fourth->id();
+        return HashNumber(op()) + first->id() + second->id() +
+            third->id() + fourth->id();
     }
 };
 
 template <class T>
 class MVariadicT : public T
 {
     FixedList<MUse> operands_;
 
@@ -14148,17 +14147,17 @@ class MWasmLoadTls
 
     bool congruentTo(const MDefinition* ins) const override {
         return op() == ins->op() &&
                offset() == ins->toWasmLoadTls()->offset() &&
                type() == ins->type();
     }
 
     HashNumber valueHash() const override {
-        return op() + offset();
+        return HashNumber(op()) + offset();
     }
 
     AliasSet getAliasSet() const override {
         return aliases_;
     }
 };
 
 class MWasmBoundsCheck
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -3120,22 +3120,22 @@ RangeAnalysis::truncate()
                     if (!TruncateTest(alloc(), iter->toTest()))
                         return false;
                 }
                 continue;
             }
 
             // Remember all bitop instructions for folding after range analysis.
             switch (iter->op()) {
-              case MDefinition::Op_BitAnd:
-              case MDefinition::Op_BitOr:
-              case MDefinition::Op_BitXor:
-              case MDefinition::Op_Lsh:
-              case MDefinition::Op_Rsh:
-              case MDefinition::Op_Ursh:
+              case MDefinition::Opcode::BitAnd:
+              case MDefinition::Opcode::BitOr:
+              case MDefinition::Opcode::BitXor:
+              case MDefinition::Opcode::Lsh:
+              case MDefinition::Opcode::Rsh:
+              case MDefinition::Opcode::Ursh:
                 if (!bitops.append(static_cast<MBinaryBitwiseInstruction*>(*iter)))
                     return false;
                 break;
               default:;
             }
 
             bool shouldClone = false;
             MDefinition::TruncateKind kind = ComputeTruncateKind(*iter, &shouldClone);
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -177,89 +177,89 @@ IsObjectEscaped(MInstruction* ins, JSObj
                 JitSpew(JitSpew_Escape, "Observable object cannot be recovered");
                 return true;
             }
             continue;
         }
 
         MDefinition* def = consumer->toDefinition();
         switch (def->op()) {
-          case MDefinition::Op_StoreFixedSlot:
-          case MDefinition::Op_LoadFixedSlot:
+          case MDefinition::Opcode::StoreFixedSlot:
+          case MDefinition::Opcode::LoadFixedSlot:
             // Not escaped if it is the first argument.
             if (def->indexOf(*i) == 0)
                 break;
 
             JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
             return true;
 
-          case MDefinition::Op_LoadUnboxedScalar:
-          case MDefinition::Op_StoreUnboxedScalar:
-          case MDefinition::Op_LoadUnboxedObjectOrNull:
-          case MDefinition::Op_StoreUnboxedObjectOrNull:
-          case MDefinition::Op_LoadUnboxedString:
-          case MDefinition::Op_StoreUnboxedString:
+          case MDefinition::Opcode::LoadUnboxedScalar:
+          case MDefinition::Opcode::StoreUnboxedScalar:
+          case MDefinition::Opcode::LoadUnboxedObjectOrNull:
+          case MDefinition::Opcode::StoreUnboxedObjectOrNull:
+          case MDefinition::Opcode::LoadUnboxedString:
+          case MDefinition::Opcode::StoreUnboxedString:
             // Not escaped if it is the first argument.
             if (def->indexOf(*i) != 0) {
                 JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
                 return true;
             }
 
             if (!def->getOperand(1)->isConstant()) {
                 JitSpewDef(JitSpew_Escape, "is addressed with unknown index\n", def);
                 return true;
             }
 
             break;
 
-          case MDefinition::Op_PostWriteBarrier:
+          case MDefinition::Opcode::PostWriteBarrier:
             break;
 
-          case MDefinition::Op_Slots: {
+          case MDefinition::Opcode::Slots: {
 #ifdef DEBUG
             // Assert that MSlots are only used by MStoreSlot and MLoadSlot.
             MSlots* ins = def->toSlots();
             MOZ_ASSERT(ins->object() != 0);
             for (MUseIterator i(ins->usesBegin()); i != ins->usesEnd(); i++) {
                 // toDefinition should normally never fail, since they don't get
                 // captured by resume points.
                 MDefinition* def = (*i)->consumer()->toDefinition();
-                MOZ_ASSERT(def->op() == MDefinition::Op_StoreSlot ||
-                           def->op() == MDefinition::Op_LoadSlot);
+                MOZ_ASSERT(def->op() == MDefinition::Opcode::StoreSlot ||
+                           def->op() == MDefinition::Opcode::LoadSlot);
             }
 #endif
             break;
           }
 
-          case MDefinition::Op_GuardShape: {
+          case MDefinition::Opcode::GuardShape: {
             MGuardShape* guard = def->toGuardShape();
             MOZ_ASSERT(!ins->isGuardShape());
             if (obj->maybeShape() != guard->shape()) {
                 JitSpewDef(JitSpew_Escape, "has a non-matching guard shape\n", guard);
                 return true;
             }
             if (IsObjectEscaped(def->toInstruction(), obj)) {
                 JitSpewDef(JitSpew_Escape, "is indirectly escaped by\n", def);
                 return true;
             }
             break;
           }
 
-          case MDefinition::Op_Lambda:
-          case MDefinition::Op_LambdaArrow: {
+          case MDefinition::Opcode::Lambda:
+          case MDefinition::Opcode::LambdaArrow: {
             if (IsLambdaEscaped(def->toInstruction(), obj)) {
                 JitSpewDef(JitSpew_Escape, "is indirectly escaped by\n", def);
                 return true;
             }
             break;
           }
 
           // This instruction is a no-op used to verify that scalar replacement
           // is working as expected in jit-test.
-          case MDefinition::Op_AssertRecoveredOnBailout:
+          case MDefinition::Opcode::AssertRecoveredOnBailout:
             break;
 
           default:
             JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
             return true;
         }
     }
 
@@ -821,17 +821,17 @@ IsElementEscaped(MElements* def, uint32_
     JitSpewIndent spewIndent(JitSpew_Escape);
 
     for (MUseIterator i(def->usesBegin()); i != def->usesEnd(); i++) {
         // The MIRType::Elements cannot be captured in a resume point as
         // it does not represent a value allocation.
         MDefinition* access = (*i)->consumer()->toDefinition();
 
         switch (access->op()) {
-          case MDefinition::Op_LoadElement: {
+          case MDefinition::Opcode::LoadElement: {
             MOZ_ASSERT(access->toLoadElement()->elements() == def);
 
             // If we need hole checks, then the array cannot be escaped
             // as the array might refer to the prototype chain to look
             // for properties, thus it might do additional side-effects
             // which are not reflected by the alias set, is we are
             // bailing on holes.
             if (access->toLoadElement()->needsHoleCheck()) {
@@ -851,17 +851,17 @@ IsElementEscaped(MElements* def, uint32_
             if (index < 0 || arraySize <= uint32_t(index)) {
                 JitSpewDef(JitSpew_Escape,
                            "has a load element with an out-of-bound index\n", access);
                 return true;
             }
             break;
           }
 
-          case MDefinition::Op_StoreElement: {
+          case MDefinition::Opcode::StoreElement: {
             MOZ_ASSERT(access->toStoreElement()->elements() == def);
 
             // If we need hole checks, then the array cannot be escaped
             // as the array might refer to the prototype chain to look
             // for properties, thus it might do additional side-effects
             // which are not reflected by the alias set, is we are
             // bailing on holes.
             if (access->toStoreElement()->needsHoleCheck()) {
@@ -885,25 +885,25 @@ IsElementEscaped(MElements* def, uint32_
             // We are not yet encoding magic hole constants in resume points.
             if (access->toStoreElement()->value()->type() == MIRType::MagicHole) {
                 JitSpewDef(JitSpew_Escape, "has a store element with an magic-hole constant\n", access);
                 return true;
             }
             break;
           }
 
-          case MDefinition::Op_SetInitializedLength:
+          case MDefinition::Opcode::SetInitializedLength:
             MOZ_ASSERT(access->toSetInitializedLength()->elements() == def);
             break;
 
-          case MDefinition::Op_InitializedLength:
+          case MDefinition::Opcode::InitializedLength:
             MOZ_ASSERT(access->toInitializedLength()->elements() == def);
             break;
 
-          case MDefinition::Op_ArrayLength:
+          case MDefinition::Opcode::ArrayLength:
             MOZ_ASSERT(access->toArrayLength()->elements() == def);
             break;
 
           default:
             JitSpewDef(JitSpew_Escape, "is escaped by\n", access);
             return true;
         }
     }
@@ -953,30 +953,30 @@ IsArrayEscaped(MInstruction* ins)
                 JitSpew(JitSpew_Escape, "Observable array cannot be recovered");
                 return true;
             }
             continue;
         }
 
         MDefinition* def = consumer->toDefinition();
         switch (def->op()) {
-          case MDefinition::Op_Elements: {
+          case MDefinition::Opcode::Elements: {
             MElements *elem = def->toElements();
             MOZ_ASSERT(elem->object() == ins);
             if (IsElementEscaped(elem, length)) {
                 JitSpewDef(JitSpew_Escape, "is indirectly escaped by\n", elem);
                 return true;
             }
 
             break;
           }
 
           // This instruction is a no-op used to verify that scalar replacement
           // is working as expected in jit-test.
-          case MDefinition::Op_AssertRecoveredOnBailout:
+          case MDefinition::Opcode::AssertRecoveredOnBailout:
             break;
 
           default:
             JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
             return true;
         }
     }
 
--- a/js/src/jit/WasmBCE.cpp
+++ b/js/src/jit/WasmBCE.cpp
@@ -36,17 +36,17 @@ jit::EliminateBoundsChecks(MIRGenerator*
         return false;
 
     for (ReversePostorderIterator bIter(graph.rpoBegin()); bIter != graph.rpoEnd(); bIter++) {
         MBasicBlock* block = *bIter;
         for (MDefinitionIterator dIter(block); dIter;) {
             MDefinition* def = *dIter++;
 
             switch (def->op()) {
-              case MDefinition::Op_WasmBoundsCheck: {
+              case MDefinition::Opcode::WasmBoundsCheck: {
                 MWasmBoundsCheck* bc = def->toWasmBoundsCheck();
                 MDefinition* addr = bc->index();
 
                 // Eliminate constant-address bounds checks to addresses below
                 // the heap minimum.
                 //
                 // The payload of the MConstant will be Double if the constant
                 // result is above 2^31-1, but we don't care about that for BCE.
@@ -69,17 +69,17 @@ jit::EliminateBoundsChecks(MIRGenerator*
                             bc->setRedundant();
                     } else {
                         if (!lastSeen.add(ptr, addr->id(), def))
                             return false;
                     }
                 }
                 break;
               }
-              case MDefinition::Op_Phi: {
+              case MDefinition::Opcode::Phi: {
                 MPhi* phi = def->toPhi();
                 bool phiChecked = true;
 
                 MOZ_ASSERT(phi->numOperands() > 0);
 
                 // If all incoming values to a phi node are safe (i.e. have a
                 // check that dominates this block) then we can consider this
                 // phi node checked.
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -601,17 +601,17 @@ CodeGeneratorShared::encode(LSnapshot* s
     uint32_t lirId = 0;
     uint32_t mirOpcode = 0;
     uint32_t mirId = 0;
 
     if (LNode* ins = instruction()) {
         lirOpcode = ins->op();
         lirId = ins->id();
         if (ins->mirRaw()) {
-            mirOpcode = ins->mirRaw()->op();
+            mirOpcode = uint32_t(ins->mirRaw()->op());
             mirId = ins->mirRaw()->id();
             if (ins->mirRaw()->trackedPc())
                 pcOpcode = *ins->mirRaw()->trackedPc();
         }
     }
     snapshots_.trackSnapshot(pcOpcode, mirOpcode, mirId, lirOpcode, lirId);
 #endif