Bug 1029830 - IonMonkey: GVN: More folding for MTest and MTableSwitch. r=nbp
authorDan Gohman <sunfish@mozilla.com>
Wed, 17 Sep 2014 10:27:26 -0700
changeset 205745 ce0a75f9481b5c33867ddfa0b758685e2561913a
parent 205744 8f27a48a25d5a7acabf69867597f3dfe0f951cdd
child 205746 29ba45e163d874fb94f74002305a72cfc513eb4f
push id49264
push userdgohman@mozilla.com
push dateWed, 17 Sep 2014 17:27:46 +0000
treeherdermozilla-inbound@ce0a75f9481b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1029830
milestone35.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 1029830 - IonMonkey: GVN: More folding for MTest and MTableSwitch. r=nbp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -321,16 +321,28 @@ MTest::foldsTo(TempAllocator &alloc)
         if (opop->isNot())
             return MTest::New(alloc, opop->toNot()->input(), ifTrue(), ifFalse());
         return MTest::New(alloc, op->toNot()->input(), ifFalse(), ifTrue());
     }
 
     if (op->isConstant())
         return MGoto::New(alloc, op->toConstant()->valueToBoolean() ? ifTrue() : ifFalse());
 
+    switch (op->type()) {
+      case MIRType_Undefined:
+      case MIRType_Null:
+        return MGoto::New(alloc, ifFalse());
+      case MIRType_Object:
+        if (!operandMightEmulateUndefined())
+            return MGoto::New(alloc, ifTrue());
+        break;
+      default:
+        break;
+    }
+
     return this;
 }
 
 void
 MTest::filtersUndefinedOrNull(bool trueBranch, MDefinition **subject, bool *filtersUndefined,
                               bool *filtersNull)
 {
     MDefinition *ins = getOperand(0);
@@ -3545,16 +3557,30 @@ MBoundsCheck::foldsTo(TempAllocator &all
        if (idx + uint32_t(minimum()) < len && idx + uint32_t(maximum()) < len)
            return index();
     }
 
     return this;
 }
 
 MDefinition *
+MTableSwitch::foldsTo(TempAllocator &alloc)
+{
+    MDefinition *op = getOperand(0);
+
+    // If we only have one successor, convert to a plain goto to the only
+    // successor. TableSwitch indices are numeric; other types will always go to
+    // the only successor.
+    if (numSuccessors() == 1 || (op->type() != MIRType_Value && !IsNumberType(op->type())))
+        return MGoto::New(alloc, getDefault());
+
+    return this;
+}
+
+MDefinition *
 MArrayJoin::foldsTo(TempAllocator &alloc) {
     // :TODO: Enable this optimization after fixing Bug 977966 test cases.
     return this;
 
     MDefinition *arr = array();
 
     if (!arr->isStringSplit())
         return this;
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1880,16 +1880,18 @@ class MTableSwitch MOZ_FINAL
     void replaceOperand(size_t index, MDefinition *operand) MOZ_FINAL MOZ_OVERRIDE {
         JS_ASSERT(index == 0);
         operand_.replaceProducer(operand);
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
+
+    MDefinition *foldsTo(TempAllocator &alloc);
 };
 
 template <size_t Arity, size_t Successors>
 class MAryControlInstruction : public MControlInstruction
 {
     mozilla::Array<MUse, Arity> operands_;
     mozilla::Array<MBasicBlock *, Successors> successors_;