Bug 1328826 - IonMonkey: Speculate concatenation on baseline caches, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Mon, 09 Jan 2017 16:12:35 +0100
changeset 356575 28ca0dfe8d723df5c41a5d79114a5e42609e3a3c
parent 356574 e038230119a50d99d696e9a47faf8db32bbeb0af
child 356576 15748795cb4b4450cbb198b030af29b7f273d46e
push id10621
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 16:02:43 +0000
treeherdermozilla-aurora@dca7b42e6c67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1328826
milestone53.0a1
Bug 1328826 - IonMonkey: Speculate concatenation on baseline caches, r=jandem
js/src/jit/BaselineInspector.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/MIR.h
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -360,43 +360,56 @@ BaselineInspector::expectedCompareType(j
     return MCompare::Compare_Unknown;
 }
 
 static bool
 TryToSpecializeBinaryArithOp(ICStub** stubs,
                              uint32_t nstubs,
                              MIRType* result)
 {
-    DebugOnly<bool> sawInt32 = false;
+    bool sawInt32 = false;
     bool sawDouble = false;
     bool sawOther = false;
+    bool sawString = false;
 
     for (uint32_t i = 0; i < nstubs; i++) {
         switch (stubs[i]->kind()) {
           case ICStub::BinaryArith_Int32:
             sawInt32 = true;
             break;
           case ICStub::BinaryArith_BooleanWithInt32:
             sawInt32 = true;
             break;
           case ICStub::BinaryArith_Double:
             sawDouble = true;
             break;
           case ICStub::BinaryArith_DoubleWithInt32:
             sawDouble = true;
             break;
+          case ICStub::BinaryArith_StringConcat:
+            // Don't report true for BinaryArith_StringObjectConcat, since
+            // IonMonkey doesn't support MConcat with objects yet.
+            sawString = true;
+            break;
           default:
             sawOther = true;
             break;
         }
     }
 
     if (sawOther)
         return false;
 
+    if (sawString) {
+        if (sawDouble || sawInt32)
+            return false;
+        *result = MIRType::String;
+        return true;
+    }
+
     if (sawDouble) {
         *result = MIRType::Double;
         return true;
     }
 
     MOZ_ASSERT(sawInt32);
     *result = MIRType::Int32;
     return true;
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -3308,19 +3308,26 @@ IonBuilder::binaryArithTrySpecializedOnB
     trackOptimizationAttempt(TrackedStrategy::BinaryArith_SpecializedOnBaselineTypes);
 
     MIRType specialization = inspector->expectedBinaryArithSpecialization(pc);
     if (specialization == MIRType::None) {
         trackOptimizationOutcome(TrackedOutcome::SpeculationOnInputTypesFailed);
         return Ok();
     }
 
-    MDefinition::Opcode def_op = JSOpToMDefinition(op);
-    MBinaryArithInstruction* ins = MBinaryArithInstruction::New(alloc(), def_op, left, right);
-    ins->setSpecialization(specialization);
+    MInstruction* ins;
+    if (specialization == MIRType::String) {
+        MOZ_ASSERT(op == JSOP_ADD);
+        ins = MConcat::New(alloc(), left, right);
+    } else {
+        MDefinition::Opcode def_op = JSOpToMDefinition(op);
+        MBinaryArithInstruction* arith = MBinaryArithInstruction::New(alloc(), def_op, left, right);
+        arith->setSpecialization(specialization);
+        ins = arith;
+    }
 
     current->add(ins);
     current->push(ins);
 
     MOZ_ASSERT(!ins->isEffectful());
     MOZ_TRY(maybeInsertResume());
 
     trackOptimizationSuccess();
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -7207,19 +7207,16 @@ class MMod : public MBinaryArithInstruct
 
 class MConcat
   : public MBinaryInstruction,
     public MixPolicy<ConvertToStringPolicy<0>, ConvertToStringPolicy<1> >::Data
 {
     MConcat(MDefinition* left, MDefinition* right)
       : MBinaryInstruction(left, right)
     {
-        // At least one input should be definitely string
-        MOZ_ASSERT(left->type() == MIRType::String || right->type() == MIRType::String);
-
         setMovable();
         setResultType(MIRType::String);
     }
 
   public:
     INSTRUCTION_HEADER(Concat)
     TRIVIAL_NEW_WRAPPERS