aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2016-02-25 10:58:58 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2016-03-06 14:25:43 +0000
commitc020bc671b30ea90f6bacd8bf6cd26ce5e808a6b (patch)
tree875a541f27e050e10396bbd1f6289816ca3b6ab2
parent3cc5c3b845b6c26d2e6c35de4672bd55b7e192b0 (diff)
V4 IR: Store the phi-node parameters directly in the class.
Every time one of the paramets was accessed, the chain of loads was: phi->d->incoming->heapdata[i] Now it is: phi[i + offsetof(incoming)] This also removes at least one malloc (for the Data), and usually two (when the number of parameters is <= 4, which is most of the cases). Change-Id: I953e784647148266ae5a49a93a203d0d22cdcb63 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp8
-rw-r--r--src/qml/compiler/qv4jsir.cpp6
-rw-r--r--src/qml/compiler/qv4jsir_p.h14
-rw-r--r--src/qml/compiler/qv4ssa.cpp52
-rw-r--r--src/qml/jit/qv4regalloc.cpp6
5 files changed, 39 insertions, 47 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp
index 7d6d7e65bc..be10d50e9b 100644
--- a/src/qml/compiler/qv4isel_moth.cpp
+++ b/src/qml/compiler/qv4isel_moth.cpp
@@ -258,13 +258,13 @@ protected:
for (IR::Stmt *succStmt : jump->target->statements()) {
if (IR::Phi *phi = succStmt->asPhi()) {
forceActivation(*phi->targetTemp);
- for (int i = 0, ei = phi->d->incoming.size(); i != ei; ++i) {
- IR::Expr *e = phi->d->incoming[i];
+ for (int i = 0, ei = phi->incoming.size(); i != ei; ++i) {
+ IR::Expr *e = phi->incoming[i];
if (IR::Temp *t = e->asTemp()) {
forceActivation(*t);
}
if (jump->target->in[i] == _currentBasicBlock)
- moves.add(phi->d->incoming[i], phi->targetTemp);
+ moves.add(phi->incoming[i], phi->targetTemp);
}
} else {
break;
@@ -303,7 +303,7 @@ protected:
#if !defined(QT_NO_DEBUG)
Q_ASSERT(_stackSlotForTemp.contains(phi->targetTemp->index));
Q_ASSERT(_slotIsInUse[_stackSlotForTemp[phi->targetTemp->index]]);
- foreach (IR::Expr *e, phi->d->incoming) {
+ foreach (IR::Expr *e, phi->incoming) {
if (IR::Temp *t = e->asTemp())
Q_ASSERT(_stackSlotForTemp.contains(t->index));
}
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp
index 4c87b7557e..e383d1432b 100644
--- a/src/qml/compiler/qv4jsir.cpp
+++ b/src/qml/compiler/qv4jsir.cpp
@@ -1084,13 +1084,13 @@ void IRPrinter::visitPhi(Phi *s)
s->targetTemp->accept(this);
*out << " = phi ";
- for (int i = 0, ei = s->d->incoming.size(); i < ei; ++i) {
+ for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
if (i > 0)
*out << ", ";
if (currentBB)
*out << 'L' << currentBB->in.at(i)->index() << ": ";
- if (s->d->incoming[i])
- s->d->incoming[i]->accept(this);
+ if (s->incoming[i])
+ s->incoming[i]->accept(this);
}
}
diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h
index 974e8dfe0d..0189ff4a23 100644
--- a/src/qml/compiler/qv4jsir_p.h
+++ b/src/qml/compiler/qv4jsir_p.h
@@ -753,21 +753,15 @@ struct Ret: Stmt {
struct Phi: Stmt {
Temp *targetTemp;
- struct Data {
- QVector<Expr *> incoming; // used by Phi nodes
- };
-
- Data *d;
+ VarLengthArray<Expr *, 4> incoming;
- Phi(int id): Stmt(id), d(0) {}
+ Phi(int id): Stmt(id) {}
virtual void accept(StmtVisitor *v) { v->visitPhi(this); }
virtual Phi *asPhi() { return this; }
- void destroyData() {
- delete d;
- d = 0;
- }
+ void destroyData()
+ { incoming.~VarLengthArray(); }
};
struct Q_QML_PRIVATE_EXPORT Module {
diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp
index 704524ce19..1e55f6b1c7 100644
--- a/src/qml/compiler/qv4ssa.cpp
+++ b/src/qml/compiler/qv4ssa.cpp
@@ -1380,16 +1380,15 @@ public:
void insertPhiNode(const Temp &a, BasicBlock *y, IR::Function *f) {
Phi *phiNode = f->NewStmt<Phi>();
- phiNode->d = new Phi::Data;
phiNode->targetTemp = f->New<Temp>();
phiNode->targetTemp->init(a.kind, a.index);
y->prependStatement(phiNode);
- phiNode->d->incoming.resize(y->in.size());
+ phiNode->incoming.resize(y->in.size());
for (int i = 0, ei = y->in.size(); i < ei; ++i) {
Temp *t = f->New<Temp>();
t->init(a.kind, a.index);
- phiNode->d->incoming[i] = t;
+ phiNode->incoming[i] = t;
}
}
@@ -1590,7 +1589,7 @@ private:
Q_ASSERT(j >= 0 && j < Y->in.size());
for (Stmt *s : Y->statements()) {
if (Phi *phi = s->asPhi()) {
- Temp *t = phi->d->incoming[j]->asTemp();
+ Temp *t = phi->incoming[j]->asTemp();
unsigned newTmp = currentNumber(*t);
// qDebug()<<"I: replacing phi use"<<a<<"with"<<newTmp<<"in L"<<Y->index;
t->index = newTmp;
@@ -2273,7 +2272,7 @@ protected:
virtual void visitRet(Ret *s) { s->expr->accept(this); }
virtual void visitPhi(Phi *s) {
s->targetTemp->accept(this);
- foreach (Expr *e, s->d->incoming)
+ foreach (Expr *e, s->incoming)
e->accept(this);
}
};
@@ -2568,9 +2567,9 @@ protected:
virtual void visitCJump(CJump *s) { _ty = run(s->cond); }
virtual void visitRet(Ret *s) { _ty = run(s->expr); }
virtual void visitPhi(Phi *s) {
- _ty = run(s->d->incoming[0]);
- for (int i = 1, ei = s->d->incoming.size(); i != ei; ++i) {
- TypingResult ty = run(s->d->incoming[i]);
+ _ty = run(s->incoming[0]);
+ for (int i = 1, ei = s->incoming.size(); i != ei; ++i) {
+ TypingResult ty = run(s->incoming[i]);
if (!ty.fullyTyped && _ty.fullyTyped) {
// When one of the temps not fully typed, we already know that we cannot completely type this node.
// So, pick the type we calculated upto this point, and wait until the unknown one will be typed.
@@ -2889,7 +2888,7 @@ public:
_defUses.addUse(*source, conversion.stmt);
if (Phi *phi = conversion.stmt->asPhi()) {
- int idx = phi->d->incoming.indexOf(t);
+ int idx = phi->incoming.indexOf(t);
Q_ASSERT(idx != -1);
bb->in[idx]->insertStatementBeforeTerminator(convCall);
} else {
@@ -3041,8 +3040,8 @@ protected:
virtual void visitRet(Ret *s) { run(s->expr); }
virtual void visitPhi(Phi *s) {
Type ty = s->targetTemp->type;
- for (int i = 0, ei = s->d->incoming.size(); i != ei; ++i)
- run(s->d->incoming[i], ty);
+ for (int i = 0, ei = s->incoming.size(); i != ei; ++i)
+ run(s->incoming[i], ty);
}
};
@@ -3566,7 +3565,7 @@ static void cleanupBasicBlocks(IR::Function *function)
outBB->in.remove(idx);
for (Stmt *s : outBB->statements()) {
if (Phi *phi = s->asPhi())
- phi->d->incoming.remove(idx);
+ phi->incoming.remove(idx);
else
break;
}
@@ -3581,9 +3580,9 @@ static void cleanupBasicBlocks(IR::Function *function)
inline Const *isConstPhi(Phi *phi)
{
- if (Const *c = phi->d->incoming[0]->asConst()) {
- for (int i = 1, ei = phi->d->incoming.size(); i != ei; ++i) {
- if (Const *cc = phi->d->incoming[i]->asConst()) {
+ if (Const *c = phi->incoming[0]->asConst()) {
+ for (int i = 1, ei = phi->incoming.size(); i != ei; ++i) {
+ if (Const *cc = phi->incoming[i]->asConst()) {
if (c->value != cc->value)
return 0;
if (!(c->type == cc->type || (c->type & NumberType && cc->type & NumberType)))
@@ -3684,8 +3683,8 @@ protected:
virtual void visitCJump(CJump *s) { check(s->cond); }
virtual void visitRet(Ret *s) { check(s->expr); }
virtual void visitPhi(Phi *s) {
- for (int i = 0, ei = s->d->incoming.size(); i != ei; ++i)
- check(s->d->incoming[i]);
+ for (int i = 0, ei = s->incoming.size(); i != ei; ++i)
+ check(s->incoming[i]);
}
private:
@@ -3746,11 +3745,11 @@ void unlink(BasicBlock *from, BasicBlock *to, IR::Function *func, DefUses &defUs
if (!outStmt)
continue;
if (Phi *phi = outStmt->asPhi()) {
- if (Temp *t = phi->d->incoming[idx]->asTemp()) {
+ if (Temp *t = phi->incoming[idx]->asTemp()) {
defUses.removeUse(phi, *t);
W += defUses.defStmt(*t);
}
- phi->d->incoming.remove(idx);
+ phi->incoming.remove(idx);
W += phi;
} else {
break;
@@ -3987,9 +3986,9 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df)
}
// copy propagation:
- if (phi->d->incoming.size() == 1) {
+ if (phi->incoming.size() == 1) {
Temp *t = phi->targetTemp;
- Expr *e = phi->d->incoming.first();
+ Expr *e = phi->incoming.first();
QVector<Stmt *> newT2Uses;
replaceUses(t, e, W, &newT2Uses);
@@ -4427,7 +4426,7 @@ private:
for (Stmt *s : successor->statements()) {
if (Phi *phi = s->asPhi()) {
- if (Temp *t = phi->d->incoming.at(bbIndex)->asTemp())
+ if (Temp *t = phi->incoming.at(bbIndex)->asTemp())
live.insert(*t);
} else {
break;
@@ -4644,9 +4643,8 @@ protected:
clonedStmt = phi;
phi->targetTemp = clone(stmt->targetTemp);
- phi->d = new Phi::Data;
- foreach (Expr *in, stmt->d->incoming)
- phi->d->incoming.append(clone(in));
+ foreach (Expr *in, stmt->incoming)
+ phi->incoming.append(clone(in));
block->appendStatement(phi);
}
@@ -4902,7 +4900,7 @@ static void verifyNoPointerSharing(IR::Function *function)
{
check(s);
s->targetTemp->accept(this);
- foreach (Expr *e, s->d->incoming)
+ foreach (Expr *e, s->incoming)
e->accept(this);
}
@@ -5341,7 +5339,7 @@ void Optimizer::convertOutOfSSA() {
Q_ASSERT(inIdx >= 0);
for (Stmt *s : successor->statements()) {
if (Phi *phi = s->asPhi()) {
- moves.add(clone(phi->d->incoming[inIdx], function),
+ moves.add(clone(phi->incoming[inIdx], function),
clone(phi->targetTemp, function)->asTemp());
} else {
break;
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index 6741529245..131e0a5b0a 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -702,8 +702,8 @@ protected: // IRDecoder
virtual void visitPhi(IR::Phi *s)
{
addDef(s->targetTemp, true);
- for (int i = 0, ei = s->d->incoming.size(); i < ei; ++i) {
- Expr *e = s->d->incoming.at(i);
+ for (int i = 0, ei = s->incoming.size(); i < ei; ++i) {
+ Expr *e = s->incoming.at(i);
if (Temp *t = e->asTemp()) {
// The actual use of an incoming value in a phi node is right before the terminator
// of the other side of the incoming edge.
@@ -1024,7 +1024,7 @@ private:
if (it->start() == successorStart) {
if (Phi *phi = findDefPhi(it->temp(), successor)) {
isPhiTarget = true;
- Expr *opd = phi->d->incoming[successor->in.indexOf(predecessor)];
+ Expr *opd = phi->incoming[successor->in.indexOf(predecessor)];
if (opd->asConst()) {
moveFrom = opd;
} else {