Bug 1019188 - Transform phi(int32,boolean) into phi(int32,int32) when it is only consumed by test instructions, r=sunfish.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 04 Jun 2014 15:54:32 -0600
changeset 206994 703903939a5e1d2e83cd0970c167d7d333a959e6
parent 206993 91ad28afdd77610e271e28eac36e572de6904bdc
child 206995 d4a005d1c687a3a79d7f8d9808433d825bbe7fc5
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1019188
milestone32.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 1019188 - Transform phi(int32,boolean) into phi(int32,int32) when it is only consumed by test instructions, r=sunfish.
js/src/jit/RangeAnalysis.cpp
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -2441,16 +2441,52 @@ MDefinition::TruncateKind
 MCompare::operandTruncateKind(size_t index) const
 {
     // If we're doing an int32 comparison on operands which were previously
     // floating-point, convert them!
     JS_ASSERT_IF(truncateOperands_, isInt32Comparison());
     return truncateOperands_ ? TruncateAfterBailouts : NoTruncate;
 }
 
+static void
+TruncateTest(TempAllocator &alloc, MTest *test)
+{
+    // If all possible inputs to the test are either int32 or boolean,
+    // convert those inputs to int32 so that an int32 test can be performed.
+
+    if (test->input()->type() != MIRType_Value)
+        return;
+
+    if (!test->input()->isPhi() || !test->input()->hasOneDefUse() || test->input()->isImplicitlyUsed())
+        return;
+
+    MPhi *phi = test->input()->toPhi();
+    for (size_t i = 0; i < phi->numOperands(); i++) {
+        MDefinition *def = phi->getOperand(i);
+        if (!def->isBox())
+            return;
+        MDefinition *inner = def->getOperand(0);
+        if (inner->type() != MIRType_Boolean && inner->type() != MIRType_Int32)
+            return;
+    }
+
+    for (size_t i = 0; i < phi->numOperands(); i++) {
+        MDefinition *inner = phi->getOperand(i)->getOperand(0);
+        if (inner->type() != MIRType_Int32) {
+            MBasicBlock *block = inner->block();
+            inner = MToInt32::New(alloc, inner);
+            block->insertBefore(block->lastIns(), inner->toInstruction());
+        }
+        JS_ASSERT(inner->type() == MIRType_Int32);
+        phi->replaceOperand(i, inner);
+    }
+
+    phi->setResultType(MIRType_Int32);
+}
+
 // Examine all the users of |candidate| and determine the most aggressive
 // truncate kind that satisfies all of them.
 static MDefinition::TruncateKind
 ComputeRequestedTruncateKind(MInstruction *candidate)
 {
     // If the value naturally produces an int32 value (before bailout checks)
     // that needs no conversion, we don't have to worry about resume points
     // seeing truncated values.
@@ -2580,18 +2616,21 @@ RangeAnalysis::truncate()
     // any automatic truncations.
     MOZ_ASSERT(!mir->compilingAsmJS());
 
     Vector<MInstruction *, 16, SystemAllocPolicy> worklist;
     Vector<MBinaryBitwiseInstruction *, 16, SystemAllocPolicy> bitops;
 
     for (PostorderIterator block(graph_.poBegin()); block != graph_.poEnd(); block++) {
         for (MInstructionReverseIterator iter(block->rbegin()); iter != block->rend(); iter++) {
-            if (iter->type() == MIRType_None)
+            if (iter->type() == MIRType_None) {
+                if (iter->isTest())
+                    TruncateTest(alloc(), iter->toTest());
                 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: