diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-04-15 15:30:12 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-04-30 15:01:24 +0200 |
commit | a719ccf476273f17bf72dbf0909a7663fe64f2b0 (patch) | |
tree | 69d6c09044b4fb9fcec96579b81b547a3aa86e11 /src/qml | |
parent | cedd581762db0f100b167c5ec1865541aa743cae (diff) |
V4 IR: more copy removal.
Change-Id: Ie86bf5902328ad105fb07eb3e2809db21ff024d9
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 76 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa_p.h | 5 | ||||
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 11 |
3 files changed, 55 insertions, 37 deletions
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 10988bffa6..0308daa34a 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -1278,7 +1278,8 @@ public: private: IR::Function *function; - QHash<UntypedTemp, DefUse> _defUses; + typedef QHash<UntypedTemp, DefUse> DefUses; + DefUses _defUses; QHash<Stmt *, QList<Temp> > _usesPerStatement; BasicBlock *_block; @@ -1374,8 +1375,16 @@ public: QList<Temp> usedVars(Stmt *s) const { return _usesPerStatement[s]; } - QList<Stmt *> uses(const UntypedTemp &var) const - { return _defUses[var].uses; } + const QList<Stmt *> &uses(const UntypedTemp &var) const + { + static const QList<Stmt *> noUses; + + DefUses::const_iterator it = _defUses.find(var); + if (it == _defUses.end()) + return noUses; + else + return it->uses; + } QVector<Stmt*> removeDefUses(Stmt *s) { @@ -1507,6 +1516,8 @@ class StatementWorklist QSet<Stmt *> removed; QHash<Stmt*,Stmt*> replaced; + Q_DISABLE_COPY(StatementWorklist) + public: StatementWorklist(IR::Function *function) { @@ -1873,8 +1884,9 @@ class TypeInference: public StmtVisitor, public ExprVisitor { QQmlEnginePrivate *qmlEngine; IR::Function *function; const DefUsesCalculator &_defUses; - QHash<Temp, DiscoveredType> _tempTypes; - QSet<Stmt *> _worklist; + typedef QHash<Temp, DiscoveredType> TempTypes; + TempTypes _tempTypes; + QList<Stmt *> _worklist; struct TypingResult { DiscoveredType type; bool fullyTyped; @@ -1901,23 +1913,24 @@ public: if (bb->isRemoved()) continue; if (i == 0 || !bb->in.isEmpty()) - foreach (Stmt *s, bb->statements()) - if (!s->asJump()) - _worklist.insert(s); + _worklist += bb->statements().toList(); } while (!_worklist.isEmpty()) { - QList<Stmt *> worklist = _worklist.values(); + QList<Stmt *> worklist = QSet<Stmt *>::fromList(_worklist).toList(); _worklist.clear(); while (!worklist.isEmpty()) { Stmt *s = worklist.first(); worklist.removeFirst(); + if (s->asJump()) + continue; + #if defined(SHOW_SSA) qout<<"Typing stmt ";s->dump(qout);qout<<endl; #endif if (!run(s)) { - _worklist.insert(s); + _worklist += s; #if defined(SHOW_SSA) qout<<"Pushing back stmt: "; s->dump(qout);qout<<endl; @@ -1968,8 +1981,11 @@ private: #endif if (isAlwaysVar(t)) ty = DiscoveredType(VarType); - if (_tempTypes[*t] != ty) { - _tempTypes[*t] = ty; + TempTypes::iterator it = _tempTypes.find(*t); + if (it == _tempTypes.end()) + it = _tempTypes.insert(*t, DiscoveredType()); + if (it.value() != ty) { + it.value() = ty; #if defined(SHOW_SSA) foreach (Stmt *s, _defUses.uses(*t)) { @@ -1979,7 +1995,7 @@ private: } #endif - _worklist += QSet<Stmt *>::fromList(_defUses.uses(*t)); + _worklist += _defUses.uses(*t); } } else { e->type = (Type) ty.type; @@ -2269,7 +2285,7 @@ public: private: bool isUsedAsInt32(const UntypedTemp &t, const QVector<UntypedTemp> &knownOk) const { - QList<Stmt *> uses = _defUses.uses(t); + const QList<Stmt *> &uses = _defUses.uses(t); if (uses.isEmpty()) return false; @@ -2924,7 +2940,7 @@ public: , _replacement(0) {} - QVector<Stmt *> operator()(Temp *toReplace, Expr *replacement) + void operator()(Temp *toReplace, Expr *replacement, StatementWorklist &W, QList<Stmt *> *newUses = 0) { Q_ASSERT(replacement->asTemp() || replacement->asConst() || replacement->asName()); @@ -2933,20 +2949,22 @@ public: qSwap(_toReplace, toReplace); qSwap(_replacement, replacement); - QList<Stmt *> uses = _defUses.uses(*_toReplace); + const QList<Stmt *> &uses = _defUses.uses(*_toReplace); + if (newUses) + newUses->reserve(uses.size()); + // qout << " " << uses.size() << " uses:"<<endl; - QVector<Stmt *> result; - result.reserve(uses.size()); foreach (Stmt *use, uses) { // qout<<" ";use->dump(qout);qout<<"\n"; use->accept(this); // qout<<" -> ";use->dump(qout);qout<<"\n"; - result.append(use); + W += use; + if (newUses) + newUses->append(use); } qSwap(_replacement, replacement); qSwap(_toReplace, toReplace); - return result; } protected: @@ -3173,7 +3191,7 @@ void optimizeSSA(IR::Function *function, DefUsesCalculator &defUses, DominatorTr if (Phi *phi = s->asPhi()) { // constant propagation: if (Const *c = isConstPhi(phi)) { - W += replaceUses(phi->targetTemp, c); + replaceUses(phi->targetTemp, c, W); defUses.removeDef(*phi->targetTemp); W.clear(s); continue; @@ -3184,11 +3202,11 @@ void optimizeSSA(IR::Function *function, DefUsesCalculator &defUses, DominatorTr Temp *t = phi->targetTemp; Expr *e = phi->d->incoming.first(); - QVector<Stmt *> newT2Uses = replaceUses(t, e); - W += newT2Uses; + QList<Stmt *> newT2Uses; + replaceUses(t, e, W, &newT2Uses); if (Temp *t2 = e->asTemp()) { defUses.removeUse(s, *t2); - defUses.addUses(*t2, QList<Stmt*>::fromVector(newT2Uses)); + defUses.addUses(*t2, newT2Uses); } defUses.removeDef(*t); W.clear(s); @@ -3233,7 +3251,7 @@ void optimizeSSA(IR::Function *function, DefUsesCalculator &defUses, DominatorTr // constant propagation: if (Const *sourceConst = m->source->asConst()) { - W += replaceUses(targetTemp, sourceConst); + replaceUses(targetTemp, sourceConst, W); defUses.removeDef(*targetTemp); W.clear(s); continue; @@ -3243,7 +3261,7 @@ void optimizeSSA(IR::Function *function, DefUsesCalculator &defUses, DominatorTr Const *c = function->New<Const>(); const int enumValue = member->attachedPropertiesIdOrEnumValue; c->init(SInt32Type, enumValue); - W += replaceUses(targetTemp, c); + replaceUses(targetTemp, c, W); defUses.removeDef(*targetTemp); W.clear(s); defUses.removeUse(s, *member->base->asTemp()); @@ -3261,10 +3279,10 @@ void optimizeSSA(IR::Function *function, DefUsesCalculator &defUses, DominatorTr // copy propagation: if (Temp *sourceTemp = unescapableTemp(m->source, function)) { - QVector<Stmt *> newT2Uses = replaceUses(targetTemp, sourceTemp); - W += newT2Uses; + QList<Stmt *> newT2Uses; + replaceUses(targetTemp, sourceTemp, W, &newT2Uses); defUses.removeUse(s, *sourceTemp); - defUses.addUses(*sourceTemp, QList<Stmt*>::fromVector(newT2Uses)); + defUses.addUses(*sourceTemp, newT2Uses); defUses.removeDef(*targetTemp); W.clear(s); continue; diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index f8fa6c0634..e53573fdd5 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -77,12 +77,12 @@ private: public: enum { Invalid = -1 }; - LifeTimeInterval() + LifeTimeInterval(int rangeCapacity = 2) : _end(Invalid) , _reg(Invalid) , _isFixedInterval(0) , _isSplitFromInterval(0) - { _ranges.reserve(2); } + { _ranges.reserve(rangeCapacity); } bool isValid() const { return _end != Invalid; } @@ -93,7 +93,6 @@ public: void setFrom(Stmt *from); void addRange(int from, int to); const Ranges &ranges() const { return _ranges; } - void reserveRanges(int capacity) { _ranges.reserve(capacity); } int start() const { return _ranges.first().start; } int end() const { return _end; } diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index 5893bbc3dd..c1b39a4ff4 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -1085,6 +1085,8 @@ RegisterAllocator::~RegisterAllocator() void RegisterAllocator::run(IR::Function *function, const Optimizer &opt) { + _lastAssignedRegister.reserve(function->tempCount); + _assignedSpillSlots.reserve(function->tempCount); _activeSpillSlots.resize(function->tempCount); #ifdef DEBUG_REGALLOC @@ -1141,11 +1143,10 @@ static inline LifeTimeInterval createFixedInterval(int reg, bool isFP, int range Temp t; t.init(Temp::PhysicalRegister, reg, 0); t.type = isFP ? IR::DoubleType : IR::SInt32Type; - LifeTimeInterval i; + LifeTimeInterval i(rangeCount); i.setTemp(t); i.setReg(reg); i.setFixedInterval(true); - i.reserveRanges(rangeCount); return i; } @@ -1187,7 +1188,7 @@ void RegisterAllocator::linearScan() // check for intervals in active that are handled or inactive for (int i = 0; i < _active.size(); ) { - const LifeTimeInterval &it = _active[i]; + const LifeTimeInterval &it = _active.at(i); if (it.end() < position) { if (!it.isFixedInterval()) _handled += it; @@ -1202,7 +1203,7 @@ void RegisterAllocator::linearScan() // check for intervals in inactive that are handled or active for (int i = 0; i < _inactive.size(); ) { - LifeTimeInterval &it = _inactive[i]; + const LifeTimeInterval &it = _inactive.at(i); if (it.end() < position) { if (!it.isFixedInterval()) _handled += it; @@ -1604,7 +1605,7 @@ void RegisterAllocator::assignSpillSlot(const Temp &t, int startPos, int endPos) return; for (int i = 0, ei = _activeSpillSlots.size(); i != ei; ++i) { - if (_activeSpillSlots[i] < startPos) { + if (_activeSpillSlots.at(i) < startPos) { _activeSpillSlots[i] = endPos; _assignedSpillSlots.insert(t, i); return; |