diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2016-05-03 12:49:59 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-06-08 11:48:45 +0000 |
commit | c3241f99cf80ff1e9bdd45f67516d5d22fe8821d (patch) | |
tree | 449fbf122dd4ec0afbe669076f528e83dd1e5bb7 | |
parent | 950994cab62816dfbcba3a1c9f8304ddd24bb726 (diff) | |
download | qtdeclarative-c3241f99cf80ff1e9bdd45f67516d5d22fe8821d.tar.gz |
V4: Change uses of StmtVisitor/ExprVisitor to use new style visitors.
Change-Id: I668c829bf04e0e16ed94db169507cc5290deec50
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 29 | ||||
-rw-r--r-- | src/qml/compiler/qqmltypecompiler_p.h | 81 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.h | 34 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_util_p.h | 50 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 316 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 125 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 877 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm.cpp | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 83 |
10 files changed, 787 insertions, 816 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index cd204573c3..b9a3f1419c 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -2736,7 +2736,7 @@ bool QQmlJavaScriptBindingExpressionSimplificationPass::simplifyBinding(QV4::IR: for (QV4::IR::BasicBlock *bb : function->basicBlocks()) { for (QV4::IR::Stmt *s : bb->statements()) { - s->accept(this); + visit(s); if (!_canSimplify) return false; } @@ -2906,7 +2906,7 @@ void QQmlIRFunctionCleanser::clean() foreach (QV4::IR::Function *function, module->functions) { for (QV4::IR::BasicBlock *block : function->basicBlocks()) { for (QV4::IR::Stmt *s : block->statements()) { - s->accept(this); + visit(s); } } } @@ -2917,9 +2917,30 @@ void QQmlIRFunctionCleanser::clean() } } -void QQmlIRFunctionCleanser::visitClosure(QV4::IR::Closure *closure) +void QQmlIRFunctionCleanser::visit(QV4::IR::Stmt *s) { - closure->value = newFunctionIndices.at(closure->value); + + switch (s->stmtKind) { + case QV4::IR::Stmt::PhiStmt: + // nothing to do + break; + default: + STMT_VISIT_ALL_KINDS(s); + break; + } +} + +void QQmlIRFunctionCleanser::visit(QV4::IR::Expr *e) +{ + switch (e->exprKind) { + case QV4::IR::Expr::ClosureExpr: { + auto closure = e->asClosure(); + closure->value = newFunctionIndices.at(closure->value); + } break; + default: + EXPR_VISIT_ALL_KINDS(e); + break; + } } QT_END_NAMESPACE diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index b55106ac7b..915626e183 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -358,7 +358,7 @@ private: const QQmlPropertyCacheVector &propertyCaches; }; -class QQmlJavaScriptBindingExpressionSimplificationPass : public QQmlCompilePass, public QV4::IR::StmtVisitor +class QQmlJavaScriptBindingExpressionSimplificationPass : public QQmlCompilePass { public: QQmlJavaScriptBindingExpressionSimplificationPass(QQmlTypeCompiler *typeCompiler); @@ -368,12 +368,30 @@ public: private: void reduceTranslationBindings(int objectIndex); - virtual void visitMove(QV4::IR::Move *move); - virtual void visitJump(QV4::IR::Jump *) {} - virtual void visitCJump(QV4::IR::CJump *) { discard(); } - virtual void visitExp(QV4::IR::Exp *) { discard(); } - virtual void visitPhi(QV4::IR::Phi *) {} - virtual void visitRet(QV4::IR::Ret *ret); + void visit(QV4::IR::Stmt *s) + { + switch (s->stmtKind) { + case QV4::IR::Stmt::MoveStmt: + visitMove(s->asMove()); + break; + case QV4::IR::Stmt::RetStmt: + visitRet(s->asRet()); + break; + case QV4::IR::Stmt::CJumpStmt: + discard(); + break; + case QV4::IR::Stmt::ExpStmt: + discard(); + break; + case QV4::IR::Stmt::JumpStmt: + break; + case QV4::IR::Stmt::PhiStmt: + break; + } + } + + void visitMove(QV4::IR::Move *move); + void visitRet(QV4::IR::Ret *ret); void visitFunctionCall(const QString *name, QV4::IR::ExprList *args, QV4::IR::Temp *target); @@ -397,8 +415,7 @@ private: QVector<int> irFunctionsToRemove; }; -class QQmlIRFunctionCleanser : public QQmlCompilePass, public QV4::IR::StmtVisitor, - public QV4::IR::ExprVisitor +class QQmlIRFunctionCleanser : public QQmlCompilePass { public: QQmlIRFunctionCleanser(QQmlTypeCompiler *typeCompiler, const QVector<int> &functionsToRemove); @@ -406,51 +423,13 @@ public: void clean(); private: - virtual void visitClosure(QV4::IR::Closure *closure); - - virtual void visitTemp(QV4::IR::Temp *) {} - virtual void visitArgLocal(QV4::IR::ArgLocal *) {} - virtual void visitMove(QV4::IR::Move *s) { - s->source->accept(this); - s->target->accept(this); - } - - virtual void visitConvert(QV4::IR::Convert *e) { e->expr->accept(this); } - virtual void visitPhi(QV4::IR::Phi *) { } - - virtual void visitExp(QV4::IR::Exp *s) { s->expr->accept(this); } - - virtual void visitJump(QV4::IR::Jump *) {} - virtual void visitCJump(QV4::IR::CJump *s) { s->cond->accept(this); } - virtual void visitRet(QV4::IR::Ret *s) { s->expr->accept(this); } - - virtual void visitConst(QV4::IR::Const *) {} - virtual void visitString(QV4::IR::String *) {} - virtual void visitRegExp(QV4::IR::RegExp *) {} - virtual void visitName(QV4::IR::Name *) {} - virtual void visitUnop(QV4::IR::Unop *e) { e->expr->accept(this); } - virtual void visitBinop(QV4::IR::Binop *e) { e->left->accept(this); e->right->accept(this); } - virtual void visitCall(QV4::IR::Call *e) { - e->base->accept(this); - for (QV4::IR::ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitNew(QV4::IR::New *e) { - e->base->accept(this); - for (QV4::IR::ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); + visit(s->source); + visit(s->target); } - virtual void visitSubscript(QV4::IR::Subscript *e) { - e->base->accept(this); - e->index->accept(this); - } - - virtual void visitMember(QV4::IR::Member *e) { - e->base->accept(this); - } + void visit(QV4::IR::Stmt *s); + void visit(QV4::IR::Expr *e); private: QV4::IR::Module *module; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index b452c4b3d9..967dca13a1 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -252,7 +252,7 @@ protected: _unhandled.removeLast(); } - s->accept(this); + visit(s); } if (IR::Jump *jump = s->asJump()) { @@ -275,7 +275,7 @@ protected: moves.order(); QList<IR::Move *> newMoves = moves.insertMoves(_currentBasicBlock, _function, true); foreach (IR::Move *move, newMoves) - move->accept(this); + visit(move); } } @@ -425,7 +425,7 @@ void InstructionSelection::run(int functionIndex) } } - s->accept(this); + visit(s); } } diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index 2ee776adf4..61fd11c435 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -111,17 +111,34 @@ public: }; namespace IR { -class Q_QML_PRIVATE_EXPORT IRDecoder: protected IR::StmtVisitor +class Q_QML_PRIVATE_EXPORT IRDecoder { public: IRDecoder() : _function(0) {} virtual ~IRDecoder() = 0; - virtual void visitPhi(IR::Phi *) {} - -public: // visitor methods for StmtVisitor: - virtual void visitMove(IR::Move *s); - virtual void visitExp(IR::Exp *s); + void visit(Stmt *s) + { + if (auto e = s->asExp()) { + visitExp(e); + } else if (auto m = s->asMove()) { + visitMove(m); + } else if (auto j = s->asJump()) { + visitJump(j); + } else if (auto c = s->asCJump()) { + visitCJump(c); + } else if (auto r = s->asRet()) { + visitRet(r); + } else if (auto p = s->asPhi()) { + visitPhi(p); + } else { + Q_UNREACHABLE(); + } + } + +private: // visitor methods for StmtVisitor: + void visitMove(IR::Move *s); + void visitExp(IR::Exp *s); public: // to implement by subclasses: virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) = 0; @@ -179,6 +196,11 @@ public: // to implement by subclasses: virtual void binop(IR::AluOp oper, IR::Expr *leftSource, IR::Expr *rightSource, IR::Expr *target) = 0; protected: + virtual void visitJump(IR::Jump *) = 0; + virtual void visitCJump(IR::CJump *) = 0; + virtual void visitRet(IR::Ret *) = 0; + virtual void visitPhi(IR::Phi *) {} + virtual void callBuiltin(IR::Call *c, IR::Expr *result); IR::Function *_function; // subclass needs to set diff --git a/src/qml/compiler/qv4isel_util_p.h b/src/qml/compiler/qv4isel_util_p.h index 674fc01623..1755193d32 100644 --- a/src/qml/compiler/qv4isel_util_p.h +++ b/src/qml/compiler/qv4isel_util_p.h @@ -104,7 +104,7 @@ inline Primitive convertToValue(IR::Const *c) return Primitive::undefinedValue(); } -class ConvertTemps: protected IR::StmtVisitor, protected IR::ExprVisitor +class ConvertTemps { void renumber(IR::Temp *t) { @@ -132,7 +132,7 @@ protected: virtual void process(IR::Stmt *s) { - s->accept(this); + visit(s); } public: @@ -157,34 +157,28 @@ public: } protected: - virtual void visitConst(IR::Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(IR::Name *) {} - virtual void visitTemp(IR::Temp *e) { renumber(e); } - virtual void visitArgLocal(IR::ArgLocal *) {} - virtual void visitClosure(IR::Closure *) {} - virtual void visitConvert(IR::Convert *e) { e->expr->accept(this); } - virtual void visitUnop(IR::Unop *e) { e->expr->accept(this); } - virtual void visitBinop(IR::Binop *e) { e->left->accept(this); e->right->accept(this); } - virtual void visitCall(IR::Call *e) { - e->base->accept(this); - for (IR::ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); + void visit(IR::Stmt *s) { + switch (s->stmtKind) { + case IR::Stmt::PhiStmt: + visitPhi(s->asPhi()); + break; + default: + STMT_VISIT_ALL_KINDS(s); + break; + } } - virtual void visitNew(IR::New *e) { - e->base->accept(this); - for (IR::ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); + + virtual void visitPhi(IR::Phi *) + { Q_UNREACHABLE(); } + +private: + void visit(IR::Expr *e) { + if (auto temp = e->asTemp()) { + renumber(temp); + } else { + EXPR_VISIT_ALL_KINDS(e); + } } - virtual void visitSubscript(IR::Subscript *e) { e->base->accept(this); e->index->accept(this); } - virtual void visitMember(IR::Member *e) { e->base->accept(this); } - virtual void visitExp(IR::Exp *s) { s->expr->accept(this); } - virtual void visitMove(IR::Move *s) { s->target->accept(this); s->source->accept(this); } - virtual void visitJump(IR::Jump *) {} - virtual void visitCJump(IR::CJump *s) { s->cond->accept(this); } - virtual void visitRet(IR::Ret *s) { s->expr->accept(this); } - virtual void visitPhi(IR::Phi *) { Q_UNREACHABLE(); } }; } // namespace QV4 diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 370dfd0fae..b994d2f707 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -157,12 +157,13 @@ AluOp binaryOperator(int op) } } -struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor +class RemoveSharedExpressions { CloneExpr clone; std::vector<Expr *> subexpressions; // contains all the non-cloned subexpressions in the given function. sorted using std::lower_bound. Expr *uniqueExpr; +public: RemoveSharedExpressions(): uniqueExpr(0) {} void operator()(IR::Function *function) @@ -176,11 +177,12 @@ struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor clone.setBasicBlock(block); for (Stmt *s : block->statements()) { - s->accept(this); + visit(s); } } } +private: template <typename Expr_> Expr_ *cleanup(Expr_ *expr) { @@ -189,7 +191,7 @@ struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor subexpressions.insert(it, expr); IR::Expr *e = expr; qSwap(uniqueExpr, e); - expr->accept(this); + visit(expr); qSwap(uniqueExpr, e); return static_cast<Expr_ *>(e); } @@ -199,83 +201,45 @@ struct RemoveSharedExpressions: IR::StmtVisitor, IR::ExprVisitor return clone(expr); } - // statements - virtual void visitExp(Exp *s) + void visit(Stmt *s) { - s->expr = cleanup(s->expr); - } - - virtual void visitMove(Move *s) - { - s->target = cleanup(s->target); - s->source = cleanup(s->source); - } - - virtual void visitJump(Jump *) - { - // nothing to do for Jump statements - } - - virtual void visitCJump(CJump *s) - { - s->cond = cleanup(s->cond); - } - - virtual void visitRet(Ret *s) - { - s->expr = cleanup(s->expr); - } - - virtual void visitPhi(IR::Phi *) { Q_UNIMPLEMENTED(); } - - // expressions - virtual void visitConst(Const *) {} - virtual void visitString(String *) {} - virtual void visitRegExp(RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitTemp(Temp *) {} - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - - virtual void visitConvert(Convert *e) - { - e->expr = cleanup(e->expr); - } - - virtual void visitUnop(Unop *e) - { - e->expr = cleanup(e->expr); - } - - virtual void visitBinop(Binop *e) - { - e->left = cleanup(e->left); - e->right = cleanup(e->right); - } - - virtual void visitCall(Call *e) - { - e->base = cleanup(e->base); - for (IR::ExprList *it = e->args; it; it = it->next) - it->expr = cleanup(it->expr); - } - - virtual void visitNew(New *e) - { - e->base = cleanup(e->base); - for (IR::ExprList *it = e->args; it; it = it->next) - it->expr = cleanup(it->expr); - } - - virtual void visitSubscript(Subscript *e) - { - e->base = cleanup(e->base); - e->index = cleanup(e->index); + if (auto e = s->asExp()) { + e->expr = cleanup(e->expr); + } else if (auto m = s->asMove()) { + m->target = cleanup(m->target); + m->source = cleanup(m->source); + } else if (auto c = s->asCJump()) { + c->cond = cleanup(c->cond); + } else if (auto r = s->asRet()) { + r->expr = cleanup(r->expr); + } } - virtual void visitMember(Member *e) + void visit(Expr *e) { - e->base = cleanup(e->base); + if (auto c = e->asConvert()) { + c->expr = cleanup(c->expr); + } else if (auto u = e->asUnop()) { + u->expr = cleanup(u->expr); + } else if (auto b = e->asBinop()) { + b->left = cleanup(b->left); + b->right = cleanup(b->right); + } else if (auto c = e->asCall()) { + c->base = cleanup(c->base); + for (IR::ExprList *it = c->args; it; it = it->next) { + it->expr = cleanup(it->expr); + } + } else if (auto n = e->asNew()) { + n->base = cleanup(n->base); + for (IR::ExprList *it = n->args; it; it = it->next) { + it->expr = cleanup(it->expr); + } + } else if (auto s = e->asSubscript()) { + s->base = cleanup(s->base); + s->index = cleanup(s->index); + } else if (auto m = e->asMember()) { + m->base = cleanup(m->base); + } } }; @@ -548,75 +512,39 @@ ExprList *CloneExpr::clone(ExprList *list) return clonedList; } -void CloneExpr::visitConst(Const *e) -{ - cloned = cloneConst(e, block->function); -} - -void CloneExpr::visitString(String *e) -{ - cloned = block->STRING(e->value); -} - -void CloneExpr::visitRegExp(RegExp *e) -{ - cloned = block->REGEXP(e->value, e->flags); -} - -void CloneExpr::visitName(Name *e) -{ - cloned = cloneName(e, block->function); -} - -void CloneExpr::visitTemp(Temp *e) -{ - cloned = cloneTemp(e, block->function); -} - -void CloneExpr::visitArgLocal(ArgLocal *e) -{ - cloned = cloneArgLocal(e, block->function); -} - -void CloneExpr::visitClosure(Closure *e) -{ - cloned = block->CLOSURE(e->value); -} - -void CloneExpr::visitConvert(Convert *e) -{ - cloned = block->CONVERT(clone(e->expr), e->type); -} - -void CloneExpr::visitUnop(Unop *e) -{ - cloned = block->UNOP(e->op, clone(e->expr)); -} - -void CloneExpr::visitBinop(Binop *e) -{ - cloned = block->BINOP(e->op, clone(e->left), clone(e->right)); -} - -void CloneExpr::visitCall(Call *e) -{ - cloned = block->CALL(clone(e->base), clone(e->args)); -} - -void CloneExpr::visitNew(New *e) -{ - cloned = block->NEW(clone(e->base), clone(e->args)); -} - -void CloneExpr::visitSubscript(Subscript *e) -{ - cloned = block->SUBSCRIPT(clone(e->base), clone(e->index)); -} - -void CloneExpr::visitMember(Member *e) -{ - Expr *clonedBase = clone(e->base); - cloned = block->MEMBER(clonedBase, e->name, e->property, e->kind, e->idIndex); +void CloneExpr::visit(Expr *e) +{ + if (auto c = e->asConst()) { + cloned = cloneConst(c, block->function); + } else if (auto s = e->asString()) { + cloned = block->STRING(s->value); + } else if (auto r = e->asRegExp()) { + cloned = block->REGEXP(r->value, r->flags); + } else if (auto n = e->asName()) { + cloned = cloneName(n, block->function); + } else if (auto t = e->asTemp()) { + cloned = cloneTemp(t, block->function); + } else if (auto a = e->asArgLocal()) { + cloned = cloneArgLocal(a, block->function); + } else if (auto c = e->asClosure()) { + cloned = block->CLOSURE(c->value); + } else if (auto c = e->asConvert()) { + cloned = block->CONVERT(clone(c->expr), c->type); + } else if (auto u = e->asUnop()) { + cloned = block->UNOP(u->op, clone(u->expr)); + } else if (auto b = e->asBinop()) { + cloned = block->BINOP(b->op, clone(b->left), clone(b->right)); + } else if (auto c = e->asCall()) { + cloned = block->CALL(clone(c->base), clone(c->args)); + } else if (auto n = e->asNew()) { + cloned = block->NEW(clone(n->base), clone(n->args)); + } else if (auto s = e->asSubscript()) { + cloned = block->SUBSCRIPT(clone(s->base), clone(s->index)); + } else if (auto m = e->asMember()) { + cloned = block->MEMBER(clone(m->base), m->name, m->property, m->kind, m->idIndex); + } else { + Q_UNREACHABLE(); + } } IRPrinter::IRPrinter(QTextStream *out) @@ -632,17 +560,17 @@ IRPrinter::~IRPrinter() void IRPrinter::print(Stmt *s) { - s->accept(this); + visit(s); } void IRPrinter::print(const Expr &e) { - const_cast<Expr *>(&e)->accept(this); + visit(const_cast<Expr *>(&e)); } void IRPrinter::print(Expr *e) { - e->accept(this); + visit(e); } void IRPrinter::print(Function *f) @@ -696,7 +624,7 @@ void IRPrinter::print(BasicBlock *bb) QTextStream *prevOut = &os; std::swap(out, prevOut); addStmtNr(s); - s->accept(this); + visit(s); if (s->location.startLine) { out->flush(); for (int i = 58 - str.length(); i > 0; --i) @@ -713,10 +641,29 @@ void IRPrinter::print(BasicBlock *bb) std::swap(currentBB, bb); } +void IRPrinter::visit(Stmt *s) +{ + if (auto e = s->asExp()) { + visitExp(e); + } else if (auto m = s->asMove()) { + visitMove(m); + } else if (auto j = s->asJump()) { + visitJump(j); + } else if (auto c = s->asCJump()) { + visitCJump(c); + } else if (auto r = s->asRet()) { + visitRet(r); + } else if (auto p = s->asPhi()) { + visitPhi(p); + } else { + Q_UNREACHABLE(); + } +} + void IRPrinter::visitExp(Exp *s) { *out << "void "; - s->expr->accept(this); + visit(s->expr); } void IRPrinter::visitMove(Move *s) @@ -725,13 +672,13 @@ void IRPrinter::visitMove(Move *s) if (!s->swap && targetTemp->type != UnknownType) *out << typeName(targetTemp->type) << ' '; - s->target->accept(this); + visit(s->target); *out << ' '; if (s->swap) *out << "<=> "; else *out << "= "; - s->source->accept(this); + visit(s->source); } void IRPrinter::visitJump(Jump *s) @@ -742,7 +689,7 @@ void IRPrinter::visitJump(Jump *s) void IRPrinter::visitCJump(CJump *s) { *out << "if "; - s->cond->accept(this); + visit(s->cond); *out << " goto L" << s->iftrue->index() << " else goto L" << s->iffalse->index(); } @@ -752,7 +699,7 @@ void IRPrinter::visitRet(Ret *s) *out << "return"; if (s->expr) { *out << ' '; - s->expr->accept(this); + visit(s->expr); } } @@ -761,7 +708,7 @@ void IRPrinter::visitPhi(Phi *s) if (s->targetTemp->type != UnknownType) *out << typeName(s->targetTemp->type) << ' '; - s->targetTemp->accept(this); + visit(s->targetTemp); *out << " = phi "; for (int i = 0, ei = s->incoming.size(); i < ei; ++i) { if (i > 0) @@ -769,7 +716,42 @@ void IRPrinter::visitPhi(Phi *s) if (currentBB) *out << 'L' << currentBB->in.at(i)->index() << ": "; if (s->incoming[i]) - s->incoming[i]->accept(this); + visit(s->incoming[i]); + } +} + +void IRPrinter::visit(Expr *e) +{ + if (auto c = e->asConst()) { + visitConst(c); + } else if (auto s = e->asString()) { + visitString(s); + } else if (auto r = e->asRegExp()) { + visitRegExp(r); + } else if (auto n = e->asName()) { + visitName(n); + } else if (auto t = e->asTemp()) { + visitTemp(t); + } else if (auto a = e->asArgLocal()) { + visitArgLocal(a); + } else if (auto c = e->asClosure()) { + visitClosure(c); + } else if (auto c = e->asConvert()) { + visitConvert(c); + } else if (auto u = e->asUnop()) { + visitUnop(u); + } else if (auto b = e->asBinop()) { + visitBinop(b); + } else if (auto c = e->asCall()) { + visitCall(c); + } else if (auto n = e->asNew()) { + visitNew(n); + } else if (auto s = e->asSubscript()) { + visitSubscript(s); + } else if (auto m = e->asMember()) { + visitMember(m); + } else { + Q_UNREACHABLE(); } } @@ -867,32 +849,32 @@ void IRPrinter::visitClosure(Closure *e) void IRPrinter::visitConvert(Convert *e) { *out << "convert " << typeName(e->expr->type) << " to " << typeName(e->type) << ' '; - e->expr->accept(this); + visit(e->expr); } void IRPrinter::visitUnop(Unop *e) { *out << opname(e->op) << ' '; - e->expr->accept(this); + visit(e->expr); } void IRPrinter::visitBinop(Binop *e) { *out << opname(e->op) << ' '; - e->left->accept(this); + visit(e->left); *out << ", "; - e->right->accept(this); + visit(e->right); } void IRPrinter::visitCall(Call *e) { *out << "call "; - e->base->accept(this); + visit(e->base); *out << '('; for (ExprList *it = e->args; it; it = it->next) { if (it != e->args) *out << ", "; - it->expr->accept(this); + visit(it->expr); } *out << ')'; } @@ -900,21 +882,21 @@ void IRPrinter::visitCall(Call *e) void IRPrinter::visitNew(New *e) { *out << "new "; - e->base->accept(this); + visit(e->base); *out << '('; for (ExprList *it = e->args; it; it = it->next) { if (it != e->args) *out << ", "; - it->expr->accept(this); + visit(it->expr); } *out << ')'; } void IRPrinter::visitSubscript(Subscript *e) { - e->base->accept(this); + visit(e->base); *out << '['; - e->index->accept(this); + visit(e->index); *out << ']'; } @@ -924,7 +906,7 @@ void IRPrinter::visitMember(Member *e) && e->attachedPropertiesId != 0 && !e->base->asTemp()) *out << "[[attached property from " << e->attachedPropertiesId << "]]"; else - e->base->accept(this); + visit(e->base); *out << '.' << *e->name; #ifndef V4_BOOTSTRAP if (e->property) { diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 8ba641ab6a..0254ae224d 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -217,34 +217,6 @@ inline bool strictlyEqualTypes(Type t1, Type t2) QString typeName(Type t); -struct ExprVisitor { - virtual ~ExprVisitor() {} - virtual void visitConst(Const *) = 0; - virtual void visitString(String *) = 0; - virtual void visitRegExp(RegExp *) = 0; - virtual void visitName(Name *) = 0; - virtual void visitTemp(Temp *) = 0; - virtual void visitArgLocal(ArgLocal *) = 0; - virtual void visitClosure(Closure *) = 0; - virtual void visitConvert(Convert *) = 0; - virtual void visitUnop(Unop *) = 0; - virtual void visitBinop(Binop *) = 0; - virtual void visitCall(Call *) = 0; - virtual void visitNew(New *) = 0; - virtual void visitSubscript(Subscript *) = 0; - virtual void visitMember(Member *) = 0; -}; - -struct StmtVisitor { - virtual ~StmtVisitor() {} - virtual void visitExp(Exp *) = 0; - virtual void visitMove(Move *) = 0; - virtual void visitJump(Jump *) = 0; - virtual void visitCJump(CJump *) = 0; - virtual void visitRet(Ret *) = 0; - virtual void visitPhi(Phi *) = 0; -}; - struct MemberExpressionResolver; struct DiscoveredType { @@ -341,8 +313,6 @@ struct Q_AUTOTEST_EXPORT Expr { } Expr(ExprKind exprKind): type(UnknownType), exprKind(exprKind) {} - virtual ~Expr() {} - virtual void accept(ExprVisitor *) = 0; bool isLValue() const; Const *asConst() { return as<Const>(); } @@ -437,8 +407,6 @@ struct Const: Expr { this->value = value; } - virtual void accept(ExprVisitor *v) { v->visitConst(this); } - static bool classof(const Expr *c) { return c->exprKind == ConstExpr; } }; @@ -452,8 +420,6 @@ struct String: Expr { this->value = value; } - virtual void accept(ExprVisitor *v) { v->visitString(this); } - static bool classof(const Expr *c) { return c->exprKind == StringExpr; } }; @@ -476,8 +442,6 @@ struct RegExp: Expr { this->flags = flags; } - virtual void accept(ExprVisitor *v) { v->visitRegExp(this); } - static bool classof(const Expr *c) { return c->exprKind == RegExpExpr; } }; @@ -517,8 +481,6 @@ struct Name: Expr { void init(const QString *id, quint32 line, quint32 column); void init(Builtin builtin, quint32 line, quint32 column); - virtual void accept(ExprVisitor *v) { v->visitName(this); } - static bool classof(const Expr *c) { return c->exprKind == NameExpr; } }; @@ -553,8 +515,6 @@ struct Q_AUTOTEST_EXPORT Temp: Expr { } bool isInvalid() const { return kind == Invalid; } - virtual void accept(ExprVisitor *v) { v->visitTemp(this); } - virtual Temp *asTemp() { return this; } static bool classof(const Expr *c) { return c->exprKind == TempExpr; } }; @@ -597,8 +557,6 @@ struct Q_AUTOTEST_EXPORT ArgLocal: Expr { ArgLocal(): Expr(ArgLocalExpr) {} - virtual void accept(ExprVisitor *v) { v->visitArgLocal(this); } - bool operator==(const ArgLocal &other) const { return index == other.index && scope == other.scope && kind == other.kind; } @@ -617,8 +575,6 @@ struct Closure: Expr { this->functionName = functionName; } - virtual void accept(ExprVisitor *v) { v->visitClosure(this); } - static bool classof(const Expr *c) { return c->exprKind == ClosureExpr; } }; @@ -633,8 +589,6 @@ struct Convert: Expr { this->type = type; } - virtual void accept(ExprVisitor *v) { v->visitConvert(this); } - static bool classof(const Expr *c) { return c->exprKind == ConvertExpr; } }; @@ -650,8 +604,6 @@ struct Unop: Expr { this->expr = expr; } - virtual void accept(ExprVisitor *v) { v->visitUnop(this); } - static bool classof(const Expr *c) { return c->exprKind == UnopExpr; } }; @@ -669,8 +621,6 @@ struct Binop: Expr { this->right = right; } - virtual void accept(ExprVisitor *v) { v->visitBinop(this); } - static bool classof(const Expr *c) { return c->exprKind == BinopExpr; } }; @@ -692,8 +642,6 @@ struct Call: Expr { return 0; } - virtual void accept(ExprVisitor *v) { v->visitCall(this); } - static bool classof(const Expr *c) { return c->exprKind == CallExpr; } }; @@ -715,8 +663,6 @@ struct New: Expr { return 0; } - virtual void accept(ExprVisitor *v) { v->visitNew(this); } - static bool classof(const Expr *c) { return c->exprKind == NewExpr; } }; @@ -732,8 +678,6 @@ struct Subscript: Expr { this->index = index; } - virtual void accept(ExprVisitor *v) { v->visitSubscript(this); } - static bool classof(const Expr *c) { return c->exprKind == SubscriptExpr; } }; @@ -789,8 +733,6 @@ struct Member: Expr { this->kind = kind; } - virtual void accept(ExprVisitor *v) { v->visitMember(this); } - static bool classof(const Expr *c) { return c->exprKind == MemberExpr; } }; @@ -829,17 +771,8 @@ struct Stmt { explicit Stmt(int id, StmtKind stmtKind): _id(id), stmtKind(stmtKind) {} - virtual ~Stmt() - { -#ifdef Q_CC_MSVC - // MSVC complains about potential memory leaks if a destructor never returns. -#else - Q_UNREACHABLE(); -#endif - } - virtual Stmt *asTerminator() { return 0; } + Stmt *asTerminator(); - virtual void accept(StmtVisitor *) = 0; Exp *asExp() { return as<Exp>(); } Move *asMove() { return as<Move>(); } Jump *asJump() { return as<Jump>(); } @@ -900,8 +833,6 @@ struct Exp: Stmt { this->expr = expr; } - virtual void accept(StmtVisitor *v) { v->visitExp(this); } - static bool classof(const Stmt *c) { return c->stmtKind == ExpStmt; } }; @@ -919,8 +850,6 @@ struct Move: Stmt { this->swap = false; } - virtual void accept(StmtVisitor *v) { v->visitMove(this); } - static bool classof(const Stmt *c) { return c->stmtKind == MoveStmt; } }; @@ -934,10 +863,6 @@ struct Jump: Stmt { this->target = target; } - virtual Stmt *asTerminator() { return this; } - - virtual void accept(StmtVisitor *v) { v->visitJump(this); } - static bool classof(const Stmt *c) { return c->stmtKind == JumpStmt; } }; @@ -957,10 +882,6 @@ struct CJump: Stmt { this->parent = parent; } - virtual Stmt *asTerminator() { return this; } - - virtual void accept(StmtVisitor *v) { v->visitCJump(this); } - static bool classof(const Stmt *c) { return c->stmtKind == CJumpStmt; } }; @@ -974,10 +895,6 @@ struct Ret: Stmt { this->expr = expr; } - virtual Stmt *asTerminator() { return this; } - - virtual void accept(StmtVisitor *v) { v->visitRet(this); } - static bool classof(const Stmt *c) { return c->stmtKind == RetStmt; } }; @@ -991,14 +908,25 @@ struct Phi: Stmt { Phi(int id): Stmt(id, PhiStmt) {} - virtual void accept(StmtVisitor *v) { v->visitPhi(this); } - static bool classof(const Stmt *c) { return c->stmtKind == PhiStmt; } void destroyData() { incoming.~VarLengthArray(); } }; +inline Stmt *Stmt::asTerminator() +{ + if (auto s = asJump()) { + return s; + } else if (auto s = asCJump()) { + return s; + } else if (auto s = asRet()) { + return s; + } else { + return nullptr; + } +} + struct Q_QML_PRIVATE_EXPORT Module { QQmlJS::MemoryPool pool; QVector<Function *> functions; @@ -1397,7 +1325,7 @@ private: int _statementCount; }; -class CloneExpr: protected IR::ExprVisitor +class CloneExpr { public: explicit CloneExpr(IR::BasicBlock *block = 0); @@ -1415,7 +1343,7 @@ public: { Expr *c = expr; qSwap(cloned, c); - expr->accept(this); + visit(expr); qSwap(cloned, c); return static_cast<ExprSubclass *>(c); } @@ -1458,23 +1386,10 @@ public: return newArgLocal; } -protected: +private: IR::ExprList *clone(IR::ExprList *list); - virtual void visitConst(Const *); - virtual void visitString(String *); - virtual void visitRegExp(RegExp *); - virtual void visitName(Name *); - virtual void visitTemp(Temp *); - virtual void visitArgLocal(ArgLocal *); - virtual void visitClosure(Closure *); - virtual void visitConvert(Convert *); - virtual void visitUnop(Unop *); - virtual void visitBinop(Binop *); - virtual void visitCall(Call *); - virtual void visitNew(New *); - virtual void visitSubscript(Subscript *); - virtual void visitMember(Member *); + void visit(Expr *e); protected: IR::BasicBlock *block; @@ -1483,7 +1398,7 @@ private: IR::Expr *cloned; }; -class Q_AUTOTEST_EXPORT IRPrinter: public StmtVisitor, public ExprVisitor +class Q_AUTOTEST_EXPORT IRPrinter { public: IRPrinter(QTextStream *out); @@ -1496,6 +1411,7 @@ public: virtual void print(Function *f); virtual void print(BasicBlock *bb); + void visit(Stmt *s); virtual void visitExp(Exp *s); virtual void visitMove(Move *s); virtual void visitJump(Jump *s); @@ -1503,6 +1419,7 @@ public: virtual void visitRet(Ret *s); virtual void visitPhi(Phi *s); + void visit(Expr *e); virtual void visitConst(Const *e); virtual void visitString(String *e); virtual void visitRegExp(RegExp *e); diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 6965d839ab..90e72facfc 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -898,7 +898,7 @@ private: } }; -class VariableCollector: public StmtVisitor, ExprVisitor { +class VariableCollector { std::vector<Temp> _allTemps; std::vector<BasicBlockSet> _defsites; std::vector<std::vector<int> > A_orig; @@ -946,7 +946,7 @@ public: currentBB = bb; killed.assign(function->tempCount, false); for (Stmt *s : bb->statements()) - s->accept(this); + visit(s); } } @@ -971,62 +971,45 @@ public: return nonLocals.at(var.index); } -protected: - virtual void visitPhi(Phi *) {} - virtual void visitConvert(Convert *e) { e->expr->accept(this); } - - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitUnop(Unop *e) { e->expr->accept(this); } - virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); } - virtual void visitSubscript(Subscript *e) { e->base->accept(this); e->index->accept(this); } - virtual void visitMember(Member *e) { e->base->accept(this); } - virtual void visitExp(Exp *s) { s->expr->accept(this); } - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { s->cond->accept(this); } - virtual void visitRet(Ret *s) { s->expr->accept(this); } - - virtual void visitCall(Call *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitNew(New *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitMove(Move *s) { - s->source->accept(this); +private: + void visit(Stmt *s) + { + if (s->asPhi()) { + // nothing to do + } else if (auto move = s->asMove()) { + visit(move->source); - if (Temp *t = s->target->asTemp()) { - addTemp(t); + if (Temp *t = move->target->asTemp()) { + addTemp(t); - if (isCollectable(t)) { - _defsites[t->index].insert(currentBB); - addDefInCurrentBlock(t); + if (isCollectable(t)) { + _defsites[t->index].insert(currentBB); + addDefInCurrentBlock(t); - // For semi-pruned SSA: - killed.setBit(t->index); + // For semi-pruned SSA: + killed.setBit(t->index); + } + } else { + visit(move->target); } } else { - s->target->accept(this); + STMT_VISIT_ALL_KINDS(s) } } - virtual void visitTemp(Temp *t) + void visit(Expr *e) { - addTemp(t); + if (auto t = e->asTemp()) { + addTemp(t); - if (isCollectable(t)) - if (!killed.at(t->index)) - nonLocals.setBit(t->index); + if (isCollectable(t)) { + if (!killed.at(t->index)) { + nonLocals.setBit(t->index); + } + } + } else { + EXPR_VISIT_ALL_KINDS(e); + } } }; @@ -1345,7 +1328,7 @@ void insertPhiNode(const Temp &a, BasicBlock *y, IR::Function *f) { // // Undo(t, c) = // mapping[t] = c -class VariableRenamer: public StmtVisitor, public ExprVisitor +class VariableRenamer { Q_DISABLE_COPY(VariableRenamer) @@ -1466,7 +1449,7 @@ private: for (Stmt *s : bb->statements()) { currentStmt = s; - s->accept(this); + visit(s); } for (BasicBlock *Y : bb->out) { @@ -1532,23 +1515,35 @@ private: return newIndex; } -protected: - virtual void visitTemp(Temp *e) { // only called for uses, not defs -// qDebug()<<"I: replacing use of"<<e->index<<"with"<<stack[e->index].top(); - e->index = currentNumber(*e); - e->kind = Temp::VirtualRegister; - defUses.addUse(*e, currentStmt); - } +private: + void visit(Stmt *s) + { + if (auto move = s->asMove()) { + // uses: + visit(move->source); - virtual void visitMove(Move *s) { - // uses: - s->source->accept(this); + // defs: + if (Temp *t = move->target->asTemp()) { + renameTemp(t); + } else { + visit(move->target); + } + } else if (auto phi = s->asPhi()) { + renameTemp(phi->targetTemp); + } else { + STMT_VISIT_ALL_KINDS(s); + } + } - // defs: - if (Temp *t = s->target->asTemp()) - renameTemp(t); - else - s->target->accept(this); + void visit(Expr *e) + { + if (auto temp = e->asTemp()) { + temp->index = currentNumber(*temp); + temp->kind = Temp::VirtualRegister; + defUses.addUse(*temp, currentStmt); + } else { + EXPR_VISIT_ALL_KINDS(e); + } } void renameTemp(Temp *t) { // only called for defs, not uses @@ -1558,44 +1553,6 @@ protected: t->index = newIdx; defUses.addDef(t, currentStmt, currentBB); } - - virtual void visitConvert(Convert *e) { e->expr->accept(this); } - virtual void visitPhi(Phi *s) { renameTemp(s->targetTemp); } - - virtual void visitExp(Exp *s) { s->expr->accept(this); } - - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { s->cond->accept(this); } - virtual void visitRet(Ret *s) { s->expr->accept(this); } - - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitUnop(Unop *e) { e->expr->accept(this); } - virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); } - virtual void visitCall(Call *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitNew(New *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitSubscript(Subscript *e) { - e->base->accept(this); - e->index->accept(this); - } - - virtual void visitMember(Member *e) { - e->base->accept(this); - } }; // This function converts the IR to semi-pruned SSA form. For details about SSA and the algorightm, @@ -1922,7 +1879,7 @@ private: } }; -class SideEffectsChecker: public ExprVisitor +class SideEffectsChecker { bool _sideEffect; @@ -1931,11 +1888,14 @@ public: : _sideEffect(false) {} + ~SideEffectsChecker() + {} + bool hasSideEffects(Expr *expr) { bool sideEffect = false; qSwap(_sideEffect, sideEffect); - expr->accept(this); + visit(expr); qSwap(_sideEffect, sideEffect); return sideEffect; } @@ -1948,12 +1908,35 @@ protected: bool seenSideEffects() const { return _sideEffect; } -protected: - void visitConst(Const *) Q_DECL_OVERRIDE {} - void visitString(IR::String *) Q_DECL_OVERRIDE {} - void visitRegExp(IR::RegExp *) Q_DECL_OVERRIDE {} + void visit(Expr *e) + { + if (auto n = e->asName()) { + visitName(n); + } else if (auto t = e->asTemp()) { + visitTemp(t); + } else if (auto c = e->asClosure()) { + visitClosure(c); + } else if (auto c = e->asConvert()) { + visitConvert(c); + } else if (auto u = e->asUnop()) { + visitUnop(u); + } else if (auto b = e->asBinop()) { + visitBinop(b); + } else if (auto c = e->asCall()) { + visitCall(c); + } else if (auto n = e->asNew()) { + visitNew(n); + } else if (auto s = e->asSubscript()) { + visitSubscript(s); + } else if (auto m = e->asMember()) { + visitMember(m); + } + } - void visitName(Name *e) Q_DECL_OVERRIDE { + virtual void visitTemp(Temp *) {} + +private: + void visitName(Name *e) { if (e->freeOfSideEffects) return; // TODO: maybe we can distinguish between built-ins of which we know that they do not have @@ -1962,15 +1945,12 @@ protected: markAsSideEffect(); } - void visitTemp(Temp *) Q_DECL_OVERRIDE {} - void visitArgLocal(ArgLocal *) Q_DECL_OVERRIDE {} - - void visitClosure(Closure *) Q_DECL_OVERRIDE { + void visitClosure(Closure *) { markAsSideEffect(); } - void visitConvert(Convert *e) Q_DECL_OVERRIDE { - e->expr->accept(this); + void visitConvert(Convert *e) { + visit(e->expr); switch (e->expr->type) { case QObjectType: @@ -1983,8 +1963,8 @@ protected: } } - void visitUnop(Unop *e) Q_DECL_OVERRIDE { - e->expr->accept(this); + void visitUnop(Unop *e) { + visit(e->expr); switch (e->op) { case OpUPlus: @@ -2001,7 +1981,7 @@ protected: } } - void visitBinop(Binop *e) Q_DECL_OVERRIDE { + void visitBinop(Binop *e) { // TODO: prune parts that don't have a side-effect. For example, in: // function f(x) { +x+1; return 0; } // we can prune the binop and leave the unop/conversion. @@ -2013,30 +1993,30 @@ protected: markAsSideEffect(); } - void visitSubscript(Subscript *e) Q_DECL_OVERRIDE { - e->base->accept(this); - e->index->accept(this); + void visitSubscript(Subscript *e) { + visit(e->base); + visit(e->index); markAsSideEffect(); } - void visitMember(Member *e) Q_DECL_OVERRIDE { - e->base->accept(this); + void visitMember(Member *e) { + visit(e->base); if (e->freeOfSideEffects) return; markAsSideEffect(); } - void visitCall(Call *e) Q_DECL_OVERRIDE { - e->base->accept(this); + void visitCall(Call *e) { + visit(e->base); for (ExprList *args = e->args; args; args = args->next) - args->expr->accept(this); + visit(args->expr); markAsSideEffect(); // TODO: there are built-in functions that have no side effect. } - void visitNew(New *e) Q_DECL_OVERRIDE { - e->base->accept(this); + void visitNew(New *e) { + visit(e->base); for (ExprList *args = e->args; args; args = args->next) - args->expr->accept(this); + visit(args->expr); markAsSideEffect(); // TODO: there are built-in types that have no side effect. } }; @@ -2045,21 +2025,19 @@ class EliminateDeadCode: public SideEffectsChecker { DefUses &_defUses; StatementWorklist &_worklist; - QVector<Temp *> _collectedTemps; + QVarLengthArray<Temp *, 8> _collectedTemps; public: EliminateDeadCode(DefUses &defUses, StatementWorklist &worklist) : _defUses(defUses) , _worklist(worklist) - { - _collectedTemps.reserve(8); - } + {} void run(Expr *&expr, Stmt *stmt) { _collectedTemps.clear(); if (!hasSideEffects(expr)) { expr = 0; - foreach (Temp *t, _collectedTemps) { + for (Temp *t : _collectedTemps) { _defUses.removeUse(stmt, *t); _worklist += _defUses.defStmt(*t); } @@ -2067,13 +2045,13 @@ public: } protected: - void visitTemp(Temp *e) Q_DECL_OVERRIDE + void visitTemp(Temp *e) Q_DECL_OVERRIDE Q_DECL_FINAL { _collectedTemps.append(e); } }; -class PropagateTempTypes: public StmtVisitor, ExprVisitor +class PropagateTempTypes { const DefUses &defUses; UntypedTemp theTemp; @@ -2089,64 +2067,31 @@ public: newType = type; theTemp = temp; if (Stmt *defStmt = defUses.defStmt(temp.temp)) - defStmt->accept(this); + visit(defStmt); foreach (Stmt *use, defUses.uses(temp.temp)) - use->accept(this); - } - -protected: - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitTemp(Temp *e) { - if (theTemp == UntypedTemp(*e)) { - e->type = static_cast<Type>(newType.type); - e->memberResolver = newType.memberResolver; - } - } - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitConvert(Convert *e) { e->expr->accept(this); } - virtual void visitUnop(Unop *e) { e->expr->accept(this); } - virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); } - - virtual void visitCall(Call *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - virtual void visitNew(New *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - virtual void visitSubscript(Subscript *e) { - e->base->accept(this); - e->index->accept(this); + visit(use); } - virtual void visitMember(Member *e) { - e->base->accept(this); - } - - virtual void visitExp(Exp *s) {s->expr->accept(this);} - virtual void visitMove(Move *s) { - s->source->accept(this); - s->target->accept(this); +private: + void visit(Stmt *s) + { + STMT_VISIT_ALL_KINDS(s); } - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { s->cond->accept(this); } - virtual void visitRet(Ret *s) { s->expr->accept(this); } - virtual void visitPhi(Phi *s) { - s->targetTemp->accept(this); - foreach (Expr *e, s->incoming) - e->accept(this); + void visit(Expr *e) + { + if (auto temp = e->asTemp()) { + if (theTemp == UntypedTemp(*temp)) { + temp->type = static_cast<Type>(newType.type); + temp->memberResolver = newType.memberResolver; + } + } else { + EXPR_VISIT_ALL_KINDS(e); + } } }; -class TypeInference: public StmtVisitor, public ExprVisitor +class TypeInference { enum { DebugTypeInference = 0 }; @@ -2248,7 +2193,7 @@ private: TypingResult ty; std::swap(_ty, ty); std::swap(_currentStmt, s); - _currentStmt->accept(this); + visit(_currentStmt); std::swap(_currentStmt, s); std::swap(_ty, ty); return ty.fullyTyped; @@ -2257,7 +2202,7 @@ private: TypingResult run(Expr *e) { TypingResult ty; std::swap(_ty, ty); - e->accept(this); + visit(e); std::swap(_ty, ty); if (ty.type != UnknownType) @@ -2299,39 +2244,74 @@ private: } } -protected: - virtual void visitConst(Const *e) { - if (e->type & NumberType) { - if (canConvertToSignedInteger(e->value)) +private: + void visit(Expr *e) + { + if (auto c = e->asConst()) { + visitConst(c); + } else if (auto s = e->asString()) { + visitString(s); + } else if (auto r = e->asRegExp()) { + visitRegExp(r); + } else if (auto n = e->asName()) { + visitName(n); + } else if (auto t = e->asTemp()) { + visitTemp(t); + } else if (auto a = e->asArgLocal()) { + visitArgLocal(a); + } else if (auto c = e->asClosure()) { + visitClosure(c); + } else if (auto c = e->asConvert()) { + visitConvert(c); + } else if (auto u = e->asUnop()) { + visitUnop(u); + } else if (auto b = e->asBinop()) { + visitBinop(b); + } else if (auto c = e->asCall()) { + visitCall(c); + } else if (auto n = e->asNew()) { + visitNew(n); + } else if (auto s = e->asSubscript()) { + visitSubscript(s); + } else if (auto m = e->asMember()) { + visitMember(m); + } else { + Q_UNREACHABLE(); + } + } + + void visitConst(Const *c) { + if (c->type & NumberType) { + if (canConvertToSignedInteger(c->value)) _ty = TypingResult(SInt32Type); - else if (canConvertToUnsignedInteger(e->value)) + else if (canConvertToUnsignedInteger(c->value)) _ty = TypingResult(UInt32Type); else - _ty = TypingResult(e->type); + _ty = TypingResult(c->type); } else - _ty = TypingResult(e->type); + _ty = TypingResult(c->type); } - virtual void visitString(IR::String *) { _ty = TypingResult(StringType); } - virtual void visitRegExp(IR::RegExp *) { _ty = TypingResult(VarType); } - virtual void visitName(Name *) { _ty = TypingResult(VarType); } - virtual void visitTemp(Temp *e) { + void visitString(IR::String *) { _ty = TypingResult(StringType); } + void visitRegExp(IR::RegExp *) { _ty = TypingResult(VarType); } + void visitName(Name *) { _ty = TypingResult(VarType); } + void visitTemp(Temp *e) { if (e->memberResolver && e->memberResolver->isValid()) _ty = TypingResult(e->memberResolver); else _ty = TypingResult(_tempTypes[e->index]); setType(e, _ty.type); } - virtual void visitArgLocal(ArgLocal *e) { + void visitArgLocal(ArgLocal *e) { _ty = TypingResult(VarType); setType(e, _ty.type); } - virtual void visitClosure(Closure *) { _ty = TypingResult(VarType); } - virtual void visitConvert(Convert *e) { + void visitClosure(Closure *) { _ty = TypingResult(VarType); } + void visitConvert(Convert *e) { _ty = TypingResult(e->type); } - virtual void visitUnop(Unop *e) { + void visitUnop(Unop *e) { _ty = run(e->expr); switch (e->op) { case OpUPlus: _ty.type = DoubleType; return; @@ -2348,7 +2328,7 @@ protected: } } - virtual void visitBinop(Binop *e) { + void visitBinop(Binop *e) { TypingResult leftTy = run(e->left); TypingResult rightTy = run(e->right); _ty.fullyTyped = leftTy.fullyTyped && rightTy.fullyTyped; @@ -2406,24 +2386,24 @@ protected: } } - virtual void visitCall(Call *e) { + void visitCall(Call *e) { _ty = run(e->base); for (ExprList *it = e->args; it; it = it->next) _ty.fullyTyped &= run(it->expr).fullyTyped; _ty.type = VarType; } - virtual void visitNew(New *e) { + void visitNew(New *e) { _ty = run(e->base); for (ExprList *it = e->args; it; it = it->next) _ty.fullyTyped &= run(it->expr).fullyTyped; _ty.type = VarType; } - virtual void visitSubscript(Subscript *e) { + void visitSubscript(Subscript *e) { _ty.fullyTyped = run(e->base).fullyTyped && run(e->index).fullyTyped; _ty.type = VarType; } - virtual void visitMember(Member *e) { + void visitMember(Member *e) { _ty = run(e->base); if (_ty.fullyTyped && _ty.type.memberResolver && _ty.type.memberResolver->isValid()) { @@ -2433,8 +2413,27 @@ protected: _ty.type = VarType; } - virtual void visitExp(Exp *s) { _ty = run(s->expr); } - virtual void visitMove(Move *s) { + void visit(Stmt *s) + { + if (auto e = s->asExp()) { + visitExp(e); + } else if (auto m = s->asMove()) { + visitMove(m); + } else if (auto j = s->asJump()) { + visitJump(j); + } else if (auto c = s->asCJump()) { + visitCJump(c); + } else if (auto r = s->asRet()) { + visitRet(r); + } else if (auto p = s->asPhi()) { + visitPhi(p); + } else { + Q_UNREACHABLE(); + } + } + + void visitExp(Exp *s) { _ty = run(s->expr); } + void visitMove(Move *s) { if (Temp *t = s->target->asTemp()) { if (Name *n = s->source->asName()) { if (n->builtin == Name::builtin_qml_context) { @@ -2455,10 +2454,10 @@ protected: _ty.fullyTyped &= sourceTy.fullyTyped; } - virtual void visitJump(Jump *) { _ty = TypingResult(MissingType); } - virtual void visitCJump(CJump *s) { _ty = run(s->cond); } - virtual void visitRet(Ret *s) { _ty = run(s->expr); } - virtual void visitPhi(Phi *s) { + void visitJump(Jump *) { _ty = TypingResult(MissingType); } + void visitCJump(CJump *s) { _ty = run(s->cond); } + void visitRet(Ret *s) { _ty = run(s->expr); } + void visitPhi(Phi *s) { _ty = run(s->incoming[0]); for (int i = 1, ei = s->incoming.size(); i != ei; ++i) { TypingResult ty = run(s->incoming[i]); @@ -2677,14 +2676,15 @@ void convertConst(Const *c, Type targetType) c->type = targetType; } -class TypePropagation: public StmtVisitor, public ExprVisitor { +class TypePropagation +{ DefUses &_defUses; Type _ty; IR::Function *_f; bool run(Expr *&e, Type requestedType = UnknownType, bool insertConversion = true) { qSwap(_ty, requestedType); - e->accept(this); + visit(e); qSwap(_ty, requestedType); if (requestedType != UnknownType) { @@ -2731,7 +2731,7 @@ public: for (Stmt *s : bb->statements()) { _currStmt = s; - s->accept(this); + visit(s); } foreach (const Conversion &conversion, _conversions) { @@ -2817,8 +2817,29 @@ public: } } -protected: - virtual void visitConst(Const *c) { +private: + void visit(Expr *e) + { + if (auto c = e->asConst()) { + visitConst(c); + } else if (auto c = e->asConvert()) { + run(c->expr, c->type); + } else if (auto u = e->asUnop()) { + run(u->expr, u->type); + } else if (auto b = e->asBinop()) { + visitBinop(b); + } else if (auto c = e->asCall()) { + visitCall(c); + } else if (auto n = e->asNew()) { + visitNew(n); + } else if (auto s = e->asSubscript()) { + visitSubscript(s); + } else if (auto m = e->asMember()) { + visitMember(m); + } + } + + void visitConst(Const *c) { if (_ty & NumberType && c->type & NumberType) { if (_ty == SInt32Type) c->value = QV4::Primitive::toInt32(c->value); @@ -2828,15 +2849,7 @@ protected: } } - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitTemp(Temp *) {} - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitConvert(Convert *e) { run(e->expr, e->type); } - virtual void visitUnop(Unop *e) { run(e->expr, e->type); } - virtual void visitBinop(Binop *e) { + void visitBinop(Binop *e) { // FIXME: This routine needs more tuning! switch (e->op) { case OpAdd: @@ -2887,20 +2900,36 @@ protected: Q_UNREACHABLE(); } } - virtual void visitCall(Call *e) { + void visitCall(Call *e) { run(e->base); for (ExprList *it = e->args; it; it = it->next) run(it->expr); } - virtual void visitNew(New *e) { + void visitNew(New *e) { run(e->base); for (ExprList *it = e->args; it; it = it->next) run(it->expr); } - virtual void visitSubscript(Subscript *e) { run(e->base); run(e->index); } - virtual void visitMember(Member *e) { run(e->base); } - virtual void visitExp(Exp *s) { run(s->expr); } - virtual void visitMove(Move *s) { + void visitSubscript(Subscript *e) { run(e->base); run(e->index); } + void visitMember(Member *e) { run(e->base); } + + void visit(Stmt *s) + { + if (auto e = s->asExp()) { + visitExp(e); + } else if (auto m = s->asMove()) { + visitMove(m); + } else if (auto c = s->asCJump()) { + visitCJump(c); + } else if (auto r = s->asRet()) { + visitRet(r); + } else if (auto p = s->asPhi()) { + visitPhi(p); + } + } + + void visitExp(Exp *s) { run(s->expr); } + void visitMove(Move *s) { if (s->source->asConvert()) return; // this statement got inserted for a phi-node type conversion @@ -2925,12 +2954,11 @@ protected: run(s->source, s->target->type, !inhibitConversion); } - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { + void visitCJump(CJump *s) { run(s->cond, BoolType); } - virtual void visitRet(Ret *s) { run(s->expr); } - virtual void visitPhi(Phi *s) { + void visitRet(Ret *s) { run(s->expr); } + void visitPhi(Phi *s) { Type ty = s->targetTemp->type; for (int i = 0, ei = s->incoming.size(); i != ei; ++i) run(s->incoming[i], ty); @@ -3504,7 +3532,7 @@ static Expr *clone(Expr *e, IR::Function *function) { } } -class ExprReplacer: public StmtVisitor, public ExprVisitor +class ExprReplacer { DefUses &_defUses; IR::Function* _function; @@ -3535,7 +3563,7 @@ public: // qout << " " << uses.size() << " uses:"<<endl; foreach (Stmt *use, uses) { // qout<<" ";use->dump(qout);qout<<"\n"; - use->accept(this); + visit(use); // qout<<" -> ";use->dump(qout);qout<<"\n"; W += use; if (newUses) @@ -3546,45 +3574,101 @@ public: qSwap(_toReplace, toReplace); } -protected: - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitTemp(Temp *) {} - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitConvert(Convert *e) { check(e->expr); } - virtual void visitUnop(Unop *e) { check(e->expr); } - virtual void visitBinop(Binop *e) { check(e->left); check(e->right); } - virtual void visitCall(Call *e) { +private: + void visit(Expr *e) + { + if (auto c = e->asConst()) { + visitConst(c); + } else if (auto s = e->asString()) { + visitString(s); + } else if (auto r = e->asRegExp()) { + visitRegExp(r); + } else if (auto n = e->asName()) { + visitName(n); + } else if (auto t = e->asTemp()) { + visitTemp(t); + } else if (auto a = e->asArgLocal()) { + visitArgLocal(a); + } else if (auto c = e->asClosure()) { + visitClosure(c); + } else if (auto c = e->asConvert()) { + visitConvert(c); + } else if (auto u = e->asUnop()) { + visitUnop(u); + } else if (auto b = e->asBinop()) { + visitBinop(b); + } else if (auto c = e->asCall()) { + visitCall(c); + } else if (auto n = e->asNew()) { + visitNew(n); + } else if (auto s = e->asSubscript()) { + visitSubscript(s); + } else if (auto m = e->asMember()) { + visitMember(m); + } else { + Q_UNREACHABLE(); + } + } + + void visitConst(Const *) {} + void visitString(IR::String *) {} + void visitRegExp(IR::RegExp *) {} + void visitName(Name *) {} + void visitTemp(Temp *) {} + void visitArgLocal(ArgLocal *) {} + void visitClosure(Closure *) {} + void visitConvert(Convert *e) { check(e->expr); } + void visitUnop(Unop *e) { check(e->expr); } + void visitBinop(Binop *e) { check(e->left); check(e->right); } + void visitCall(Call *e) { check(e->base); for (ExprList *it = e->args; it; it = it->next) check(it->expr); } - virtual void visitNew(New *e) { + void visitNew(New *e) { check(e->base); for (ExprList *it = e->args; it; it = it->next) check(it->expr); } - virtual void visitSubscript(Subscript *e) { check(e->base); check(e->index); } - virtual void visitMember(Member *e) { check(e->base); } - virtual void visitExp(Exp *s) { check(s->expr); } - virtual void visitMove(Move *s) { check(s->target); check(s->source); } - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { check(s->cond); } - virtual void visitRet(Ret *s) { check(s->expr); } - virtual void visitPhi(Phi *s) { + void visitSubscript(Subscript *e) { check(e->base); check(e->index); } + void visitMember(Member *e) { check(e->base); } + + void visit(Stmt *s) + { + if (auto e = s->asExp()) { + visitExp(e); + } else if (auto m = s->asMove()) { + visitMove(m); + } else if (auto j = s->asJump()) { + visitJump(j); + } else if (auto c = s->asCJump()) { + visitCJump(c); + } else if (auto r = s->asRet()) { + visitRet(r); + } else if (auto p = s->asPhi()) { + visitPhi(p); + } else { + Q_UNREACHABLE(); + } + } + + void visitExp(Exp *s) { check(s->expr); } + void visitMove(Move *s) { check(s->target); check(s->source); } + void visitJump(Jump *) {} + void visitCJump(CJump *s) { check(s->cond); } + void visitRet(Ret *s) { check(s->expr); } + void visitPhi(Phi *s) { for (int i = 0, ei = s->incoming.size(); i != ei; ++i) check(s->incoming[i]); } private: void check(Expr *&e) { - if (equals(e, _toReplace)) + if (equals(e, _toReplace)) { e = clone(_replacement, _function); - else - e->accept(this); + } else { + visit(e); + } } // This only calculates equality for everything needed by constant propagation @@ -4153,7 +4237,8 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df) } //### TODO: use DefUses from the optimizer, because it already has all this information -class InputOutputCollector: protected StmtVisitor, protected ExprVisitor { +class InputOutputCollector +{ void setOutput(Temp *out) { Q_ASSERT(!output); @@ -4170,48 +4255,33 @@ public: void collect(Stmt *s) { inputs.resize(0); output = 0; - s->accept(this); + visit(s); } -protected: - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitTemp(Temp *e) { - inputs.push_back(e); - } - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitConvert(Convert *e) { e->expr->accept(this); } - virtual void visitUnop(Unop *e) { e->expr->accept(this); } - virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); } - virtual void visitCall(Call *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - virtual void visitNew(New *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - virtual void visitSubscript(Subscript *e) { e->base->accept(this); e->index->accept(this); } - virtual void visitMember(Member *e) { e->base->accept(this); } - virtual void visitExp(Exp *s) { s->expr->accept(this); } - virtual void visitMove(Move *s) { - s->source->accept(this); - if (Temp *t = s->target->asTemp()) { - setOutput(t); +private: + void visit(Expr *e) + { + if (auto t = e->asTemp()) { + inputs.push_back(t); } else { - s->target->accept(this); + EXPR_VISIT_ALL_KINDS(e); } } - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { s->cond->accept(this); } - virtual void visitRet(Ret *s) { s->expr->accept(this); } - virtual void visitPhi(Phi *) { - // Handled separately + + void visit(Stmt *s) + { + if (auto m = s->asMove()) { + visit(m->source); + if (Temp *t = m->target->asTemp()) { + setOutput(t); + } else { + visit(m->target); + } + } else if (s->asPhi()) { + // Handled separately + } else { + STMT_VISIT_ALL_KINDS(s); + } } }; @@ -4381,7 +4451,7 @@ void removeUnreachleBlocks(IR::Function *function) function->renumberBasicBlocks(); } -class ConvertArgLocals: protected StmtVisitor, protected ExprVisitor +class ConvertArgLocals { public: ConvertArgLocals(IR::Function *function) @@ -4419,10 +4489,13 @@ public: } } - for (BasicBlock *bb : function->basicBlocks()) - if (!bb->isRemoved()) - for (Stmt *s : bb->statements()) - s->accept(this); + for (BasicBlock *bb : function->basicBlocks()) { + if (!bb->isRemoved()) { + for (Stmt *s : bb->statements()) { + visit(s); + } + } + } if (convertArgs && function->formals.size() > 0) function->basicBlock(0)->prependStatements(extraMoves); @@ -4430,39 +4503,45 @@ public: function->locals.clear(); } -protected: - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitTemp(Temp *) {} - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitClosure(Closure *) {} - virtual void visitConvert(Convert *e) { check(e->expr); } - virtual void visitUnop(Unop *e) { check(e->expr); } - virtual void visitBinop(Binop *e) { check(e->left); check(e->right); } - virtual void visitCall(Call *e) { - check(e->base); - for (ExprList *it = e->args; it; it = it->next) - check(it->expr); - } - virtual void visitNew(New *e) { - check(e->base); - for (ExprList *it = e->args; it; it = it->next) - check(it->expr); +private: + void visit(Stmt *s) + { + if (auto e = s->asExp()) { + check(e->expr); + } else if (auto m = s->asMove()) { + check(m->target); check(m->source); + } else if (auto c = s->asCJump()) { + check(c->cond); + } else if (auto r = s->asRet()) { + check(r->expr); + } } - virtual void visitSubscript(Subscript *e) { check(e->base); check(e->index); } - virtual void visitMember(Member *e) { check(e->base); } - virtual void visitExp(Exp *s) { check(s->expr); } - virtual void visitMove(Move *s) { check(s->target); check(s->source); } - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { check(s->cond); } - virtual void visitRet(Ret *s) { check(s->expr); } - virtual void visitPhi(Phi *) { - Q_UNREACHABLE(); + + void visit(Expr *e) + { + if (auto c = e->asConvert()) { + check(c->expr); + } else if (auto u = e->asUnop()) { + check(u->expr); + } else if (auto b = e->asBinop()) { + check(b->left); check(b->right); + } else if (auto c = e->asCall()) { + check(c->base); + for (ExprList *it = c->args; it; it = it->next) { + check(it->expr); + } + } else if (auto n = e->asNew()) { + check(n->base); + for (ExprList *it = n->args; it; it = it->next) { + check(it->expr); + } + } else if (auto s = e->asSubscript()) { + check(s->base); check(s->index); + } else if (auto m = e->asMember()) { + check(m->base); + } } -private: void check(Expr *&e) { if (ArgLocal *al = e->asArgLocal()) { if (al->kind == ArgLocal::Local) { @@ -4475,7 +4554,7 @@ private: e = t; } } else { - e->accept(this); + visit(e); } } @@ -4498,7 +4577,7 @@ private: std::vector<int> tempForLocal; }; -class CloneBasicBlock: protected IR::StmtVisitor, protected CloneExpr +class CloneBasicBlock: protected CloneExpr { public: BasicBlock *operator()(IR::BasicBlock *originalBlock) @@ -4506,38 +4585,37 @@ public: block = new BasicBlock(originalBlock->function, 0); for (Stmt *s : originalBlock->statements()) { - s->accept(this); + visit(s); clonedStmt->location = s->location; } return block; } -protected: - virtual void visitExp(Exp *stmt) - { clonedStmt = block->EXP(clone(stmt->expr)); } - - virtual void visitMove(Move *stmt) - { clonedStmt = block->MOVE(clone(stmt->target), clone(stmt->source)); } - - virtual void visitJump(Jump *stmt) - { clonedStmt = block->JUMP(stmt->target); } - - virtual void visitCJump(CJump *stmt) - { clonedStmt = block->CJUMP(clone(stmt->cond), stmt->iftrue, stmt->iffalse); } - - virtual void visitRet(Ret *stmt) - { clonedStmt = block->RET(clone(stmt->expr)); } - - virtual void visitPhi(Phi *stmt) +private: + void visit(Stmt *s) { - Phi *phi = block->function->NewStmt<Phi>(); - clonedStmt = phi; - - phi->targetTemp = clone(stmt->targetTemp); - foreach (Expr *in, stmt->incoming) - phi->incoming.append(clone(in)); - block->appendStatement(phi); + if (auto e = s->asExp()) { + clonedStmt = block->EXP(clone(e->expr)); + } else if (auto m = s->asMove()) { + clonedStmt = block->MOVE(clone(m->target), clone(m->source)); + } else if (auto j = s->asJump()) { + clonedStmt = block->JUMP(j->target); + } else if (auto c = s->asCJump()) { + clonedStmt = block->CJUMP(clone(c->cond), c->iftrue, c->iffalse); + } else if (auto r = s->asRet()) { + clonedStmt = block->RET(clone(r->expr)); + } else if (auto p = s->asPhi()) { + Phi *phi = block->function->NewStmt<Phi>(); + clonedStmt = phi; + + phi->targetTemp = clone(p->targetTemp); + foreach (Expr *in, p->incoming) + phi->incoming.append(clone(in)); + block->appendStatement(phi); + } else { + Q_UNREACHABLE(); + } } private: @@ -4769,7 +4847,7 @@ static void verifyNoPointerSharing(IR::Function *function) if (!DoVerification) return; - class : public StmtVisitor, public ExprVisitor { + class { public: void operator()(IR::Function *f) { @@ -4777,44 +4855,23 @@ static void verifyNoPointerSharing(IR::Function *function) if (bb->isRemoved()) continue; - for (Stmt *s : bb->statements()) - s->accept(this); + for (Stmt *s : bb->statements()) { + visit(s); + } } } - protected: - virtual void visitExp(Exp *s) { check(s); s->expr->accept(this); } - virtual void visitMove(Move *s) { check(s); s->target->accept(this); s->source->accept(this); } - virtual void visitJump(Jump *s) { check(s); } - virtual void visitCJump(CJump *s) { check(s); s->cond->accept(this); } - virtual void visitRet(Ret *s) { check(s); s->expr->accept(this); } - virtual void visitPhi(Phi *s) + private: + void visit(Stmt *s) { check(s); - s->targetTemp->accept(this); - foreach (Expr *e, s->incoming) - e->accept(this); - } - - virtual void visitConst(Const *e) { check(e); } - virtual void visitString(IR::String *e) { check(e); } - virtual void visitRegExp(IR::RegExp *e) { check(e); } - virtual void visitName(Name *e) { check(e); } - virtual void visitTemp(Temp *e) { check(e); } - virtual void visitArgLocal(ArgLocal *e) { check(e); } - virtual void visitClosure(Closure *e) { check(e); } - virtual void visitConvert(Convert *e) { check(e); e->expr->accept(this); } - virtual void visitUnop(Unop *e) { check(e); e->expr->accept(this); } - virtual void visitBinop(Binop *e) { check(e); e->left->accept(this); e->right->accept(this); } - virtual void visitCall(Call *e) { check(e); e->base->accept(this); check(e->args); } - virtual void visitNew(New *e) { check(e); e->base->accept(this); check(e->args); } - virtual void visitSubscript(Subscript *e) { check(e); e->base->accept(this); e->index->accept(this); } - virtual void visitMember(Member *e) { check(e); e->base->accept(this); } - - void check(ExprList *l) + STMT_VISIT_ALL_KINDS(s); + } + + void visit(Expr *e) { - for (ExprList *it = l; it; it = it->next) - check(it->expr); + check(e); + EXPR_VISIT_ALL_KINDS(e); } private: @@ -4836,7 +4893,7 @@ static void verifyNoPointerSharing(IR::Function *function) V(function); } -class RemoveLineNumbers: public SideEffectsChecker, public StmtVisitor +class RemoveLineNumbers: private SideEffectsChecker { public: static void run(IR::Function *function) @@ -4854,19 +4911,27 @@ public: } private: + ~RemoveLineNumbers() {} + static bool hasSideEffects(Stmt *stmt) { RemoveLineNumbers checker; - stmt->accept(&checker); + if (auto e = stmt->asExp()) { + checker.visit(e->expr); + } else if (auto m = stmt->asMove()) { + checker.visit(m->source); + if (!checker.seenSideEffects()) { + checker.visit(m->target); + } + } else if (auto c = stmt->asCJump()) { + checker.visit(c->cond); + } else if (auto r = stmt->asRet()) { + checker.visit(r->expr); + } return checker.seenSideEffects(); } - void visitExp(Exp *s) Q_DECL_OVERRIDE { s->expr->accept(this); } - void visitMove(Move *s) Q_DECL_OVERRIDE { s->source->accept(this); s->target->accept(this); } - void visitJump(Jump *) Q_DECL_OVERRIDE {} - void visitCJump(CJump *s) Q_DECL_OVERRIDE { s->cond->accept(this); } - void visitRet(Ret *s) Q_DECL_OVERRIDE { s->expr->accept(this); } - void visitPhi(Phi *) Q_DECL_OVERRIDE {} + void visitTemp(Temp *) Q_DECL_OVERRIDE Q_DECL_FINAL {} }; } // anonymous namespace diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 1f5a247a17..d3c624ff60 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -354,7 +354,7 @@ void InstructionSelection::run(int functionIndex) lastLine = s->location.startLine; } } - s->accept(this); + visit(s); } } diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index 6b5b79e458..45c596985d 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -87,7 +87,7 @@ public: {} protected: - void addStmtNr(Stmt *s) + void addStmtNr(Stmt *s) Q_DECL_OVERRIDE Q_DECL_FINAL { addJustifiedNr(intervals->positionForStatement(s)); } @@ -115,7 +115,7 @@ public: } protected: - void visitTemp(Temp *e) + void visitTemp(Temp *e) Q_DECL_OVERRIDE Q_DECL_FINAL { switch (e->kind) { case Temp::PhysicalRegister: { @@ -184,7 +184,7 @@ public: _currentBB = bb; for (Stmt *s : bb->statements()) { _currentStmt = s; - s->accept(this); + visit(s); } } } @@ -809,7 +809,8 @@ using namespace QT_PREPEND_NAMESPACE(QV4::IR); using namespace QT_PREPEND_NAMESPACE(QV4); namespace { -class ResolutionPhase: protected StmtVisitor, protected ExprVisitor { +class ResolutionPhase +{ Q_DISABLE_COPY(ResolutionPhase) LifeTimeIntervals::Ptr _intervals; @@ -891,7 +892,7 @@ private: addNewIntervals(usePosition(_currentStmt)); else addNewIntervals(defPosition(_currentStmt)); - _currentStmt->accept(this); + visit(_currentStmt); for (Move *load : _loads) newStatements.append(load); if (_currentStmt->asPhi()) @@ -1178,8 +1179,20 @@ private: return load; } -protected: - virtual void visitTemp(Temp *t) +private: + void visit(Expr *e) + { + switch (e->exprKind) { + case Expr::TempExpr: + visitTemp(e->asTemp()); + break; + default: + EXPR_VISIT_ALL_KINDS(e); + break; + } + } + + void visitTemp(Temp *t) { if (t->kind != Temp::VirtualRegister) return; @@ -1209,47 +1222,25 @@ protected: } } - virtual void visitArgLocal(ArgLocal *) {} - virtual void visitConst(Const *) {} - virtual void visitString(IR::String *) {} - virtual void visitRegExp(IR::RegExp *) {} - virtual void visitName(Name *) {} - virtual void visitClosure(Closure *) {} - virtual void visitConvert(Convert *e) { e->expr->accept(this); } - virtual void visitUnop(Unop *e) { e->expr->accept(this); } - virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); } - virtual void visitSubscript(Subscript *e) { e->base->accept(this); e->index->accept(this); } - virtual void visitMember(Member *e) { e->base->accept(this); } - - virtual void visitCall(Call *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitNew(New *e) { - e->base->accept(this); - for (ExprList *it = e->args; it; it = it->next) - it->expr->accept(this); - } - - virtual void visitExp(Exp *s) { s->expr->accept(this); } - - virtual void visitMove(Move *s) + void visit(Stmt *s) { - if (Temp *t = s->target->asTemp()) - maybeGenerateSpill(t); + switch (s->stmtKind) { + case Stmt::MoveStmt: { + auto m = s->asMove(); + if (Temp *t = m->target->asTemp()) + maybeGenerateSpill(t); - s->source->accept(this); - s->target->accept(this); - } - - virtual void visitJump(Jump *) {} - virtual void visitCJump(CJump *s) { s->cond->accept(this); } - virtual void visitRet(Ret *s) { s->expr->accept(this); } - virtual void visitPhi(Phi *s) - { - maybeGenerateSpill(s->targetTemp); + visit(m->source); + visit(m->target); + } break; + case Stmt::PhiStmt: { + auto p = s->asPhi(); + maybeGenerateSpill(p->targetTemp); + } break; + default: + STMT_VISIT_ALL_KINDS(s); + break; + } } }; } // anonymous namespace |