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/qml/compiler/qv4ssa.cpp | |
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/qml/compiler/qv4ssa.cpp')
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
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); |