aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2012-03-29 11:46:41 +0200
committerQt by Nokia <qt-info@nokia.com>2012-04-03 16:22:04 +0200
commit373d78837d1d5049c5b1c2790d6f4023e6ecf974 (patch)
tree0b4b78c1024d886ea0cebcdce59696c9edf90c7f
parent187fe50cf5c17a6ebf73d209866364a903ca2084 (diff)
Fix constant folding for simple binary expression
This change improves constant folding of numeric and string literals. Also, we go back generating quadruples instead of IR-tree-expressions. This is kind of needed to reduce register pressure in the V4 VM. That is, V4 has typed registers so before reusing a register we need to look at the type and eventually dispose its contents (e.g. when a QString or a QUrl is stored in the register). Unfortunately, we can't effort to have all these checks in the V4 instructions. So we change `binop' to generate literals (e.g. CONST or STRING) or a TEMP (aka a preassigned register that cannot be reused). For exmaple, the IR code generated for Rectangle { color: "b" + "l" + ("u" + "e") width: 10 + 20 + 30 } is ==================== line: 3 column: 10 L0x811ca10: t0 = string_to_color("blue"); return t0; ==================== line: 4 column: 10 L0x811ca50: return 60; Change-Id: I4d8482ddab9193d8469bda6461bfb2e5a3eeb197 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp24
-rw-r--r--src/qml/qml/v4/qv4ir.cpp6
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp9
3 files changed, 33 insertions, 6 deletions
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 9afbb7e16f..08cfed9383 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -740,12 +740,26 @@ void QV4CompilerPrivate::visitBinop(IR::Binop *e)
int left = currentReg;
int right = currentReg + 1;
- traceExpression(e->left, left);
- traceExpression(e->right, right);
+ if (e->left->asTemp() && e->type != IR::StringType)
+ left = e->left->asTemp()->index;
+ else
+ traceExpression(e->left, left);
+
+ if (IR::Temp *t = e->right->asTemp())
+ right = t->index;
+ else
+ traceExpression(e->right, right);
- // At this point it is possible that the type of the
- // subexpressions is different. This can happen because
- // we keep BINOP expressions in HIR.
+ if (e->left->type != e->right->type) {
+ if (qmlVerboseCompiler())
+ qWarning().nospace() << "invalid operands to binary operator " << IR::binaryOperator(e->op)
+ << "(`" << IR::binaryOperator(e->left->type)
+ << "' and `"
+ << IR::binaryOperator(e->right->type)
+ << "'";
+ discard();
+ return;
+ }
switch (e->op) {
case IR::OpInvalid:
diff --git a/src/qml/qml/v4/qv4ir.cpp b/src/qml/qml/v4/qv4ir.cpp
index 982742c781..8fc4719791 100644
--- a/src/qml/qml/v4/qv4ir.cpp
+++ b/src/qml/qml/v4/qv4ir.cpp
@@ -606,6 +606,12 @@ Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right)
break;
}
}
+ } else if (op == OpAdd) {
+ if (String *s1 = left->asString()) {
+ if (String *s2 = right->asString()) {
+ return STRING(function->newString(s1->value.toString() + s2->value));
+ }
+ }
}
}
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index b8210b863f..31ed9a5a6a 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -892,7 +892,14 @@ void QV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult
_expr.format = ExprResult::cx;
_block->CJUMP(_block->BINOP(IR::binaryOperator(ast->op), left, right), _expr.iftrue, _expr.iffalse);
} else {
- _expr.code = _block->BINOP(IR::binaryOperator(ast->op), left, right);
+ IR::Expr *e = _block->BINOP(IR::binaryOperator(ast->op), left, right);
+ if (e->asConst() != 0 || e->asString() != 0)
+ _expr.code = e;
+ else {
+ IR::Temp *t = _block->TEMP(e->type);
+ _block->MOVE(t, e);
+ _expr.code = t;
+ }
}
}