diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2016-02-25 10:58:58 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2016-03-06 14:25:43 +0000 |
commit | c020bc671b30ea90f6bacd8bf6cd26ce5e808a6b (patch) | |
tree | 875a541f27e050e10396bbd1f6289816ca3b6ab2 | |
parent | 3cc5c3b845b6c26d2e6c35de4672bd55b7e192b0 (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.cpp | 8 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 14 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 52 | ||||
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 6 |
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 { |