aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2015-03-02 14:22:24 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-03-03 10:03:56 +0000
commitb368fe0167666cc7ce264705653107ffc21ac8cc (patch)
tree271fd9dedb9bcc93ce6efa03f6905495012aaabd /src
parentac4dcc585f4fb02b9b04867c75a883e4ad23693e (diff)
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 <fawzi.mohamed@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4ssa.cpp8
-rw-r--r--src/qml/jit/qv4regalloc.cpp29
2 files changed, 19 insertions, 18 deletions
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<LoopDetection::LoopInfo *> &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<Use> &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;