aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-06-27 13:40:24 +0200
committerErik Verbruggen <erik.verbruggen@digia.com>2014-07-23 11:59:44 +0200
commit07bee265d7ee4d0e8874697b488b249d79110298 (patch)
treee9851fdfa27ded324e7a94df1e4f083f5b253aa0 /src
parent661649edf1cd0448b4276fbf6e0a97fd5ec8c792 (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.cpp8
-rw-r--r--src/qml/compiler/qv4jsir_p.h1
-rw-r--r--src/qml/compiler/qv4ssa.cpp39
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);