aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4regalloc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jit/qv4regalloc.cpp')
-rw-r--r--src/qml/jit/qv4regalloc.cpp284
1 files changed, 148 insertions, 136 deletions
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index 6b5b79e458..63d542b5c8 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -87,7 +87,7 @@ public:
{}
protected:
- void addStmtNr(Stmt *s)
+ void addStmtNr(Stmt *s) Q_DECL_OVERRIDE Q_DECL_FINAL
{
addJustifiedNr(intervals->positionForStatement(s));
}
@@ -115,7 +115,7 @@ public:
}
protected:
- void visitTemp(Temp *e)
+ void visitTemp(Temp *e) Q_DECL_OVERRIDE Q_DECL_FINAL
{
switch (e->kind) {
case Temp::PhysicalRegister: {
@@ -184,7 +184,7 @@ public:
_currentBB = bb;
for (Stmt *s : bb->statements()) {
_currentStmt = s;
- s->accept(this);
+ visit(s);
}
}
}
@@ -272,32 +272,32 @@ public:
}
protected: // IRDecoder
- virtual void callBuiltinInvalid(IR::Name *, IR::ExprList *, IR::Expr *) {}
- virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *, IR::Member::MemberKind, int, IR::Expr *) {}
- virtual void callBuiltinTypeofMember(IR::Expr *, const QString &, IR::Expr *) {}
- virtual void callBuiltinTypeofSubscript(IR::Expr *, IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinTypeofName(const QString &, IR::Expr *) {}
- virtual void callBuiltinTypeofValue(IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinDeleteMember(IR::Expr *, const QString &, IR::Expr *) {}
- virtual void callBuiltinDeleteSubscript(IR::Expr *, IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinDeleteName(const QString &, IR::Expr *) {}
- virtual void callBuiltinDeleteValue(IR::Expr *) {}
- virtual void callBuiltinThrow(IR::Expr *) {}
- virtual void callBuiltinReThrow() {}
- virtual void callBuiltinUnwindException(IR::Expr *) {}
- virtual void callBuiltinPushCatchScope(const QString &) {};
- virtual void callBuiltinForeachIteratorObject(IR::Expr *, IR::Expr *) {}
+ void callBuiltinInvalid(IR::Name *, IR::ExprList *, IR::Expr *) override {}
+ void callBuiltinTypeofQmlContextProperty(IR::Expr *, IR::Member::MemberKind, int, IR::Expr *) override {}
+ void callBuiltinTypeofMember(IR::Expr *, const QString &, IR::Expr *) override {}
+ void callBuiltinTypeofSubscript(IR::Expr *, IR::Expr *, IR::Expr *) override {}
+ void callBuiltinTypeofName(const QString &, IR::Expr *) override {}
+ void callBuiltinTypeofValue(IR::Expr *, IR::Expr *) override {}
+ void callBuiltinDeleteMember(IR::Expr *, const QString &, IR::Expr *) override {}
+ void callBuiltinDeleteSubscript(IR::Expr *, IR::Expr *, IR::Expr *) override {}
+ void callBuiltinDeleteName(const QString &, IR::Expr *) override {}
+ void callBuiltinDeleteValue(IR::Expr *) override {}
+ void callBuiltinThrow(IR::Expr *) override {}
+ void callBuiltinReThrow() override {}
+ void callBuiltinUnwindException(IR::Expr *) override {}
+ void callBuiltinPushCatchScope(const QString &) override {};
+ void callBuiltinForeachIteratorObject(IR::Expr *, IR::Expr *) override {}
virtual void callBuiltinForeachNextProperty(IR::Temp *, IR::Temp *) {}
- virtual void callBuiltinForeachNextPropertyname(IR::Expr *, IR::Expr *) {}
- virtual void callBuiltinPushWithScope(IR::Expr *) {}
- virtual void callBuiltinPopScope() {}
- virtual void callBuiltinDeclareVar(bool , const QString &) {}
- virtual void callBuiltinDefineArray(IR::Expr *, IR::ExprList *) {}
- virtual void callBuiltinDefineObjectLiteral(IR::Expr *, int, IR::ExprList *, IR::ExprList *, bool) {}
- virtual void callBuiltinSetupArgumentObject(IR::Expr *) {}
- virtual void callBuiltinConvertThisToObject() {}
+ void callBuiltinForeachNextPropertyname(IR::Expr *, IR::Expr *) override {}
+ void callBuiltinPushWithScope(IR::Expr *) override {}
+ void callBuiltinPopScope() override {}
+ void callBuiltinDeclareVar(bool , const QString &) override {}
+ void callBuiltinDefineArray(IR::Expr *, IR::ExprList *) override {}
+ void callBuiltinDefineObjectLiteral(IR::Expr *, int, IR::ExprList *, IR::ExprList *, bool) override {}
+ void callBuiltinSetupArgumentObject(IR::Expr *) override {}
+ void callBuiltinConvertThisToObject() override {}
- virtual void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
+ void callValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
if (IR::Temp *tempValue = value->asTemp())
@@ -306,7 +306,8 @@ protected: // IRDecoder
addCall();
}
- virtual void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int propertyIndex, IR::ExprList *args, IR::Expr *result)
+ void callQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int propertyIndex,
+ IR::ExprList *args, IR::Expr *result) override
{
Q_UNUSED(propertyIndex)
@@ -316,8 +317,8 @@ protected: // IRDecoder
addCall();
}
- virtual void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
- IR::Expr *result)
+ void callProperty(IR::Expr *base, const QString &name, IR::ExprList *args,
+ IR::Expr *result) override
{
Q_UNUSED(name)
@@ -327,8 +328,8 @@ protected: // IRDecoder
addCall();
}
- virtual void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
- IR::Expr *result)
+ void callSubscript(IR::Expr *base, IR::Expr *index, IR::ExprList *args,
+ IR::Expr *result) override
{
addDef(result);
addUses(base->asTemp(), Use::CouldHaveRegister);
@@ -337,7 +338,7 @@ protected: // IRDecoder
addCall();
}
- virtual void convertType(IR::Expr *source, IR::Expr *target)
+ void convertType(IR::Expr *source, IR::Expr *target) override
{
addDef(target);
@@ -410,14 +411,14 @@ protected: // IRDecoder
addHint(target->asTemp(), sourceTemp);
}
- virtual void constructActivationProperty(IR::Name *, IR::ExprList *args, IR::Expr *result)
+ void constructActivationProperty(IR::Name *, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
addUses(args, Use::CouldHaveRegister);
addCall();
}
- virtual void constructProperty(IR::Expr *base, const QString &, IR::ExprList *args, IR::Expr *result)
+ void constructProperty(IR::Expr *base, const QString &, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
addUses(base, Use::CouldHaveRegister);
@@ -425,7 +426,7 @@ protected: // IRDecoder
addCall();
}
- virtual void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result)
+ void constructValue(IR::Expr *value, IR::ExprList *args, IR::Expr *result) override
{
addDef(result);
addUses(value, Use::CouldHaveRegister);
@@ -433,24 +434,24 @@ protected: // IRDecoder
addCall();
}
- virtual void loadThisObject(IR::Expr *temp)
+ void loadThisObject(IR::Expr *temp) override
{
addDef(temp);
}
- virtual void loadQmlContext(IR::Expr *temp)
+ void loadQmlContext(IR::Expr *temp) override
{
addDef(temp);
addCall();
}
- virtual void loadQmlImportedScripts(IR::Expr *temp)
+ void loadQmlImportedScripts(IR::Expr *temp) override
{
addDef(temp);
addCall();
}
- virtual void loadQmlSingleton(const QString &/*name*/, Expr *temp)
+ void loadQmlSingleton(const QString &/*name*/, Expr *temp) override
{
Q_UNUSED(temp);
@@ -458,21 +459,21 @@ protected: // IRDecoder
addCall();
}
- virtual void loadConst(IR::Const *sourceConst, Expr *targetTemp)
+ void loadConst(IR::Const *sourceConst, Expr *targetTemp) override
{
Q_UNUSED(sourceConst);
addDef(targetTemp);
}
- virtual void loadString(const QString &str, Expr *targetTemp)
+ void loadString(const QString &str, Expr *targetTemp) override
{
Q_UNUSED(str);
addDef(targetTemp);
}
- virtual void loadRegexp(IR::RegExp *sourceRegexp, Expr *targetTemp)
+ void loadRegexp(IR::RegExp *sourceRegexp, Expr *targetTemp) override
{
Q_UNUSED(sourceRegexp);
@@ -480,19 +481,19 @@ protected: // IRDecoder
addCall();
}
- virtual void getActivationProperty(const IR::Name *, Expr *temp)
+ void getActivationProperty(const IR::Name *, Expr *temp) override
{
addDef(temp);
addCall();
}
- virtual void setActivationProperty(IR::Expr *source, const QString &)
+ void setActivationProperty(IR::Expr *source, const QString &) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void initClosure(IR::Closure *closure, Expr *target)
+ void initClosure(IR::Closure *closure, Expr *target) override
{
Q_UNUSED(closure);
@@ -500,49 +501,52 @@ protected: // IRDecoder
addCall();
}
- virtual void getProperty(IR::Expr *base, const QString &, Expr *target)
+ void getProperty(IR::Expr *base, const QString &, Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &)
+ void setProperty(IR::Expr *source, IR::Expr *targetBase, const QString &) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase, IR::Member::MemberKind /*kind*/, int /*propertyIndex*/)
+ void setQmlContextProperty(IR::Expr *source, IR::Expr *targetBase,
+ IR::Member::MemberKind /*kind*/, int /*propertyIndex*/) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int /*propertyIndex*/)
+ void setQObjectProperty(IR::Expr *source, IR::Expr *targetBase, int /*propertyIndex*/) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, QQmlPropertyData * /*property*/, int /*index*/, IR::Expr *target)
+ void getQmlContextProperty(IR::Expr *base, IR::Member::MemberKind /*kind*/, int /*index*/,
+ bool /*captureRequired*/, IR::Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void getQObjectProperty(IR::Expr *base, QQmlPropertyData * /*property*/, bool /*captureRequired*/, bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target)
+ void getQObjectProperty(IR::Expr *base, int /*propertyIndex*/, bool /*captureRequired*/,
+ bool /*isSingleton*/, int /*attachedPropertiesId*/, IR::Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
addCall();
}
- virtual void getElement(IR::Expr *base, IR::Expr *index, Expr *target)
+ void getElement(IR::Expr *base, IR::Expr *index, Expr *target) override
{
addDef(target);
addUses(base->asTemp(), Use::CouldHaveRegister);
@@ -550,7 +554,7 @@ protected: // IRDecoder
addCall();
}
- virtual void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex)
+ void setElement(IR::Expr *source, IR::Expr *targetBase, IR::Expr *targetIndex) override
{
addUses(source->asTemp(), Use::CouldHaveRegister);
addUses(targetBase->asTemp(), Use::CouldHaveRegister);
@@ -558,7 +562,7 @@ protected: // IRDecoder
addCall();
}
- virtual void copyValue(Expr *source, Expr *target)
+ void copyValue(Expr *source, Expr *target) override
{
addDef(target);
Temp *sourceTemp = source->asTemp();
@@ -570,13 +574,13 @@ protected: // IRDecoder
addHint(targetTemp, sourceTemp);
}
- virtual void swapValues(Expr *, Expr *)
+ void swapValues(Expr *, Expr *) override
{
// Inserted by the register allocator, so it cannot occur here.
Q_UNREACHABLE();
}
- virtual void unop(AluOp oper, Expr *source, Expr *target)
+ void unop(AluOp oper, Expr *source, Expr *target) override
{
addDef(target);
@@ -612,7 +616,7 @@ protected: // IRDecoder
}
}
- virtual void binop(AluOp oper, Expr *leftSource, Expr *rightSource, Expr *target)
+ void binop(AluOp oper, Expr *leftSource, Expr *rightSource, Expr *target) override
{
bool needsCall = true;
@@ -675,8 +679,8 @@ protected: // IRDecoder
}
}
- virtual void visitJump(IR::Jump *) {}
- virtual void visitCJump(IR::CJump *s)
+ void visitJump(IR::Jump *) override {}
+ void visitCJump(IR::CJump *s) override
{
if (Temp *t = s->cond->asTemp()) {
#if 0 // TODO: change masm to generate code
@@ -696,10 +700,10 @@ protected: // IRDecoder
}
}
- virtual void visitRet(IR::Ret *s)
+ void visitRet(IR::Ret *s) override
{ addUses(s->expr->asTemp(), Use::CouldHaveRegister); }
- virtual void visitPhi(IR::Phi *s)
+ void visitPhi(IR::Phi *s) override
{
addDef(s->targetTemp, true);
for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
@@ -716,7 +720,7 @@ protected: // IRDecoder
}
protected:
- virtual void callBuiltin(IR::Call *c, IR::Expr *result)
+ void callBuiltin(IR::Call *c, IR::Expr *result) override
{
addDef(result);
addUses(c->base, Use::CouldHaveRegister);
@@ -809,14 +813,15 @@ using namespace QT_PREPEND_NAMESPACE(QV4::IR);
using namespace QT_PREPEND_NAMESPACE(QV4);
namespace {
-class ResolutionPhase: protected StmtVisitor, protected ExprVisitor {
+class ResolutionPhase
+{
Q_DISABLE_COPY(ResolutionPhase)
LifeTimeIntervals::Ptr _intervals;
- QVector<LifeTimeInterval *> _unprocessed;
+ QVector<LifeTimeInterval *> _unprocessedReverseOrder;
IR::Function *_function;
const std::vector<int> &_assignedSpillSlots;
- QHash<IR::Temp, const LifeTimeInterval *> _intervalForTemp;
+ std::vector<const LifeTimeInterval *> _liveIntervals;
const QVector<const RegisterInfo *> &_intRegs;
const QVector<const RegisterInfo *> &_fpRegs;
@@ -824,25 +829,26 @@ class ResolutionPhase: protected StmtVisitor, protected ExprVisitor {
std::vector<Move *> _loads;
std::vector<Move *> _stores;
- QHash<BasicBlock *, QList<const LifeTimeInterval *> > _liveAtStart;
- QHash<BasicBlock *, QList<const LifeTimeInterval *> > _liveAtEnd;
+ std::vector<std::vector<const LifeTimeInterval *> > _liveAtStart;
+ std::vector<std::vector<const LifeTimeInterval *> > _liveAtEnd;
public:
- ResolutionPhase(const QVector<LifeTimeInterval *> &unprocessed,
+ ResolutionPhase(QVector<LifeTimeInterval *> &&unprocessedReversedOrder,
const LifeTimeIntervals::Ptr &intervals,
IR::Function *function,
const std::vector<int> &assignedSpillSlots,
const QVector<const RegisterInfo *> &intRegs,
const QVector<const RegisterInfo *> &fpRegs)
: _intervals(intervals)
+ , _unprocessedReverseOrder(unprocessedReversedOrder)
, _function(function)
, _assignedSpillSlots(assignedSpillSlots)
, _intRegs(intRegs)
, _fpRegs(fpRegs)
+ , _currentStmt(0)
{
- _unprocessed = unprocessed;
- _liveAtStart.reserve(function->basicBlockCount());
- _liveAtEnd.reserve(function->basicBlockCount());
+ _liveAtStart.resize(function->basicBlockCount());
+ _liveAtEnd.resize(function->basicBlockCount());
}
void run() {
@@ -881,7 +887,7 @@ private:
cleanOldIntervals(_intervals->startPosition(bb));
addNewIntervals(_intervals->startPosition(bb));
- _liveAtStart[bb] = _intervalForTemp.values();
+ _liveAtStart[bb->index()] = _liveIntervals;
for (int i = 0, ei = statements.size(); i != ei; ++i) {
_currentStmt = statements.at(i);
@@ -891,7 +897,7 @@ private:
addNewIntervals(usePosition(_currentStmt));
else
addNewIntervals(defPosition(_currentStmt));
- _currentStmt->accept(this);
+ visit(_currentStmt);
for (Move *load : _loads)
newStatements.append(load);
if (_currentStmt->asPhi())
@@ -903,24 +909,24 @@ private:
}
cleanOldIntervals(_intervals->endPosition(bb));
- _liveAtEnd[bb] = _intervalForTemp.values();
+ _liveAtEnd[bb->index()] = _liveIntervals;
if (DebugRegAlloc) {
QBuffer buf;
buf.open(QIODevice::WriteOnly);
QTextStream os(&buf);
os << "Intervals live at the start of L" << bb->index() << ":" << endl;
- if (_liveAtStart[bb].isEmpty())
+ if (_liveAtStart[bb->index()].empty())
os << "\t(none)" << endl;
- for (const LifeTimeInterval *i : _liveAtStart.value(bb)) {
+ for (const LifeTimeInterval *i : _liveAtStart.at(bb->index())) {
os << "\t";
i->dump(os);
os << endl;
}
os << "Intervals live at the end of L" << bb->index() << ":" << endl;
- if (_liveAtEnd[bb].isEmpty())
+ if (_liveAtEnd[bb->index()].empty())
os << "\t(none)" << endl;
- for (const LifeTimeInterval *i : _liveAtEnd.value(bb)) {
+ for (const LifeTimeInterval *i : _liveAtEnd.at(bb->index())) {
os << "\t";
i->dump(os);
os << endl;
@@ -933,9 +939,19 @@ private:
}
+ const LifeTimeInterval *findLiveInterval(Temp *t) const
+ {
+ for (const LifeTimeInterval *lti : _liveIntervals) {
+ if (lti->temp() == *t)
+ return lti;
+ }
+
+ return nullptr;
+ }
+
void maybeGenerateSpill(Temp *t)
{
- const LifeTimeInterval *i = _intervalForTemp[*t];
+ const LifeTimeInterval *i = findLiveInterval(t);
if (i->reg() == LifeTimeInterval::InvalidRegister)
return;
@@ -951,26 +967,27 @@ private:
if (position == Stmt::InvalidId)
return;
- while (!_unprocessed.isEmpty()) {
- const LifeTimeInterval *i = _unprocessed.constFirst();
+ while (!_unprocessedReverseOrder.isEmpty()) {
+ const LifeTimeInterval *i = _unprocessedReverseOrder.constLast();
if (i->start() > position)
break;
Q_ASSERT(!i->isFixedInterval());
- _intervalForTemp[i->temp()] = i;
+ _liveIntervals.push_back(i);
// qDebug() << "-- Activating interval for temp" << i->temp().index;
- _unprocessed.removeFirst();
+ _unprocessedReverseOrder.removeLast();
}
}
void cleanOldIntervals(int position)
{
- QMutableHashIterator<Temp, const LifeTimeInterval *> it(_intervalForTemp);
- while (it.hasNext()) {
- const LifeTimeInterval *i = it.next().value();
- if (i->end() < position || i->isFixedInterval())
- it.remove();
+ for (size_t it = 0; it != _liveIntervals.size(); ) {
+ const LifeTimeInterval *lti = _liveIntervals.at(it);
+ if (lti->end() < position || lti->isFixedInterval())
+ _liveIntervals.erase(_liveIntervals.begin() + it);
+ else
+ ++it;
}
}
@@ -1017,7 +1034,7 @@ private:
int successorStart = _intervals->startPosition(successor);
Q_ASSERT(successorStart > 0);
- for (const LifeTimeInterval *it : _liveAtStart.value(successor)) {
+ for (const LifeTimeInterval *it : _liveAtStart.at(successor->index())) {
bool isPhiTarget = false;
Expr *moveFrom = 0;
@@ -1031,7 +1048,7 @@ private:
Temp *t = opd->asTemp();
Q_ASSERT(t);
- for (const LifeTimeInterval *it2 : _liveAtEnd.value(predecessor)) {
+ for (const LifeTimeInterval *it2 : _liveAtEnd.at(predecessor->index())) {
if (it2->temp() == *t
&& it2->reg() != LifeTimeInterval::InvalidRegister
&& it2->covers(predecessorEnd)) {
@@ -1046,7 +1063,7 @@ private:
}
}
} else {
- for (const LifeTimeInterval *predIt : _liveAtEnd.value(predecessor)) {
+ for (const LifeTimeInterval *predIt : _liveAtEnd.at(predecessor->index())) {
if (predIt->temp() == it->temp()) {
if (predIt->reg() != LifeTimeInterval::InvalidRegister
&& predIt->covers(predecessorEnd)) {
@@ -1178,13 +1195,25 @@ private:
return load;
}
-protected:
- virtual void visitTemp(Temp *t)
+private:
+ void visit(Expr *e)
+ {
+ switch (e->exprKind) {
+ case Expr::TempExpr:
+ visitTemp(e->asTemp());
+ break;
+ default:
+ EXPR_VISIT_ALL_KINDS(e);
+ break;
+ }
+ }
+
+ void visitTemp(Temp *t)
{
if (t->kind != Temp::VirtualRegister)
return;
- const LifeTimeInterval *i = _intervalForTemp[*t];
+ const LifeTimeInterval *i = findLiveInterval(t);
Q_ASSERT(i->isValid());
if (_currentStmt != 0 && i->start() == usePosition(_currentStmt)) {
@@ -1209,47 +1238,25 @@ protected:
}
}
- virtual void visitArgLocal(ArgLocal *) {}
- virtual void visitConst(Const *) {}
- virtual void visitString(IR::String *) {}
- virtual void visitRegExp(IR::RegExp *) {}
- virtual void visitName(Name *) {}
- virtual void visitClosure(Closure *) {}
- virtual void visitConvert(Convert *e) { e->expr->accept(this); }
- virtual void visitUnop(Unop *e) { e->expr->accept(this); }
- virtual void visitBinop(Binop *e) { e->left->accept(this); e->right->accept(this); }
- virtual void visitSubscript(Subscript *e) { e->base->accept(this); e->index->accept(this); }
- virtual void visitMember(Member *e) { e->base->accept(this); }
-
- virtual void visitCall(Call *e) {
- e->base->accept(this);
- for (ExprList *it = e->args; it; it = it->next)
- it->expr->accept(this);
- }
-
- virtual void visitNew(New *e) {
- e->base->accept(this);
- for (ExprList *it = e->args; it; it = it->next)
- it->expr->accept(this);
- }
-
- virtual void visitExp(Exp *s) { s->expr->accept(this); }
-
- virtual void visitMove(Move *s)
+ void visit(Stmt *s)
{
- if (Temp *t = s->target->asTemp())
- maybeGenerateSpill(t);
-
- s->source->accept(this);
- s->target->accept(this);
- }
+ switch (s->stmtKind) {
+ case Stmt::MoveStmt: {
+ auto m = s->asMove();
+ if (Temp *t = m->target->asTemp())
+ maybeGenerateSpill(t);
- virtual void visitJump(Jump *) {}
- virtual void visitCJump(CJump *s) { s->cond->accept(this); }
- virtual void visitRet(Ret *s) { s->expr->accept(this); }
- virtual void visitPhi(Phi *s)
- {
- maybeGenerateSpill(s->targetTemp);
+ visit(m->source);
+ visit(m->target);
+ } break;
+ case Stmt::PhiStmt: {
+ auto p = s->asPhi();
+ maybeGenerateSpill(p->targetTemp);
+ } break;
+ default:
+ STMT_VISIT_ALL_KINDS(s);
+ break;
+ }
}
};
} // anonymous namespace
@@ -1322,8 +1329,13 @@ void RegisterAllocator::run(IR::Function *function, const Optimizer &opt)
if (DebugRegAlloc)
dump(function);
- std::sort(_handled.begin(), _handled.end(), LifeTimeInterval::lessThan);
- ResolutionPhase(_handled, _lifeTimeIntervals, function, _assignedSpillSlots, _normalRegisters, _fpRegisters).run();
+ // sort the ranges in reverse order, so the ResolutionPhase can take from the end (and thereby
+ // prevent the copy overhead that taking from the beginning would give).
+ std::sort(_handled.begin(), _handled.end(),
+ [](const LifeTimeInterval *r1, const LifeTimeInterval *r2) -> bool {
+ return LifeTimeInterval::lessThan(r2, r1);
+ });
+ ResolutionPhase(std::move(_handled), _lifeTimeIntervals, function, _assignedSpillSlots, _normalRegisters, _fpRegisters).run();
function->tempCount = *std::max_element(_assignedSpillSlots.begin(), _assignedSpillSlots.end()) + 1;