diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-06-27 13:40:24 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-07-23 11:59:44 +0200 |
commit | 07bee265d7ee4d0e8874697b488b249d79110298 (patch) | |
tree | e9851fdfa27ded324e7a94df1e4f083f5b253aa0 /src | |
parent | 661649edf1cd0448b4276fbf6e0a97fd5ec8c792 (diff) |
V4 IR: copy arguments to temps at function start.
When arguments cannot "escape" from the current context, and when the
arguments array is not used, actual arguments can be treated the same
as temporaries instead of memory locations. This has the benefits that
they are subject to the same optimizations, and type deduction can
assume that the value/type didn't change since its assignment. Another
effect is that the values can be kept in registers, and loads from the
stack take only 1 indirect load instead of 2 (from the formals array).
Change-Id: I209da7991ec5d903b3c5acdbcaf6b1cc67502520
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-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); |