aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2014-04-15 15:30:12 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-30 15:01:24 +0200
commita719ccf476273f17bf72dbf0909a7663fe64f2b0 (patch)
tree69d6c09044b4fb9fcec96579b81b547a3aa86e11 /src/qml
parentcedd581762db0f100b167c5ec1865541aa743cae (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.cpp76
-rw-r--r--src/qml/compiler/qv4ssa_p.h5
-rw-r--r--src/qml/jit/qv4regalloc.cpp11
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;