diff options
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 8 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 39 |
3 files changed, 48 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 5bebfb3caf..4b26ff20b7 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -771,6 +771,14 @@ void BasicBlock::prependStatement(Stmt *stmt) _statements.prepend(stmt); } +void BasicBlock::prependStatements(const QVector<Stmt *> &stmts) +{ + Q_ASSERT(!isRemoved()); + QVector<Stmt *> newStmts = stmts; + newStmts += _statements; + _statements = newStmts; +} + void BasicBlock::insertStatementBefore(Stmt *before, Stmt *newStmt) { int idx = _statements.indexOf(before); diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 4bff15ddce..606313d0c1 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -820,6 +820,7 @@ public: void appendStatement(Stmt *statement); void prependStatement(Stmt *stmt); + void prependStatements(const QVector<Stmt *> &stmts); void insertStatementBefore(Stmt *before, Stmt *newStmt); void insertStatementBefore(int index, Stmt *newStmt); void insertStatementBeforeTerminator(Stmt *stmt); diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index eb9e818bac..8e6fa35d1f 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -3944,7 +3944,9 @@ class ConvertArgLocals: protected StmtVisitor, protected ExprVisitor public: ConvertArgLocals(IR::Function *function) : function(function) + , convertArgs(!function->usesArgumentsObject) { + tempForFormal.resize(function->formals.size(), -1); tempForLocal.resize(function->locals.size(), -1); } @@ -3953,11 +3955,36 @@ public: if (function->variablesCanEscape()) return; + QVector<Stmt *> extraMoves; + if (convertArgs) { + const int formalCount = function->formals.size(); + extraMoves.reserve(formalCount + function->basicBlock(0)->statementCount()); + extraMoves.resize(formalCount); + + for (int i = 0; i != formalCount; ++i) { + const int newTemp = function->tempCount++; + tempForFormal[i] = newTemp; + + ArgLocal *source = function->New<ArgLocal>(); + source->init(ArgLocal::Formal, i, 0); + + Temp *target = function->New<Temp>(); + target->init(Temp::VirtualRegister, newTemp); + + Move *m = function->NewStmt<Move>(); + m->init(target, source); + extraMoves[i] = m; + } + } + foreach (BasicBlock *bb, function->basicBlocks()) if (!bb->isRemoved()) foreach (Stmt *s, bb->statements()) s->accept(this); + if (convertArgs && function->formals.size() > 0) + function->basicBlock(0)->prependStatements(extraMoves); + function->locals.clear(); } @@ -4000,6 +4027,10 @@ private: Temp *t = function->New<Temp>(); t->init(Temp::VirtualRegister, fetchTempForLocal(al->index)); e = t; + } else if (convertArgs && al->kind == ArgLocal::Formal) { + Temp *t = function->New<Temp>(); + t->init(Temp::VirtualRegister, fetchTempForFormal(al->index)); + e = t; } } else { e->accept(this); @@ -4014,7 +4045,14 @@ private: return ref; } + int fetchTempForFormal(int formal) + { + return tempForFormal[formal]; + } + IR::Function *function; + bool convertArgs; + std::vector<int> tempForFormal; std::vector<int> tempForLocal; }; } // anonymous namespace @@ -4252,6 +4290,7 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine) // qout << "SSA for " << (function->name ? qPrintable(*function->name) : "<anonymous>") << endl; ConvertArgLocals(function).toTemps(); + showMeTheCode(function); // Calculate the dominator tree: DominatorTree df(function); |