diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-16 09:32:28 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-08-25 11:53:47 +0000 |
commit | 29e1531252ef435086a2b84e20a8e83304ca30bc (patch) | |
tree | 51bc6cf51b019f979ef93ce1425098d0ad373008 /src/qml/compiler | |
parent | 584dcb7773f2fe44ba53bd43f6eda7185249e9ab (diff) |
Add optimized JmpCmpEq/NeNull instructions
for comparisons with null or undefined.
Change-Id: I4a70d12ace501e4c4735b2ccfd6de19aeb9fef22
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 40 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 8 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 12 |
3 files changed, 58 insertions, 2 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index e3205d9d8d..379db2cd9c 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1037,16 +1037,52 @@ static QSOperator::Op invert(QSOperator::Op oper) } } +static QSOperator::Op swap(QSOperator::Op oper) +{ + switch (oper) { + case QSOperator::StrictEqual: return QSOperator::StrictEqual; + case QSOperator::StrictNotEqual: return QSOperator::StrictNotEqual; + case QSOperator::Equal: return QSOperator::Equal; + case QSOperator::NotEqual: return QSOperator::NotEqual; + case QSOperator::Gt: return QSOperator::Le; + case QSOperator::Ge: return QSOperator::Lt; + case QSOperator::Lt: return QSOperator::Ge; + case QSOperator::Le: return QSOperator::Gt; + default: Q_UNIMPLEMENTED(); return QSOperator::Invalid; + } +} + Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Reference &right) { - left = left.storeOnStack(); - right.loadInAccumulator(); + if (left.isConst()) { + oper = swap(oper); + qSwap(left, right); + } const BytecodeGenerator::Label *jumpTarget = _expr.iftrue(); if (_expr.trueBlockFollowsCondition()) { oper = invert(oper); jumpTarget = _expr.iffalse(); } + if (right.isConst()) { + if (right.constant == Encode::null() || right.constant == Encode::undefined()) { + if (oper == QSOperator::Equal) { + left.loadInAccumulator(); + Instruction::CmpJmpEqNull cjump; + bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget); + return Reference(); + } else if (oper == QSOperator::NotEqual) { + left.loadInAccumulator(); + Instruction::CmpJmpNeNull cjump; + bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget); + return Reference(); + } + } + } + + left = left.storeOnStack(); + right.loadInAccumulator(); + switch (oper) { case QSOperator::StrictEqual: { Instruction::JumpStrictEqual cjump; diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index 5f5c1d2d50..c1d99162f5 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -390,6 +390,14 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals) d << "acc " << absoluteInstructionOffset(start, instr); MOTH_END_INSTR(JumpNe) + MOTH_BEGIN_INSTR(CmpJmpEqNull) + d << absoluteInstructionOffset(start, instr); + MOTH_END_INSTR(CmpJmpEqNull) + + MOTH_BEGIN_INSTR(CmpJmpNeNull) + d << absoluteInstructionOffset(start, instr); + MOTH_END_INSTR(CmpJmpNeNull) + MOTH_BEGIN_INSTR(CmpJmpEq) d << instr.lhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr); MOTH_END_INSTR(CmpJmpEq) diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 2f181f806c..cb55e84442 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -140,6 +140,8 @@ QT_BEGIN_NAMESPACE F(Jump, jump) \ F(JumpEq, jumpEq) \ F(JumpNe, jumpNe) \ + F(CmpJmpEqNull, cmpJmpEqNull) \ + F(CmpJmpNeNull, cmpJmpNeNull) \ F(CmpJmpEq, cmpJmpEq) \ F(CmpJmpNe, cmpJmpNe) \ F(CmpJmpGt, cmpJmpGt) \ @@ -570,6 +572,14 @@ union Instr MOTH_INSTR_HEADER ptrdiff_t offset; }; + struct instr_cmpJmpEqNull { + MOTH_INSTR_HEADER + ptrdiff_t offset; + }; + struct instr_cmpJmpNeNull { + MOTH_INSTR_HEADER + ptrdiff_t offset; + }; struct instr_cmpJmpEq { MOTH_INSTR_HEADER StackSlot lhs; @@ -788,6 +798,8 @@ union Instr instr_jump jump; instr_jumpEq jumpEq; instr_jumpNe jumpNe; + instr_cmpJmpEqNull cmpJmpEqNull; + instr_cmpJmpNeNull cmpJmpNeNull; instr_cmpJmpEq cmpJmpEq; instr_cmpJmpNe cmpJmpNe; instr_cmpJmpGt cmpJmpGt; |