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/qv4codegen.cpp | |
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/qv4codegen.cpp')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 40 |
1 files changed, 38 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; |