Enable constant propagation for all types
authorLars Knoll <lars.knoll@digia.com>
Fri, 14 Mar 2014 09:17:27 +0000 (10:17 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 19 Mar 2014 07:14:53 +0000 (08:14 +0100)
So far constant propagation was only enabled for
numbers and booleans. Enable it for all types now
and make sure the propagation does the right thing.

Change-Id: I202b0073f463d8a42e34931a736544207284b6dc
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/compiler/qv4jsir.cpp
src/qml/compiler/qv4ssa.cpp
src/qml/jit/qv4assembler.cpp

index d9d0742b6825405d1c9fc68ef8d2d8630ee479bd..a656f4dffe9caba12af220d24d6512968000a903 100644 (file)
@@ -745,7 +745,12 @@ Expr *BasicBlock::CONST(Type type, double value)
             type = SInt32Type;
         else
             type = DoubleType;
+    } else if (type == NullType) {
+        value = 0;
+    } else if (type == UndefinedType) {
+        value = qSNaN();
     }
+
     e->init(type, value);
     return e;
 }
index ca0bbb1bb36096c5da1af83630fd67d47c69b296..338041ad5ded488aa4ef43192c4a28dfaedee1e1 100644 (file)
@@ -2305,6 +2305,10 @@ void convertConst(Const *c, Type targetType)
     case BoolType:
         c->value = !(c->value == 0 || std::isnan(c->value));
         break;
+    case NullType:
+    case UndefinedType:
+        c->value = qSNaN();
+        c->type = targetType;
     default:
         Q_UNIMPLEMENTED();
         Q_ASSERT(!"Unimplemented!");
@@ -2991,6 +2995,11 @@ private:
             }
         }
 
+        if (e1->type == IR::NullType && e2->type == IR::NullType)
+            return true;
+        if (e1->type == IR::UndefinedType && e2->type == IR::UndefinedType)
+            return true;
+
         return false;
     }
 };
@@ -3116,18 +3125,20 @@ bool tryOptimizingComparison(Expr *&expr)
         expr = leftConst;
         return true;
     case OpStrictEqual:
-        if (!strictlyEqualTypes(leftConst->type, rightConst->type))
-            return false;
-        // intentional fall-through
+        leftConst->value = Runtime::compareStrictEqual(&l, &r);
+        leftConst->type = BoolType;
+        expr = leftConst;
+        return true;
     case OpEqual:
         leftConst->value = Runtime::compareEqual(&l, &r);
         leftConst->type = BoolType;
         expr = leftConst;
         return true;
     case OpStrictNotEqual:
-        if (!strictlyEqualTypes(leftConst->type, rightConst->type))
-            return false;
-        // intentional fall-through
+        leftConst->value = Runtime::compareStrictNotEqual(&l, &r);
+        leftConst->type = BoolType;
+        expr = leftConst;
+        return true;
     case OpNotEqual:
         leftConst->value = Runtime::compareNotEqual(&l, &r);
         leftConst->type = BoolType;
@@ -3214,13 +3225,9 @@ void optimizeSSA(IR::Function *function, DefUsesCalculator &defUses, DominatorTr
 
                 // constant propagation:
                 if (Const *sourceConst = m->source->asConst()) {
-                    if (sourceConst->type & NumberType || sourceConst->type == BoolType) {
-                        // TODO: when propagating other constants, e.g. undefined, the other
-                        // optimization passes have to be changed to cope with them.
-                        W += replaceUses(targetTemp, sourceConst);
-                        defUses.removeDef(*targetTemp);
-                        W.clear(s);
-                    }
+                    W += replaceUses(targetTemp, sourceConst);
+                    defUses.removeDef(*targetTemp);
+                    W.clear(s);
                     continue;
                 }
                 if (Member *member = m->source->asMember()) {
index 4e644c434db0b7ab19b5b9452ffdd5e8fa99e7b7..2393c9a8caa0ec24537720b8a5c52c410445a6ed 100644 (file)
@@ -338,8 +338,11 @@ Assembler::Jump Assembler::genTryDoubleConversion(IR::Expr *src, Assembler::FPRe
         convertUInt32ToDouble(toUInt32Register(src, Assembler::ScratchRegister),
                                    dest, Assembler::ReturnValueRegister);
         return Assembler::Jump();
+    case IR::NullType:
+    case IR::UndefinedType:
     case IR::BoolType:
         // TODO?
+    case IR::StringType:
         return jump();
     default:
         break;