aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-16 09:32:28 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2017-08-25 11:53:47 +0000
commit29e1531252ef435086a2b84e20a8e83304ca30bc (patch)
tree51bc6cf51b019f979ef93ce1425098d0ad373008 /src/qml/compiler/qv4codegen.cpp
parent584dcb7773f2fe44ba53bd43f6eda7185249e9ab (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.cpp40
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;