Bug 1193112: IonMonkey - Let the float32 optimization work with Float32, r=bbouvier
authorHannes Verschore <hv1989@gmail.com>
Fri, 14 Aug 2015 11:46:28 +0200
changeset 290413 2db399cd414f8ca2e70b41d4c36d50fa0a9a8d87
parent 290379 0760af2a400f9bb1b86449d52bcf41926ab58288
child 290414 d791ba00bf065740fc504329a1075f5132cdc800
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier
bugs1193112
milestone43.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 1193112: IonMonkey - Let the float32 optimization work with Float32, r=bbouvier
js/src/jit-test/tests/ion/testFloat32.js
js/src/jit/MIR.cpp
js/src/jit/MIR.h
--- a/js/src/jit-test/tests/ion/testFloat32.js
+++ b/js/src/jit-test/tests/ion/testFloat32.js
@@ -240,16 +240,48 @@ test(acceptAbs);
 
 function refuseAbs() {
     var res = Math.abs(f32[0]);
     assertFloat32(res, false);
     f64[0] = res + 1;
 }
 test(refuseAbs);
 
+function acceptFilterTypeSet() {
+    var res = f32[0];
+    if (!res) {
+    } else {
+        f32[0] = res;
+        assertFloat32(res, true);
+    }
+}
+test(acceptFilterTypeSet);
+
+function acceptFilterTypeSet2() {
+    var res = f32[0];
+    if (!res) {
+    } else {
+        var res1 = Math.abs(res);
+        f32[0] = res1;
+        assertFloat32(res1, true);
+    }
+}
+test(acceptFilterTypeSet2);
+
+function refuseFilterTypeSet() {
+    var res = f32[0];
+    if (!res) {
+    } else {
+        var res1 = Math.abs(res);
+        f64[0] = res1 + 1;
+        assertFloat32(res1, false);
+    }
+}
+test(refuseFilterTypeSet);
+
 function refuseTrigo() {
     var res = Math.cos(f32[0]);
     f32[0] = res;
     assertFloat32(res, false);
 
     var res = Math.sin(f32[0]);
     f32[0] = res;
     assertFloat32(res, false);
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -51,17 +51,17 @@ template<size_t Op> static void
 ConvertDefinitionToDouble(TempAllocator& alloc, MDefinition* def, MInstruction* consumer)
 {
     MInstruction* replace = MToDouble::New(alloc, def);
     consumer->replaceOperand(Op, replace);
     consumer->block()->insertBefore(consumer, replace);
 }
 
 static bool
-CheckUsesAreFloat32Consumers(MInstruction* ins)
+CheckUsesAreFloat32Consumers(const MInstruction* ins)
 {
     bool allConsumerUses = true;
     for (MUseDefIterator use(ins); allConsumerUses && use; use++)
         allConsumerUses &= use.def()->canConsumeFloat32(use.use());
     return allConsumerUses;
 }
 
 void
@@ -2272,16 +2272,33 @@ MBinaryArithInstruction::foldsTo(TempAll
             return MTruncateToInt32::New(alloc, rhs);
         return rhs; // x op id => x
     }
 
     return this;
 }
 
 void
+MFilterTypeSet::trySpecializeFloat32(TempAllocator& alloc)
+{
+    MDefinition* in = input();
+    if (in->type() != MIRType_Float32)
+        return;
+
+    setResultType(MIRType_Float32);
+}
+
+bool
+MFilterTypeSet::canConsumeFloat32(MUse* operand) const
+{
+    MOZ_ASSERT(getUseFor(0) == operand);
+    return CheckUsesAreFloat32Consumers(this);
+}
+
+void
 MBinaryArithInstruction::trySpecializeFloat32(TempAllocator& alloc)
 {
     // Do not use Float32 if we can use int32.
     if (specialization_ == MIRType_Int32)
         return;
 
     MDefinition* left = lhs();
     MDefinition* right = rhs();
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -847,30 +847,30 @@ class MDefinition : public MNode
     }
 };
 
 // An MUseDefIterator walks over uses in a definition, skipping any use that is
 // not a definition. Items from the use list must not be deleted during
 // iteration.
 class MUseDefIterator
 {
-    MDefinition* def_;
+    const MDefinition* def_;
     MUseIterator current_;
 
     MUseIterator search(MUseIterator start) {
         MUseIterator i(start);
         for (; i != def_->usesEnd(); i++) {
             if (i->consumer()->isDefinition())
                 return i;
         }
         return def_->usesEnd();
     }
 
   public:
-    explicit MUseDefIterator(MDefinition* def)
+    explicit MUseDefIterator(const MDefinition* def)
       : def_(def),
         current_(search(def->usesBegin()))
     { }
 
     explicit operator bool() const {
         return current_ != def_->usesEnd();
     }
     MUseDefIterator operator ++() {
@@ -12275,16 +12275,21 @@ class MFilterTypeSet
     }
     AliasSet getAliasSet() const override {
         return AliasSet::None();
     }
     virtual bool neverHoist() const override {
         return resultTypeSet()->empty();
     }
     void computeRange(TempAllocator& alloc) override;
+
+    bool isFloat32Commutative() const override { return true; }
+    bool canProduceFloat32() const override { return input()->canProduceFloat32(); }
+    bool canConsumeFloat32(MUse* operand) const override;
+    void trySpecializeFloat32(TempAllocator& alloc) override;
 };
 
 // Given a value, guard that the value is in a particular TypeSet, then returns
 // that value.
 class MTypeBarrier
   : public MUnaryInstruction,
     public TypeBarrierPolicy::Data
 {