private:
IR::Function *function;
- QHash<UntypedTemp, DefUse> _defUses;
+ typedef QHash<UntypedTemp, DefUse> DefUses;
+ DefUses _defUses;
QHash<Stmt *, QList<Temp> > _usesPerStatement;
BasicBlock *_block;
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)
{
QSet<Stmt *> removed;
QHash<Stmt*,Stmt*> replaced;
+ Q_DISABLE_COPY(StatementWorklist)
+
public:
StatementWorklist(IR::Function *function)
{
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;
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;
#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)) {
}
#endif
- _worklist += QSet<Stmt *>::fromList(_defUses.uses(*t));
+ _worklist += _defUses.uses(*t);
}
} else {
e->type = (Type) ty.type;
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;
, _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());
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:
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;
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);
// constant propagation:
if (Const *sourceConst = m->source->asConst()) {
- W += replaceUses(targetTemp, sourceConst);
+ replaceUses(targetTemp, sourceConst, W);
defUses.removeDef(*targetTemp);
W.clear(s);
continue;
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());
// 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;
void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
{
+ _lastAssignedRegister.reserve(function->tempCount);
+ _assignedSpillSlots.reserve(function->tempCount);
_activeSpillSlots.resize(function->tempCount);
#ifdef DEBUG_REGALLOC
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;
}
// 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;
// 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;
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;