diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2016-03-11 12:27:48 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2016-03-20 13:14:52 +0000 |
commit | 2a37b8f2b1522558a6144b09db6f9487652a788c (patch) | |
tree | 8ae20d7307ed6755db2714a6dc8a2371523f8b64 | |
parent | 2e7d4ecdc59942b484159ca827f5d5dbc8787a1b (diff) |
V4: Allow the compiler to inline more small methods.
Change-Id: Ib2dc03a2535fcbdb10be2dab39593e8dc224fd93
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 324 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir_p.h | 333 | ||||
-rw-r--r-- | src/qml/parser/qqmljsmemorypool_p.h | 4 |
3 files changed, 325 insertions, 336 deletions
diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index a9f8df7748..b28db59190 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -511,262 +511,6 @@ void Function::setStatementCount(int cnt) _statementCount = cnt; } -BasicBlock::~BasicBlock() -{ - for (Stmt *s : qAsConst(_statements)) { - if (Phi *p = s->asPhi()) { - p->destroyData(); - } else { - break; - } - } -} - -unsigned BasicBlock::newTemp() -{ - Q_ASSERT(!isRemoved()); - return function->tempCount++; -} - -Temp *BasicBlock::TEMP(unsigned index) -{ - Q_ASSERT(!isRemoved()); - Temp *e = function->New<Temp>(); - e->init(Temp::VirtualRegister, index); - return e; -} - -ArgLocal *BasicBlock::ARG(unsigned index, unsigned scope) -{ - Q_ASSERT(!isRemoved()); - ArgLocal *e = function->New<ArgLocal>(); - e->init(scope ? ArgLocal::ScopedFormal : ArgLocal::Formal, index, scope); - return e; -} - -ArgLocal *BasicBlock::LOCAL(unsigned index, unsigned scope) -{ - Q_ASSERT(!isRemoved()); - ArgLocal *e = function->New<ArgLocal>(); - e->init(scope ? ArgLocal::ScopedLocal : ArgLocal::Local, index, scope); - return e; -} - -Expr *BasicBlock::CONST(Type type, double value) -{ - Q_ASSERT(!isRemoved()); - Const *e = function->New<Const>(); - if (type == NumberType) { - int ival = (int)value; - // +0 != -0, so we need to convert to double when negating 0 - if (ival == value && !(value == 0 && isNegative(value))) - type = SInt32Type; - else - type = DoubleType; - } else if (type == NullType) { - value = 0; - } else if (type == UndefinedType) { - value = qQNaN(); - } - - e->init(type, value); - return e; -} - -Expr *BasicBlock::STRING(const QString *value) -{ - Q_ASSERT(!isRemoved()); - String *e = function->New<String>(); - e->init(value); - return e; -} - -Expr *BasicBlock::REGEXP(const QString *value, int flags) -{ - Q_ASSERT(!isRemoved()); - RegExp *e = function->New<RegExp>(); - e->init(value, flags); - return e; -} - -Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column) -{ - Q_ASSERT(!isRemoved()); - Name *e = function->New<Name>(); - e->init(function->newString(id), line, column); - return e; -} - -Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column) -{ - Q_ASSERT(!isRemoved()); - Name *e = function->New<Name>(); - e->initGlobal(function->newString(id), line, column); - return e; -} - - -Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column) -{ - Q_ASSERT(!isRemoved()); - Name *e = function->New<Name>(); - e->init(builtin, line, column); - return e; -} - -Closure *BasicBlock::CLOSURE(int functionInModule) -{ - Q_ASSERT(!isRemoved()); - Closure *clos = function->New<Closure>(); - clos->init(functionInModule, function->module->functions.at(functionInModule)->name); - return clos; -} - -Expr *BasicBlock::CONVERT(Expr *expr, Type type) -{ - Q_ASSERT(!isRemoved()); - Convert *e = function->New<Convert>(); - e->init(expr, type); - return e; -} - -Expr *BasicBlock::UNOP(AluOp op, Expr *expr) -{ - Q_ASSERT(!isRemoved()); - Unop *e = function->New<Unop>(); - e->init(op, expr); - return e; -} - -Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) -{ - Q_ASSERT(!isRemoved()); - Binop *e = function->New<Binop>(); - e->init(op, left, right); - return e; -} - -Expr *BasicBlock::CALL(Expr *base, ExprList *args) -{ - Q_ASSERT(!isRemoved()); - Call *e = function->New<Call>(); - e->init(base, args); - int argc = 0; - for (ExprList *it = args; it; it = it->next) - ++argc; - function->maxNumberOfArguments = qMax(function->maxNumberOfArguments, argc); - return e; -} - -Expr *BasicBlock::NEW(Expr *base, ExprList *args) -{ - Q_ASSERT(!isRemoved()); - New *e = function->New<New>(); - e->init(base, args); - return e; -} - -Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index) -{ - Q_ASSERT(!isRemoved()); - Subscript *e = function->New<Subscript>(); - e->init(base, index); - return e; -} - -Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *property, uchar kind, int attachedPropertiesIdOrEnumValue) -{ - Q_ASSERT(!isRemoved()); - Member*e = function->New<Member>(); - e->init(base, name, property, kind, attachedPropertiesIdOrEnumValue); - return e; -} - -Stmt *BasicBlock::EXP(Expr *expr) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Exp *s = function->NewStmt<Exp>(); - s->init(expr); - appendStatement(s); - return s; -} - -Stmt *BasicBlock::MOVE(Expr *target, Expr *source) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Move *s = function->NewStmt<Move>(); - s->init(target, source); - appendStatement(s); - return s; -} - -Stmt *BasicBlock::JUMP(BasicBlock *target) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Jump *s = function->NewStmt<Jump>(); - s->init(target); - appendStatement(s); - - Q_ASSERT(! out.contains(target)); - out.append(target); - - Q_ASSERT(! target->in.contains(this)); - target->in.append(this); - - return s; -} - -Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - if (iftrue == iffalse) { - MOVE(TEMP(newTemp()), cond); - return JUMP(iftrue); - } - - CJump *s = function->NewStmt<CJump>(); - s->init(cond, iftrue, iffalse, this); - appendStatement(s); - - Q_ASSERT(! out.contains(iftrue)); - out.append(iftrue); - - Q_ASSERT(! iftrue->in.contains(this)); - iftrue->in.append(this); - - Q_ASSERT(! out.contains(iffalse)); - out.append(iffalse); - - Q_ASSERT(! iffalse->in.contains(this)); - iffalse->in.append(this); - - return s; -} - -Stmt *BasicBlock::RET(Expr *expr) -{ - Q_ASSERT(!isRemoved()); - if (isTerminated()) - return 0; - - Ret *s = function->NewStmt<Ret>(); - s->init(expr); - appendStatement(s); - return s; -} - void BasicBlock::setStatements(const QVector<Stmt *> &newStatements) { Q_ASSERT(!isRemoved()); @@ -784,74 +528,6 @@ void BasicBlock::setStatements(const QVector<Stmt *> &newStatements) _statements = newStatements; } -void BasicBlock::appendStatement(Stmt *statement) -{ - Q_ASSERT(!isRemoved()); - if (nextLocation.startLine) - statement->location = nextLocation; - _statements.append(statement); -} - -void BasicBlock::prependStatement(Stmt *stmt) -{ - Q_ASSERT(!isRemoved()); - _statements.prepend(stmt); -} - -void BasicBlock::prependStatements(const QVector<Stmt *> &stmts) -{ - Q_ASSERT(!isRemoved()); - QVector<Stmt *> newStmts = stmts; - newStmts += _statements; - _statements = newStmts; -} - -void BasicBlock::insertStatementBefore(Stmt *before, Stmt *newStmt) -{ - int idx = _statements.indexOf(before); - Q_ASSERT(idx >= 0); - _statements.insert(idx, newStmt); -} - -void BasicBlock::insertStatementBefore(int index, Stmt *newStmt) -{ - Q_ASSERT(index >= 0); - _statements.insert(index, newStmt); -} - -void BasicBlock::insertStatementBeforeTerminator(Stmt *stmt) -{ - Q_ASSERT(!isRemoved()); - _statements.insert(_statements.size() - 1, stmt); -} - -void BasicBlock::replaceStatement(int index, Stmt *newStmt) -{ - Q_ASSERT(!isRemoved()); - if (Phi *p = _statements[index]->asPhi()) { - p->destroyData(); - } - _statements[index] = newStmt; -} - -void BasicBlock::removeStatement(Stmt *stmt) -{ - Q_ASSERT(!isRemoved()); - if (Phi *p = stmt->asPhi()) { - p->destroyData(); - } - _statements.remove(_statements.indexOf(stmt)); -} - -void BasicBlock::removeStatement(int idx) -{ - Q_ASSERT(!isRemoved()); - if (Phi *p = _statements[idx]->asPhi()) { - p->destroyData(); - } - _statements.remove(idx); -} - CloneExpr::CloneExpr(BasicBlock *block) : block(block), cloned(0) { diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index baa338ed52..4dfd63705b 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -811,7 +811,17 @@ public: , _groupStart(false) , _isRemoved(false) {} - ~BasicBlock(); + + ~BasicBlock() + { + for (Stmt *s : qAsConst(_statements)) { + if (Phi *p = s->asPhi()) { + p->destroyData(); + } else { + break; + } + } + } const QVector<Stmt *> &statements() const { @@ -834,15 +844,73 @@ public: return i; } - void appendStatement(Stmt *statement); - void prependStatement(Stmt *stmt); - void prependStatements(const QVector<Stmt *> &stmts); - void insertStatementBefore(Stmt *before, Stmt *newStmt); - void insertStatementBefore(int index, Stmt *newStmt); - void insertStatementBeforeTerminator(Stmt *stmt); - void replaceStatement(int index, Stmt *newStmt); - void removeStatement(Stmt *stmt); - void removeStatement(int idx); + void appendStatement(Stmt *statement) + { + Q_ASSERT(!isRemoved()); + if (nextLocation.startLine) + statement->location = nextLocation; + _statements.append(statement); + } + + void prependStatement(Stmt *stmt) + { + Q_ASSERT(!isRemoved()); + _statements.prepend(stmt); + } + + void prependStatements(const QVector<Stmt *> &stmts) + { + Q_ASSERT(!isRemoved()); + QVector<Stmt *> newStmts = stmts; + newStmts += _statements; + _statements = newStmts; + } + + void insertStatementBefore(Stmt *before, Stmt *newStmt) + { + int idx = _statements.indexOf(before); + Q_ASSERT(idx >= 0); + _statements.insert(idx, newStmt); + } + + void insertStatementBefore(int index, Stmt *newStmt) + { + Q_ASSERT(index >= 0); + _statements.insert(index, newStmt); + } + + void insertStatementBeforeTerminator(Stmt *stmt) + { + Q_ASSERT(!isRemoved()); + _statements.insert(_statements.size() - 1, stmt); + } + + void replaceStatement(int index, Stmt *newStmt) + { + Q_ASSERT(!isRemoved()); + if (Phi *p = _statements[index]->asPhi()) { + p->destroyData(); + } + _statements[index] = newStmt; + } + + void removeStatement(Stmt *stmt) + { + Q_ASSERT(!isRemoved()); + if (Phi *p = stmt->asPhi()) { + p->destroyData(); + } + _statements.remove(_statements.indexOf(stmt)); + } + + void removeStatement(int idx) + { + Q_ASSERT(!isRemoved()); + if (Phi *p = _statements[idx]->asPhi()) { + p->destroyData(); + } + _statements.remove(idx); + } inline bool isEmpty() const { Q_ASSERT(!isRemoved()); @@ -1207,6 +1275,251 @@ protected: BasicBlock *currentBB; }; +inline unsigned BasicBlock::newTemp() +{ + Q_ASSERT(!isRemoved()); + return function->tempCount++; +} + +inline Temp *BasicBlock::TEMP(unsigned index) +{ + Q_ASSERT(!isRemoved()); + Temp *e = function->New<Temp>(); + e->init(Temp::VirtualRegister, index); + return e; +} + +inline ArgLocal *BasicBlock::ARG(unsigned index, unsigned scope) +{ + Q_ASSERT(!isRemoved()); + ArgLocal *e = function->New<ArgLocal>(); + e->init(scope ? ArgLocal::ScopedFormal : ArgLocal::Formal, index, scope); + return e; +} + +inline ArgLocal *BasicBlock::LOCAL(unsigned index, unsigned scope) +{ + Q_ASSERT(!isRemoved()); + ArgLocal *e = function->New<ArgLocal>(); + e->init(scope ? ArgLocal::ScopedLocal : ArgLocal::Local, index, scope); + return e; +} + +inline Expr *BasicBlock::CONST(Type type, double value) +{ + Q_ASSERT(!isRemoved()); + Const *e = function->New<Const>(); + if (type == NumberType) { + int ival = (int)value; + // +0 != -0, so we need to convert to double when negating 0 + if (ival == value && !(value == 0 && isNegative(value))) + type = SInt32Type; + else + type = DoubleType; + } else if (type == NullType) { + value = 0; + } else if (type == UndefinedType) { + value = qQNaN(); + } + + e->init(type, value); + return e; +} + +inline Expr *BasicBlock::STRING(const QString *value) +{ + Q_ASSERT(!isRemoved()); + String *e = function->New<String>(); + e->init(value); + return e; +} + +inline Expr *BasicBlock::REGEXP(const QString *value, int flags) +{ + Q_ASSERT(!isRemoved()); + RegExp *e = function->New<RegExp>(); + e->init(value, flags); + return e; +} + +inline Name *BasicBlock::NAME(const QString &id, quint32 line, quint32 column) +{ + Q_ASSERT(!isRemoved()); + Name *e = function->New<Name>(); + e->init(function->newString(id), line, column); + return e; +} + +inline Name *BasicBlock::GLOBALNAME(const QString &id, quint32 line, quint32 column) +{ + Q_ASSERT(!isRemoved()); + Name *e = function->New<Name>(); + e->initGlobal(function->newString(id), line, column); + return e; +} + + +inline Name *BasicBlock::NAME(Name::Builtin builtin, quint32 line, quint32 column) +{ + Q_ASSERT(!isRemoved()); + Name *e = function->New<Name>(); + e->init(builtin, line, column); + return e; +} + +inline Closure *BasicBlock::CLOSURE(int functionInModule) +{ + Q_ASSERT(!isRemoved()); + Closure *clos = function->New<Closure>(); + clos->init(functionInModule, function->module->functions.at(functionInModule)->name); + return clos; +} + +inline Expr *BasicBlock::CONVERT(Expr *expr, Type type) +{ + Q_ASSERT(!isRemoved()); + Convert *e = function->New<Convert>(); + e->init(expr, type); + return e; +} + +inline Expr *BasicBlock::UNOP(AluOp op, Expr *expr) +{ + Q_ASSERT(!isRemoved()); + Unop *e = function->New<Unop>(); + e->init(op, expr); + return e; +} + +inline Expr *BasicBlock::BINOP(AluOp op, Expr *left, Expr *right) +{ + Q_ASSERT(!isRemoved()); + Binop *e = function->New<Binop>(); + e->init(op, left, right); + return e; +} + +inline Expr *BasicBlock::CALL(Expr *base, ExprList *args) +{ + Q_ASSERT(!isRemoved()); + Call *e = function->New<Call>(); + e->init(base, args); + int argc = 0; + for (ExprList *it = args; it; it = it->next) + ++argc; + function->maxNumberOfArguments = qMax(function->maxNumberOfArguments, argc); + return e; +} + +inline Expr *BasicBlock::NEW(Expr *base, ExprList *args) +{ + Q_ASSERT(!isRemoved()); + New *e = function->New<New>(); + e->init(base, args); + return e; +} + +inline Expr *BasicBlock::SUBSCRIPT(Expr *base, Expr *index) +{ + Q_ASSERT(!isRemoved()); + Subscript *e = function->New<Subscript>(); + e->init(base, index); + return e; +} + +inline Expr *BasicBlock::MEMBER(Expr *base, const QString *name, QQmlPropertyData *property, uchar kind, int attachedPropertiesIdOrEnumValue) +{ + Q_ASSERT(!isRemoved()); + Member*e = function->New<Member>(); + e->init(base, name, property, kind, attachedPropertiesIdOrEnumValue); + return e; +} + +inline Stmt *BasicBlock::EXP(Expr *expr) +{ + Q_ASSERT(!isRemoved()); + if (isTerminated()) + return 0; + + Exp *s = function->NewStmt<Exp>(); + s->init(expr); + appendStatement(s); + return s; +} + +inline Stmt *BasicBlock::MOVE(Expr *target, Expr *source) +{ + Q_ASSERT(!isRemoved()); + if (isTerminated()) + return 0; + + Move *s = function->NewStmt<Move>(); + s->init(target, source); + appendStatement(s); + return s; +} + +inline Stmt *BasicBlock::JUMP(BasicBlock *target) +{ + Q_ASSERT(!isRemoved()); + if (isTerminated()) + return 0; + + Jump *s = function->NewStmt<Jump>(); + s->init(target); + appendStatement(s); + + Q_ASSERT(! out.contains(target)); + out.append(target); + + Q_ASSERT(! target->in.contains(this)); + target->in.append(this); + + return s; +} + +inline Stmt *BasicBlock::CJUMP(Expr *cond, BasicBlock *iftrue, BasicBlock *iffalse) +{ + Q_ASSERT(!isRemoved()); + if (isTerminated()) + return 0; + + if (iftrue == iffalse) { + MOVE(TEMP(newTemp()), cond); + return JUMP(iftrue); + } + + CJump *s = function->NewStmt<CJump>(); + s->init(cond, iftrue, iffalse, this); + appendStatement(s); + + Q_ASSERT(! out.contains(iftrue)); + out.append(iftrue); + + Q_ASSERT(! iftrue->in.contains(this)); + iftrue->in.append(this); + + Q_ASSERT(! out.contains(iffalse)); + out.append(iffalse); + + Q_ASSERT(! iffalse->in.contains(this)); + iffalse->in.append(this); + + return s; +} + +inline Stmt *BasicBlock::RET(Expr *expr) +{ + Q_ASSERT(!isRemoved()); + if (isTerminated()) + return 0; + + Ret *s = function->NewStmt<Ret>(); + s->init(expr); + appendStatement(s); + return s; +} + } // end of namespace IR } // end of namespace QV4 diff --git a/src/qml/parser/qqmljsmemorypool_p.h b/src/qml/parser/qqmljsmemorypool_p.h index 3659271bc6..08609e2961 100644 --- a/src/qml/parser/qqmljsmemorypool_p.h +++ b/src/qml/parser/qqmljsmemorypool_p.h @@ -94,7 +94,7 @@ public: inline void *allocate(size_t size) { size = (size + 7) & ~7; - if (_ptr && (_ptr + size < _end)) { + if (Q_LIKELY(_ptr && (_ptr + size < _end))) { void *addr = _ptr; _ptr += size; return addr; @@ -111,7 +111,7 @@ public: template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); } private: - void *allocate_helper(size_t size) + Q_NEVER_INLINE void *allocate_helper(size_t size) { Q_ASSERT(size < BLOCK_SIZE); |