From b368fe0167666cc7ce264705653107ffc21ac8cc Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 2 Mar 2015 14:22:24 +0100 Subject: V4: fix phi node use position calculation. As phi-nodes get transformed into moves, and the moves end up right before the terminator of the basic block of the incoming edge, the use by that phi-node is the position of that terminator minus one. However, when checking if uses need a register, this was not taken into account, resulting in an invalid life-time interval split position calculation. Task-number: QTBUG-44687 Change-Id: I0edd416f7ee5c8ea16bf7133870be45d0e6efea9 Reviewed-by: Fawzi Mohamed --- src/qml/compiler/qv4ssa.cpp | 8 +++++++- src/qml/jit/qv4regalloc.cpp | 29 ++++++++++++----------------- 2 files changed, 19 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 52db540871..a0ed77ffc1 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -3844,6 +3844,7 @@ void cfg2dot(IR::Function *f, const QVector &loops = } qout << "}\n"; + buf.close(); qDebug("%s", buf.data().constData()); } @@ -4301,6 +4302,7 @@ public: } qout << endl; } + buf.close(); qDebug("%s", buf.data().constData()); } @@ -4315,7 +4317,7 @@ private: foreach (Stmt *s, successor->statements()) { if (Phi *phi = s->asPhi()) { - if (Temp *t = phi->d->incoming[bbIndex]->asTemp()) + if (Temp *t = phi->d->incoming.at(bbIndex)->asTemp()) live.insert(*t); } else { break; @@ -4886,6 +4888,8 @@ void LifeTimeInterval::addRange(int from, int to) { LifeTimeInterval LifeTimeInterval::split(int atPosition, int newStart) { Q_ASSERT(atPosition < newStart || newStart == InvalidPosition); + Q_ASSERT(atPosition <= _end); + Q_ASSERT(newStart <= _end || newStart == InvalidPosition); if (_ranges.isEmpty() || atPosition < _ranges.first().start) return LifeTimeInterval(); @@ -5204,6 +5208,7 @@ void Optimizer::convertOutOfSSA() { os << (void *) function; os << " on basic-block L" << bb->index() << ":" << endl; moves.dump(); + buf.close(); qDebug("%s", buf.data().constData()); } @@ -5317,6 +5322,7 @@ void MoveMapping::add(Expr *from, Temp *to) { printer.print(to); os << " <- "; printer.print(from); + buf.close(); qDebug("%s", buf.data().constData()); } return; diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index 4bc8e14fbf..b34cd7bd68 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -185,21 +185,7 @@ public: const std::vector &uses(const Temp &t) const { - return _uses[t.index]; - } - - bool useMustHaveReg(const Temp &t, int position) { - foreach (const Use &use, uses(t)) - if (use.pos == position) - return use.mustHaveRegister(); - return false; - } - - bool isUsedAt(const Temp &t, int position) { - foreach (const Use &use, uses(t)) - if (use.pos == position) - return true; - return false; + return _uses.at(t.index); } bool canHaveRegister(const Temp &t) const { @@ -699,9 +685,13 @@ protected: // IRDecoder virtual void visitPhi(IR::Phi *s) { addDef(s->targetTemp, true); - foreach (Expr *e, s->d->incoming) { + for (int i = 0, ei = s->d->incoming.size(); i < ei; ++i) { + Expr *e = s->d->incoming.at(i); if (Temp *t = e->asTemp()) { - addUses(t, Use::CouldHaveRegister); + // The actual use of an incoming value in a phi node is right before the terminator + // of the other side of the incoming edge. + const int usePos = _lifeTimeIntervals->positionForStatement(_currentBB->in.at(i)->terminator()) - 1; + addUses(t, Use::CouldHaveRegister, usePos); addHint(s->targetTemp, t); addHint(t, s->targetTemp); } @@ -747,6 +737,11 @@ private: void addUses(Expr *e, Use::RegisterFlag flag) { const int usePos = usePosition(_currentStmt); + addUses(e, flag, usePos); + } + + void addUses(Expr *e, Use::RegisterFlag flag, int usePos) + { Q_ASSERT(usePos > 0); if (!e) return; -- cgit v1.2.3