diff options
Diffstat (limited to 'src/qml/jit/qv4regalloc.cpp')
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 284 |
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; |