diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-10-29 16:06:43 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-30 08:29:49 +0100 |
commit | 928a7d3e3edb278281641b6928ba046b123548ca (patch) | |
tree | ffa4f10322b224b71cd512f959b14db5c0c63ac0 | |
parent | 53a6d572e5ded9f559a7287e42a65328b4e8ba1b (diff) |
Optimize some unops and binops for moth
Optimize unops for ints/bools and add some
special binops where one side is constant.
Change-Id: I4f5639e36458560e5614371733abaafd94909ab1
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 38 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 62 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 24 |
3 files changed, 124 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 8dac616a2a..562f70bddd 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -94,9 +94,11 @@ QT_BEGIN_NAMESPACE F(Jump, jump) \ F(CJump, cjump) \ F(UNot, unot) \ + F(UNotBool, unotBool) \ F(UPlus, uplus) \ F(UMinus, uminus) \ F(UCompl, ucompl) \ + F(UComplInt, ucomplInt) \ F(Increment, increment) \ F(Decrement, decrement) \ F(Binop, binop) \ @@ -104,6 +106,9 @@ QT_BEGIN_NAMESPACE F(BitAnd, bitAnd) \ F(BitOr, bitOr) \ F(BitXor, bitXor) \ + F(BitAndConst, bitAndConst) \ + F(BitOrConst, bitOrConst) \ + F(BitXorConst, bitXorConst) \ F(Mul, mul) \ F(Sub, sub) \ F(BinopContext, binopContext) \ @@ -448,6 +453,11 @@ union Instr Param source; Param result; }; + struct instr_unotBool { + MOTH_INSTR_HEADER + Param source; + Param result; + }; struct instr_uplus { MOTH_INSTR_HEADER Param source; @@ -463,6 +473,11 @@ union Instr Param source; Param result; }; + struct instr_ucomplInt { + MOTH_INSTR_HEADER + Param source; + Param result; + }; struct instr_increment { MOTH_INSTR_HEADER Param source; @@ -504,6 +519,24 @@ union Instr Param rhs; Param result; }; + struct instr_bitAndConst { + MOTH_INSTR_HEADER + Param lhs; + int rhs; + Param result; + }; + struct instr_bitOrConst { + MOTH_INSTR_HEADER + Param lhs; + int rhs; + Param result; + }; + struct instr_bitXorConst { + MOTH_INSTR_HEADER + Param lhs; + int rhs; + Param result; + }; struct instr_mul { MOTH_INSTR_HEADER Param lhs; @@ -596,9 +629,11 @@ union Instr instr_jump jump; instr_cjump cjump; instr_unot unot; + instr_unotBool unotBool; instr_uplus uplus; instr_uminus uminus; instr_ucompl ucompl; + instr_ucomplInt ucomplInt; instr_increment increment; instr_decrement decrement; instr_binop binop; @@ -606,6 +641,9 @@ union Instr instr_bitAnd bitAnd; instr_bitOr bitOr; instr_bitXor bitXor; + instr_bitAndConst bitAndConst; + instr_bitOrConst bitOrConst; + instr_bitXorConst bitXorConst; instr_mul mul; instr_sub sub; instr_binopContext binopContext; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index cddfc0076b..11a22dd910 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -134,6 +134,22 @@ inline bool isNumberType(V4IR::Expr *e) } } +inline bool isIntegerType(V4IR::Expr *e) +{ + switch (e->type) { + case V4IR::SInt32Type: + case V4IR::UInt32Type: + return true; + default: + return false; + } +} + +inline bool isBoolType(V4IR::Expr *e) +{ + return (e->type == V4IR::BoolType); +} + } // anonymous namespace // TODO: extend to optimize out temp-to-temp moves, where the lifetime of one temp ends at that statement. @@ -546,6 +562,14 @@ void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR:: case V4IR::OpIfTrue: Q_ASSERT(!"unreachable"); break; case V4IR::OpNot: { + // ### enabling this fails in some cases, where apparently the value is not a bool at runtime + if (0 && isBoolType(sourceTemp)) { + Instruction::UNotBool unot; + unot.source = getParam(sourceTemp); + unot.result = getResultParam(targetTemp); + addInstruction(unot); + return; + } Instruction::UNot unot; unot.source = getParam(sourceTemp); unot.result = getResultParam(targetTemp); @@ -575,6 +599,14 @@ void InstructionSelection::unop(V4IR::AluOp oper, V4IR::Temp *sourceTemp, V4IR:: return; } case V4IR::OpCompl: { + // ### enabling this fails in some cases, where apparently the value is not a int at runtime + if (0 && isIntegerType(sourceTemp)) { + Instruction::UComplInt unot; + unot.source = getParam(sourceTemp); + unot.result = getResultParam(targetTemp); + addInstruction(unot); + return; + } Instruction::UCompl ucompl; ucompl.source = getParam(sourceTemp); ucompl.result = getResultParam(targetTemp); @@ -667,6 +699,16 @@ Param InstructionSelection::binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource return mul.result; } if (oper == V4IR::OpBitAnd) { + if (leftSource->asConst()) + qSwap(leftSource, rightSource); + if (V4IR::Const *c = rightSource->asConst()) { + Instruction::BitAndConst bitAnd; + bitAnd.lhs = getParam(leftSource); + bitAnd.rhs = convertToValue(c).Value::toInt32(); + bitAnd.result = getResultParam(target); + addInstruction(bitAnd); + return bitAnd.result; + } Instruction::BitAnd bitAnd; bitAnd.lhs = getParam(leftSource); bitAnd.rhs = getParam(rightSource); @@ -675,6 +717,16 @@ Param InstructionSelection::binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource return bitAnd.result; } if (oper == V4IR::OpBitOr) { + if (leftSource->asConst()) + qSwap(leftSource, rightSource); + if (V4IR::Const *c = rightSource->asConst()) { + Instruction::BitOrConst bitOr; + bitOr.lhs = getParam(leftSource); + bitOr.rhs = convertToValue(c).Value::toInt32(); + bitOr.result = getResultParam(target); + addInstruction(bitOr); + return bitOr.result; + } Instruction::BitOr bitOr; bitOr.lhs = getParam(leftSource); bitOr.rhs = getParam(rightSource); @@ -683,6 +735,16 @@ Param InstructionSelection::binopHelper(V4IR::AluOp oper, V4IR::Expr *leftSource return bitOr.result; } if (oper == V4IR::OpBitXor) { + if (leftSource->asConst()) + qSwap(leftSource, rightSource); + if (V4IR::Const *c = rightSource->asConst()) { + Instruction::BitXorConst bitXor; + bitXor.lhs = getParam(leftSource); + bitXor.rhs = convertToValue(c).Value::toInt32(); + bitXor.result = getResultParam(target); + addInstruction(bitXor); + return bitXor.result; + } Instruction::BitXor bitXor; bitXor.lhs = getParam(leftSource); bitXor.rhs = getParam(rightSource); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 0901bfbd52..d569e98325 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -476,6 +476,11 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code, STOREVALUE(instr.result, __qmljs_not(VALUEPTR(instr.source))); MOTH_END_INSTR(UNot) + MOTH_BEGIN_INSTR(UNotBool) + bool b = VALUE(instr.source).booleanValue(); + VALUE(instr.result) = QV4::Encode(!b); + MOTH_END_INSTR(UNotBool) + MOTH_BEGIN_INSTR(UPlus) STOREVALUE(instr.result, __qmljs_uplus(VALUEPTR(instr.source))); MOTH_END_INSTR(UPlus) @@ -488,6 +493,10 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code, STOREVALUE(instr.result, __qmljs_compl(VALUEPTR(instr.source))); MOTH_END_INSTR(UCompl) + MOTH_BEGIN_INSTR(UComplInt) + VALUE(instr.result) = QV4::Encode((int)~VALUE(instr.source).integerValue()); + MOTH_END_INSTR(UComplInt) + MOTH_BEGIN_INSTR(Increment) STOREVALUE(instr.result, __qmljs_increment(VALUEPTR(instr.source))); MOTH_END_INSTR(Increment) @@ -516,6 +525,21 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code, STOREVALUE(instr.result, __qmljs_bit_xor(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs))); MOTH_END_INSTR(BitXor) + MOTH_BEGIN_INSTR(BitAndConst) + int lhs = VALUEPTR(instr.lhs)->toInt32(); + STOREVALUE(instr.result, QV4::Encode((int)(lhs & instr.rhs))); + MOTH_END_INSTR(BitAnd) + + MOTH_BEGIN_INSTR(BitOrConst) + int lhs = VALUEPTR(instr.lhs)->toInt32(); + STOREVALUE(instr.result, QV4::Encode((int)(lhs | instr.rhs))); + MOTH_END_INSTR(BitOr) + + MOTH_BEGIN_INSTR(BitXorConst) + int lhs = VALUEPTR(instr.lhs)->toInt32(); + STOREVALUE(instr.result, QV4::Encode((int)(lhs ^ instr.rhs))); + MOTH_END_INSTR(BitXor) + MOTH_BEGIN_INSTR(Mul) STOREVALUE(instr.result, __qmljs_mul(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs))); MOTH_END_INSTR(Mul) |