Bug 1739614: Remove MLoadElement::needsHoleCheck. r=jandem
authorAndré Bargull <andre.bargull@gmail.com>
Tue, 09 Nov 2021 10:16:46 +0000
changeset 598679 5e3fc46b24859b5cc4738dce61ec2df8682962b5
parent 598678 209297ab2c2fe9ac437cce77b626aaca3579f03f
child 598680 59dbf9d365e5e3fd78383630e897243bba14c6ba
push id152826
push userandre.bargull@gmail.com
push dateTue, 09 Nov 2021 10:23:46 +0000
treeherderautoland@5e3fc46b2485 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1739614
milestone96.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 1739614: Remove MLoadElement::needsHoleCheck. r=jandem `MLoadElement::needsHoleCheck` is never set to false. Differential Revision: https://phabricator.services.mozilla.com/D130465
js/src/jit/CodeGenerator.cpp
js/src/jit/IonAnalysis.cpp
js/src/jit/Lowering.cpp
js/src/jit/MIR.h
js/src/jit/WarpCacheIRTranspiler.cpp
js/src/jit/shared/LIR-shared.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -13127,21 +13127,19 @@ void CodeGenerator::visitLoadElementV(LL
     NativeObject::elementsSizeMustNotOverflow();
     int32_t offset = ToInt32(load->index()) * sizeof(Value);
     masm.loadValue(Address(elements, offset), out);
   } else {
     masm.loadValue(BaseObjectElementIndex(elements, ToRegister(load->index())),
                    out);
   }
 
