diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2012-03-01 15:33:23 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-09 09:52:26 +0100 |
commit | 6a7da3f592a0cd672ce076afd75eb810b5c17c4c (patch) | |
tree | a5b7ffa8852cbc1115f8658c20cc1258736b414e /src | |
parent | 76143252bab3bd41f97d9e8170f09ae35171ae71 (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.cpp | 29 | ||||
-rw-r--r-- | src/qml/qml/v4/qv4irbuilder.cpp | 12 |
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); } } } |