diff options
author | Erik Verbruggen <[email protected]> | 2014-01-15 14:36:37 +0100 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-01-16 09:57:42 +0100 |
commit | 1ac728b7601dd5fee2fee7ea714f0626055384df (patch) | |
tree | 5de8b3afb61dac104f1070942978ba9745ea9dc6 /src/qml/compiler/qv4ssa.cpp | |
parent | a1b64d9566a49d287a8fad122859e8a99ad92151 (diff) |
V4: remove unnecessary spills and order them correctly.
When doing edge resolving, too many spills were generated, and the
dependency tracking of moves was not complete. Now we only insert spills
that are caused by phi-nodes (because any other spill would be generated
at the point a variable was defined). However, there can still be
multiple dependencies between the moves generated by the edge resolving.
Instead of only checking the first dependency, all of them are tracked.
The bug report was a case where an unneccesary spill was generated, that
got tracked, but "suppressed" the other (valid!) dependent move. The
randomness was caused by the hash seeding of QHash.
Task-number: QTBUG-35840
Change-Id: Ifbc3c8fc13de53c46a8b5859721b2497189921a3
Reviewed-by: Fawzi Mohamed <[email protected]>
Reviewed-by: Simon Hausmann <[email protected]>
Diffstat (limited to 'src/qml/compiler/qv4ssa.cpp')
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 31a1e4cdc4..a668375da0 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -3837,15 +3837,20 @@ static inline bool overlappingStorage(const Temp &t1, const Temp &t2) || (t1.type != DoubleType && t2.type != DoubleType); } -int MoveMapping::isUsedAsSource(Expr *e) const +MoveMapping::Moves MoveMapping::sourceUsages(Expr *e, const Moves &moves) { - if (Temp *t = e->asTemp()) - for (int i = 0, ei = _moves.size(); i != ei; ++i) - if (Temp *from = _moves[i].from->asTemp()) + Moves usages; + + if (Temp *t = e->asTemp()) { + for (int i = 0, ei = moves.size(); i != ei; ++i) { + const Move &move = moves[i]; + if (Temp *from = move.from->asTemp()) if (overlappingStorage(*from, *t)) - return i; + usages.append(move); + } + } - return -1; + return usages; } void MoveMapping::add(Expr *from, Temp *to, int id) { @@ -3924,9 +3929,8 @@ void MoveMapping::dump() const MoveMapping::Action MoveMapping::schedule(const Move &m, QList<Move> &todo, QList<Move> &delayed, QList<Move> &output, QList<Move> &swaps) const { - int useIdx = isUsedAsSource(m.to); - if (useIdx != -1) { - const Move &dependency = _moves[useIdx]; + Moves usages = sourceUsages(m.to, todo) + sourceUsages(m.to, delayed); + foreach (const Move &dependency, usages) { if (!output.contains(dependency)) { if (delayed.contains(dependency)) { // We have a cycle! Break it by swapping instead of assigning. |