-  if (load->mir()->needsHoleCheck()) {
-    Label testMagic;
-    masm.branchTestMagic(Assembler::Equal, out, &testMagic);
-    bailoutFrom(&testMagic, load->snapshot());
-  }
+  Label testMagic;
+  masm.branchTestMagic(Assembler::Equal, out, &testMagic);
+  bailoutFrom(&testMagic, load->snapshot());
 }
 
 void CodeGenerator::visitLoadElementHole(LLoadElementHole* lir) {
   Register elements = ToRegister(lir->elements());
   Register index = ToRegister(lir->index());
   Register initLength = ToRegister(lir->initLength());
   const ValueOperand out = ToOutValue(lir);
 
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3876,21 +3876,19 @@ bool jit::FoldLoadsWithUnbox(MIRGenerato
       // when moving the unbox before a loop.
       MUnbox* unbox = defUse->toUnbox();
       if (unbox->block() != *block) {
         continue;
       }
 
       MOZ_ASSERT(!IsMagicType(unbox->type()));
 
-      // If this is a LoadElement that needs a hole check, we only support
-      // folding it with a fallible unbox so that we can eliminate the hole
-      // check.
-      if (load->isLoadElement() && load->toLoadElement()->needsHoleCheck() &&
-          !unbox->fallible()) {
+      // If this is a LoadElement, we only support folding it with a fallible
+      // unbox so that we can eliminate the hole check.
+      if (load->isLoadElement() && !unbox->fallible()) {
         continue;
       }
 
       // Combine the load and unbox into a single MIR instruction.
       if (!graph.alloc().ensureBallast()) {
         return false;
       }
 
@@ -3908,17 +3906,17 @@ bool jit::FoldLoadsWithUnbox(MIRGenerato
         case MDefinition::Opcode::LoadDynamicSlot: {
           auto* loadIns = load->toLoadDynamicSlot();
           replacement = MLoadDynamicSlotAndUnbox::New(
               graph.alloc(), loadIns->slots(), loadIns->slot(), mode, type);
           break;
         }
         case MDefinition::Opcode::LoadElement: {
           auto* loadIns = load->toLoadElement();
-          MOZ_ASSERT_IF(loadIns->needsHoleCheck(), unbox->fallible());
+          MOZ_ASSERT(unbox->fallible());
           replacement = MLoadElementAndUnbox::New(
               graph.alloc(), loadIns->elements(), loadIns->index(), mode, type);
           break;
         }
         default:
           MOZ_CRASH("Unexpected instruction");
       }
 
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3464,19 +3464,17 @@ void LIRGenerator::visitGuardElementNotH
 
 void LIRGenerator::visitLoadElement(MLoadElement* ins) {
   MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
   MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
   MOZ_ASSERT(ins->type() == MIRType::Value);
 
   auto* lir = new (alloc()) LLoadElementV(useRegister(ins->elements()),
                                           useRegisterOrConstant(ins->index()));
-  if (ins->fallible()) {
-    assignSnapshot(lir, ins->bailoutKind());
-  }
+  assignSnapshot(lir, ins->bailoutKind());
   defineBox(lir, ins);
 }
 
 void LIRGenerator::visitLoadElementHole(MLoadElementHole* ins) {
   MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
   MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
   MOZ_ASSERT(ins->initLength()->type() == MIRType::Int32);
   MOZ_ASSERT(ins->type() == MIRType::Value);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -6446,53 +6446,38 @@ class MSpectreMaskIndex
     return congruentIfOperandsEqual(ins);
   }
   virtual AliasSet getAliasSet() const override { return AliasSet::None(); }
   void computeRange(TempAllocator& alloc) override;
 
   ALLOW_CLONE(MSpectreMaskIndex)
 };
 
-// Load a value from a dense array's element vector and does a hole check if the
-// array is not known to be packed.
+// Load a value from a dense array's element vector. Bails out if the element is
+// a hole.
 class MLoadElement : public MBinaryInstruction, public NoTypePolicy::Data {
-  bool needsHoleCheck_;
-
-  MLoadElement(MDefinition* elements, MDefinition* index, bool needsHoleCheck)
-      : MBinaryInstruction(classOpcode, elements, index),
-        needsHoleCheck_(needsHoleCheck) {
-    if (needsHoleCheck) {
-      // Uses may be optimized away based on this instruction's result
-      // type. This means it's invalid to DCE this instruction, as we
-      // have to invalidate when we read a hole.
-      setGuard();
-    }
+  MLoadElement(MDefinition* elements, MDefinition* index)
+      : MBinaryInstruction(classOpcode, elements, index) {
+    // Uses may be optimized away based on this instruction's result
+    // type. This means it's invalid to DCE this instruction, as we
+    // have to invalidate when we read a hole.
+    setGuard();
     setResultType(MIRType::Value);
     setMovable();
     MOZ_ASSERT(elements->type() == MIRType::Elements);
     MOZ_ASSERT(index->type() == MIRType::Int32);
   }
 
  public:
   INSTRUCTION_HEADER(LoadElement)
   TRIVIAL_NEW_WRAPPERS
   NAMED_OPERANDS((0, elements), (1, index))
 
-  bool needsHoleCheck() const { return needsHoleCheck_; }
-  bool fallible() const { return needsHoleCheck(); }
-
-  bool congruentTo(const MDefinition* ins) const override {
-    if (!ins->isLoadElement()) {
-      return false;
-    }
-    const MLoadElement* other = ins->toLoadElement();
-    if (needsHoleCheck() != other->needsHoleCheck()) {
-      return false;
-    }
-    return congruentIfOperandsEqual(other);
+  bool congruentTo(const MDefinition* ins) const override {
+    return congruentIfOperandsEqual(ins);
   }
   AliasType mightAlias(const MDefinition* store) const override;
   MDefinition* foldsTo(TempAllocator& alloc) override;
   AliasSet getAliasSet() const override {
     return AliasSet::Load(AliasSet::Element);
   }
 
   ALLOW_CLONE(MLoadElement)
--- a/js/src/jit/WarpCacheIRTranspiler.cpp
+++ b/js/src/jit/WarpCacheIRTranspiler.cpp
@@ -1730,18 +1730,17 @@ bool WarpCacheIRTranspiler::emitLoadDens
   auto* elements = MElements::New(alloc(), obj);
   add(elements);
 
   auto* length = MInitializedLength::New(alloc(), elements);
   add(length);
 
   index = addBoundsCheck(index, length);
 
-  bool needsHoleCheck = true;
-  auto* load = MLoadElement::New(alloc(), elements, index, needsHoleCheck);
+  auto* load = MLoadElement::New(alloc(), elements, index);
   add(load);
 
   pushResult(load);
   return true;
 }
 
 bool WarpCacheIRTranspiler::emitLoadDenseElementHoleResult(
     ObjOperandId objId, Int32OperandId indexId) {
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -1860,20 +1860,16 @@ class LLoadElementV : public LInstructio
   LIR_HEADER(LoadElementV)
 
   LLoadElementV(const LAllocation& elements, const LAllocation& index)
       : LInstructionHelper(classOpcode) {
     setOperand(0, elements);
     setOperand(1, index);
   }
 
-  const char* extraName() const {
-    return mir()->needsHoleCheck() ? "HoleCheck" : nullptr;
-  }
-
   const MLoadElement* mir() const { return mir_->toLoadElement(); }
   const LAllocation* elements() { return getOperand(0); }
   const LAllocation* index() { return getOperand(1); }
 };
 
 // Load a value from an array's elements vector, loading |undefined| if we hit a
 // hole. Bail out if we get a negative index.
 class LLoadElementHole : public LInstructionHelper<BOX_PIECES, 3, 0> {