aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2012-03-01 15:33:23 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-09 09:52:26 +0100
commit6a7da3f592a0cd672ce076afd75eb810b5c17c4c (patch)
treea5b7ffa8852cbc1115f8658c20cc1258736b414e /src
parent76143252bab3bd41f97d9e8170f09ae35171ae71 (diff)
Keep high-level intermediate representation for IR::BINOPs.
That is, keep binary expressions in HIR, this will make constant folding more effective. Also, the register allocator for expression-trees used in the V4 compiler will do a better job. Change-Id: I2d5eea08ecd9c8d6f3aa21f1fd674a691ef9e1b0 Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp29
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp12
2 files changed, 17 insertions, 24 deletions
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index f8fe3b4b57..608368afc2 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -696,29 +696,20 @@ quint8 QV4CompilerPrivate::instructionOpcode(IR::Binop *e)
void QV4CompilerPrivate::visitBinop(IR::Binop *e)
{
+ if (e->type == IR::InvalidType) {
+ discard();
+ return;
+ }
+
int left = currentReg;
int right = currentReg + 1;
- if (e->left->asTemp() && e->type != IR::StringType) // Not sure if the e->type != String test is needed
- left = e->left->asTemp()->index;
- else
- traceExpression(e->left, left);
+ traceExpression(e->left, left);
+ traceExpression(e->right, right);
- if (IR::Temp *t = e->right->asTemp())
- right = t->index;
- else
- traceExpression(e->right, right);
-
- 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;
- }
+ // At this point it is possible that the type of the
+ // subexpressions is different. This can happen because
+ // we keep BINOP expressions in HIR.
switch (e->op) {
case IR::OpInvalid:
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index b382c262a8..36e88e5276 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -823,16 +823,18 @@ bool QV4IRBuilder::visit(AST::NotExpression *ast)
void QV4IRBuilder::binop(AST::BinaryExpression *ast, ExprResult left, ExprResult right)
{
if (IR::Type t = maxType(left.type(), right.type())) {
- implicitCvt(left, t);
- implicitCvt(right, t);
+ if (!left->asConst() && !right->asConst()) {
+ // the implicit conversions are needed only
+ // when compiling non-constant expressions.
+ implicitCvt(left, t);
+ implicitCvt(right, t);
+ }
if (_expr.hint == ExprResult::cx) {
_expr.format = ExprResult::cx;
_block->CJUMP(_block->BINOP(IR::binaryOperator(ast->op), left, right), _expr.iftrue, _expr.iffalse);
} else {
- IR::Expr *code = _block->BINOP(IR::binaryOperator(ast->op), left, right);
- _expr.code = _block->TEMP(code->type);
- _block->MOVE(_expr.code, code);
+ _expr.code = _block->BINOP(IR::binaryOperator(ast->op), left, right);
}
}
}