From 28b54d1ac92bac244902d249d24da47594510a96 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 5 Jun 2013 16:19:48 +0200 Subject: [PATCH] Mark loop blocks as belonging to a group. This will be used for block scheduling. Change-Id: I071c2107c0303d09dfd595c9825256a5167a1514 Reviewed-by: Simon Hausmann --- src/qml/qml/v4/qv4codegen.cpp | 133 ++++++++++++++++++++++-------------------- src/qml/qml/v4/qv4codegen_p.h | 15 +++-- src/qml/qml/v4/qv4jsir.cpp | 4 +- src/qml/qml/v4/qv4jsir_p.h | 23 +++++++- src/qml/qml/v4/qv4ssa.cpp | 2 +- 5 files changed, 103 insertions(+), 74 deletions(-) diff --git a/src/qml/qml/v4/qv4codegen.cpp b/src/qml/qml/v4/qv4codegen.cpp index ab48038..f5868b1 100644 --- a/src/qml/qml/v4/qv4codegen.cpp +++ b/src/qml/qml/v4/qv4codegen.cpp @@ -561,9 +561,11 @@ void Codegen::leaveEnvironment() _env = _env->parent; } -void Codegen::enterLoop(Statement *node, V4IR::BasicBlock *breakBlock, V4IR::BasicBlock *continueBlock) +void Codegen::enterLoop(Statement *node, V4IR::BasicBlock *startBlock, V4IR::BasicBlock *breakBlock, V4IR::BasicBlock *continueBlock) { - _loop = new Loop(node, breakBlock, continueBlock, _loop); + if (startBlock) + startBlock->markAsGroupStart(); + _loop = new Loop(node, startBlock, breakBlock, continueBlock, _loop); _loop->labelledStatement = _labelledStatement; // consume the enclosing labelled statement _loop->scopeAndFinally = _scopeAndFinally; _labelledStatement = 0; @@ -1158,13 +1160,13 @@ bool Codegen::visit(BinaryExpression *ast) { if (ast->op == QSOperator::And) { if (_expr.accept(cx)) { - V4IR::BasicBlock *iftrue = _function->newBasicBlock(); + V4IR::BasicBlock *iftrue = _function->newBasicBlock(groupStartBlock()); condition(ast->left, iftrue, _expr.iffalse); _block = iftrue; condition(ast->right, _expr.iftrue, _expr.iffalse); } else { - V4IR::BasicBlock *iftrue = _function->newBasicBlock(); - V4IR::BasicBlock *endif = _function->newBasicBlock(); + V4IR::BasicBlock *iftrue = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *endif = _function->newBasicBlock(groupStartBlock()); const unsigned r = _block->newTemp(); @@ -1180,13 +1182,13 @@ bool Codegen::visit(BinaryExpression *ast) return false; } else if (ast->op == QSOperator::Or) { if (_expr.accept(cx)) { - V4IR::BasicBlock *iffalse = _function->newBasicBlock(); + V4IR::BasicBlock *iffalse = _function->newBasicBlock(groupStartBlock()); condition(ast->left, _expr.iftrue, iffalse); _block = iffalse; condition(ast->right, _expr.iftrue, _expr.iffalse); } else { - V4IR::BasicBlock *iffalse = _function->newBasicBlock(); - V4IR::BasicBlock *endif = _function->newBasicBlock(); + V4IR::BasicBlock *iffalse = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *endif = _function->newBasicBlock(groupStartBlock()); const unsigned r = _block->newTemp(); move(_block->TEMP(r), *expression(ast->left)); @@ -1336,9 +1338,9 @@ bool Codegen::visit(CallExpression *ast) bool Codegen::visit(ConditionalExpression *ast) { - V4IR::BasicBlock *iftrue = _function->newBasicBlock(); - V4IR::BasicBlock *iffalse = _function->newBasicBlock(); - V4IR::BasicBlock *endif = _function->newBasicBlock(); + V4IR::BasicBlock *iftrue = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *iffalse = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *endif = _function->newBasicBlock(groupStartBlock()); const unsigned t = _block->newTemp(); @@ -1815,6 +1817,8 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, const QStringList &inheritedLocals) { qSwap(_mode, mode); // enter function code. + Loop *loop = 0; + qSwap(_loop, loop); ScopeAndFinally *scopeAndFinally = 0; @@ -1824,9 +1828,9 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, if (_debugger) _debugger->addFunction(function); - V4IR::BasicBlock *entryBlock = function->newBasicBlock(); - V4IR::BasicBlock *exitBlock = function->newBasicBlock(V4IR::Function::DontInsertBlock); - V4IR::BasicBlock *throwBlock = function->newBasicBlock(); + V4IR::BasicBlock *entryBlock = function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *exitBlock = function->newBasicBlock(groupStartBlock(), V4IR::Function::DontInsertBlock); + V4IR::BasicBlock *throwBlock = function->newBasicBlock(groupStartBlock()); function->hasDirectEval = _env->hasDirectEval; function->usesArgumentsObject = (_env->usesArgumentsObject == Environment::ArgumentsObjectUsed); function->maxNumberOfArguments = _env->maxNumberOfArguments; @@ -1879,7 +1883,6 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, throwArgs->expr = throwBlock->TEMP(returnAddress); throwBlock->EXP(throwBlock->CALL(throwBlock->NAME(V4IR::Name::builtin_throw, /*line*/0, /*column*/0), throwArgs)); throwBlock->JUMP(exitBlock); - Loop *loop = 0; qSwap(_function, function); qSwap(_block, entryBlock); @@ -1887,7 +1890,6 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast, qSwap(_throwBlock, throwBlock); qSwap(_returnAddress, returnAddress); qSwap(_scopeAndFinally, scopeAndFinally); - qSwap(_loop, loop); for (FormalParameterList *it = formals; it; it = it->next) { _function->RECEIVE(it->name.toString()); @@ -2022,11 +2024,11 @@ bool Codegen::visit(DebuggerStatement *) bool Codegen::visit(DoWhileStatement *ast) { - V4IR::BasicBlock *loopbody = _function->newBasicBlock(); - V4IR::BasicBlock *loopcond = _function->newBasicBlock(); - V4IR::BasicBlock *loopend = _function->newBasicBlock(); + V4IR::BasicBlock *loopbody = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *loopcond = _function->newBasicBlock(loopbody); + V4IR::BasicBlock *loopend = _function->newBasicBlock(groupStartBlock()); - enterLoop(ast, loopend, loopcond); + enterLoop(ast, loopbody, loopend, loopcond); _block->JUMP(loopbody); @@ -2063,11 +2065,11 @@ bool Codegen::visit(ExpressionStatement *ast) bool Codegen::visit(ForEachStatement *ast) { - V4IR::BasicBlock *foreachin = _function->newBasicBlock(); - V4IR::BasicBlock *foreachbody = _function->newBasicBlock(); - V4IR::BasicBlock *foreachend = _function->newBasicBlock(); + V4IR::BasicBlock *foreachin = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *foreachbody = _function->newBasicBlock(foreachin); + V4IR::BasicBlock *foreachend = _function->newBasicBlock(groupStartBlock()); - enterLoop(ast, foreachend, foreachin); + enterLoop(ast, foreachin, foreachend, foreachin); int objectToIterateOn = _block->newTemp(); move(_block->TEMP(objectToIterateOn), *expression(ast->expression)); @@ -2101,12 +2103,12 @@ bool Codegen::visit(ForEachStatement *ast) bool Codegen::visit(ForStatement *ast) { - V4IR::BasicBlock *forcond = _function->newBasicBlock(); - V4IR::BasicBlock *forbody = _function->newBasicBlock(); - V4IR::BasicBlock *forstep = _function->newBasicBlock(); - V4IR::BasicBlock *forend = _function->newBasicBlock(); + V4IR::BasicBlock *forcond = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *forbody = _function->newBasicBlock(forcond); + V4IR::BasicBlock *forstep = _function->newBasicBlock(forcond); + V4IR::BasicBlock *forend = _function->newBasicBlock(groupStartBlock()); - enterLoop(ast, forend, forstep); + enterLoop(ast, forcond, forend, forstep); statement(ast->initialiser); _block->JUMP(forcond); @@ -2124,6 +2126,7 @@ bool Codegen::visit(ForStatement *ast) _block = forstep; statement(ast->expression); _block->JUMP(forcond); + _block = forend; leaveLoop(); @@ -2133,9 +2136,9 @@ bool Codegen::visit(ForStatement *ast) bool Codegen::visit(IfStatement *ast) { - V4IR::BasicBlock *iftrue = _function->newBasicBlock(); - V4IR::BasicBlock *iffalse = ast->ko ? _function->newBasicBlock() : 0; - V4IR::BasicBlock *endif = _function->newBasicBlock(); + V4IR::BasicBlock *iftrue = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *iffalse = ast->ko ? _function->newBasicBlock(groupStartBlock()) : 0; + V4IR::BasicBlock *endif = _function->newBasicBlock(groupStartBlock()); condition(ast->expression, iftrue, ast->ko ? iffalse : endif); _block = iftrue; @@ -2166,8 +2169,8 @@ bool Codegen::visit(LabelledStatement *ast) AST::cast(ast->statement)) { statement(ast->statement); // labelledStatement will be associated with the ast->statement's loop. } else { - V4IR::BasicBlock *breakBlock = _function->newBasicBlock(); - enterLoop(ast->statement, breakBlock, /*continueBlock*/ 0); + V4IR::BasicBlock *breakBlock = _function->newBasicBlock(groupStartBlock()); + enterLoop(ast->statement, 0, breakBlock, /*continueBlock*/ 0); statement(ast->statement); _block->JUMP(breakBlock); _block = breakBlock; @@ -2179,11 +2182,11 @@ bool Codegen::visit(LabelledStatement *ast) bool Codegen::visit(LocalForEachStatement *ast) { - V4IR::BasicBlock *foreachin = _function->newBasicBlock(); - V4IR::BasicBlock *foreachbody = _function->newBasicBlock(); - V4IR::BasicBlock *foreachend = _function->newBasicBlock(); + V4IR::BasicBlock *foreachin = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *foreachbody = _function->newBasicBlock(foreachin); + V4IR::BasicBlock *foreachend = _function->newBasicBlock(groupStartBlock()); - enterLoop(ast, foreachend, foreachin); + enterLoop(ast, foreachin, foreachend, foreachin); variableDeclaration(ast->declaration); @@ -2217,12 +2220,12 @@ bool Codegen::visit(LocalForEachStatement *ast) bool Codegen::visit(LocalForStatement *ast) { - V4IR::BasicBlock *forcond = _function->newBasicBlock(); - V4IR::BasicBlock *forbody = _function->newBasicBlock(); - V4IR::BasicBlock *forstep = _function->newBasicBlock(); - V4IR::BasicBlock *forend = _function->newBasicBlock(); + V4IR::BasicBlock *forcond = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *forbody = _function->newBasicBlock(forcond); + V4IR::BasicBlock *forstep = _function->newBasicBlock(forcond); + V4IR::BasicBlock *forend = _function->newBasicBlock(groupStartBlock()); - enterLoop(ast, forend, forstep); + enterLoop(ast, forcond, forend, forstep); variableDeclarationList(ast->declarations); _block->JUMP(forcond); @@ -2240,6 +2243,7 @@ bool Codegen::visit(LocalForStatement *ast) _block = forstep; statement(ast->expression); _block->JUMP(forcond); + _block = forend; leaveLoop(); @@ -2263,21 +2267,22 @@ bool Codegen::visit(ReturnStatement *ast) bool Codegen::visit(SwitchStatement *ast) { - V4IR::BasicBlock *switchend = _function->newBasicBlock(); + V4IR::BasicBlock *switchend = _function->newBasicBlock(groupStartBlock()); if (ast->block) { Result lhs = expression(ast->expression); - V4IR::BasicBlock *switchcond = _block; + V4IR::BasicBlock *switchcond = _function->newBasicBlock(groupStartBlock()); + _block->JUMP(switchcond); V4IR::BasicBlock *previousBlock = 0; QHash blockMap; - enterLoop(ast, switchend, 0); + enterLoop(ast, 0, switchend, 0); for (CaseClauses *it = ast->block->clauses; it; it = it->next) { CaseClause *clause = it->clause; - _block = _function->newBasicBlock(); + _block = _function->newBasicBlock(groupStartBlock()); blockMap[clause] = _block; if (previousBlock && !previousBlock->isTerminated()) @@ -2290,7 +2295,7 @@ bool Codegen::visit(SwitchStatement *ast) } if (ast->block->defaultClause) { - _block = _function->newBasicBlock(); + _block = _function->newBasicBlock(groupStartBlock()); blockMap[ast->block->defaultClause] = _block; if (previousBlock && !previousBlock->isTerminated()) @@ -2305,7 +2310,7 @@ bool Codegen::visit(SwitchStatement *ast) for (CaseClauses *it = ast->block->moreClauses; it; it = it->next) { CaseClause *clause = it->clause; - _block = _function->newBasicBlock(); + _block = _function->newBasicBlock(groupStartBlock()); blockMap[clause] = _block; if (previousBlock && !previousBlock->isTerminated()) @@ -2326,7 +2331,7 @@ bool Codegen::visit(SwitchStatement *ast) CaseClause *clause = it->clause; Result rhs = expression(clause->expression); V4IR::BasicBlock *iftrue = blockMap[clause]; - V4IR::BasicBlock *iffalse = _function->newBasicBlock(); + V4IR::BasicBlock *iffalse = _function->newBasicBlock(groupStartBlock()); cjump(binop(V4IR::OpStrictEqual, *lhs, *rhs), iftrue, iffalse); _block = iffalse; } @@ -2335,7 +2340,7 @@ bool Codegen::visit(SwitchStatement *ast) CaseClause *clause = it->clause; Result rhs = expression(clause->expression); V4IR::BasicBlock *iftrue = blockMap[clause]; - V4IR::BasicBlock *iffalse = _function->newBasicBlock(); + V4IR::BasicBlock *iffalse = _function->newBasicBlock(groupStartBlock()); cjump(binop(V4IR::OpStrictEqual, *lhs, *rhs), iftrue, iffalse); _block = iffalse; } @@ -2367,12 +2372,12 @@ bool Codegen::visit(TryStatement *ast) (ast->catchExpression->name == QLatin1String("eval") || ast->catchExpression->name == QLatin1String("arguments"))) throwSyntaxError(ast->catchExpression->identifierToken, QCoreApplication::translate("qv4codegen", "Catch variable name may not be eval or arguments in strict mode")); - V4IR::BasicBlock *tryBody = _function->newBasicBlock(); - V4IR::BasicBlock *catchBody = _function->newBasicBlock(); + V4IR::BasicBlock *tryBody = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *catchBody = _function->newBasicBlock(groupStartBlock()); // We always need a finally body to clean up the exception handler - V4IR::BasicBlock *finallyBody = _function->newBasicBlock(); + V4IR::BasicBlock *finallyBody = _function->newBasicBlock(groupStartBlock()); - V4IR::BasicBlock *throwBlock = _function->newBasicBlock(); + V4IR::BasicBlock *throwBlock = _function->newBasicBlock(groupStartBlock()); V4IR::ExprList *throwArgs = _function->New(); throwArgs->expr = throwBlock->TEMP(_returnAddress); throwBlock->EXP(throwBlock->CALL(throwBlock->NAME(V4IR::Name::builtin_throw, /*line*/0, /*column*/0), throwArgs)); @@ -2406,7 +2411,7 @@ bool Codegen::visit(TryStatement *ast) if (ast->catchExpression) { // check if an exception got thrown within catch. Go to finally // and then rethrow - V4IR::BasicBlock *b = _function->newBasicBlock(); + V4IR::BasicBlock *b = _function->newBasicBlock(groupStartBlock()); _block->CJUMP(_block->TEMP(hasException), finallyBody, b); _block = b; } @@ -2430,7 +2435,7 @@ bool Codegen::visit(TryStatement *ast) qSwap(_throwBlock, throwBlock); - V4IR::BasicBlock *after = _function->newBasicBlock(); + V4IR::BasicBlock *after = _function->newBasicBlock(groupStartBlock()); _block = finallyBody; _block->EXP(_block->CALL(_block->NAME(V4IR::Name::builtin_finish_try, 0, 0), finishTryArgs)); @@ -2438,7 +2443,7 @@ bool Codegen::visit(TryStatement *ast) if (ast->finallyExpression && ast->finallyExpression->statement) statement(ast->finallyExpression->statement); - V4IR::BasicBlock *rethrowBlock = _function->newBasicBlock(); + V4IR::BasicBlock *rethrowBlock = _function->newBasicBlock(groupStartBlock()); _block->CJUMP(_block->TEMP(hasException), rethrowBlock, after); _block = rethrowBlock; move(_block->TEMP(_returnAddress), _block->TEMP(exception_to_rethrow)); @@ -2485,11 +2490,11 @@ bool Codegen::visit(VariableStatement *ast) bool Codegen::visit(WhileStatement *ast) { - V4IR::BasicBlock *whilecond = _function->newBasicBlock(); - V4IR::BasicBlock *whilebody = _function->newBasicBlock(); - V4IR::BasicBlock *whileend = _function->newBasicBlock(); + V4IR::BasicBlock *whilecond = _function->newBasicBlock(groupStartBlock()); + V4IR::BasicBlock *whilebody = _function->newBasicBlock(whilecond); + V4IR::BasicBlock *whileend = _function->newBasicBlock(groupStartBlock()); - enterLoop(ast, whileend, whilecond); + enterLoop(ast, whilecond, whileend, whilecond); _block->JUMP(whilecond); _block = whilecond; @@ -2509,7 +2514,7 @@ bool Codegen::visit(WithStatement *ast) { _function->hasWith = true; - V4IR::BasicBlock *withBlock = _function->newBasicBlock(); + V4IR::BasicBlock *withBlock = _function->newBasicBlock(groupStartBlock()); _block->JUMP(withBlock); _block = withBlock; @@ -2529,7 +2534,7 @@ bool Codegen::visit(WithStatement *ast) --_function->insideWithOrCatch; _block->EXP(_block->CALL(_block->NAME(V4IR::Name::builtin_pop_scope, 0, 0), 0)); - V4IR::BasicBlock *next = _function->newBasicBlock(); + V4IR::BasicBlock *next = _function->newBasicBlock(groupStartBlock()); _block->JUMP(next); _block = next; diff --git a/src/qml/qml/v4/qv4codegen_p.h b/src/qml/qml/v4/qv4codegen_p.h index 225784b..88332ab 100644 --- a/src/qml/qml/v4/qv4codegen_p.h +++ b/src/qml/qml/v4/qv4codegen_p.h @@ -254,21 +254,28 @@ protected: struct Loop { AST::LabelledStatement *labelledStatement; AST::Statement *node; + V4IR::BasicBlock *groupStartBlock; V4IR::BasicBlock *breakBlock; V4IR::BasicBlock *continueBlock; Loop *parent; ScopeAndFinally *scopeAndFinally; - Loop(AST::Statement *node, V4IR::BasicBlock *breakBlock, V4IR::BasicBlock *continueBlock, Loop *parent) - : labelledStatement(0), node(node), breakBlock(breakBlock), continueBlock(continueBlock), parent(parent) {} + Loop(AST::Statement *node, V4IR::BasicBlock *groupStartBlock, V4IR::BasicBlock *breakBlock, V4IR::BasicBlock *continueBlock, Loop *parent) + : labelledStatement(0), node(node), groupStartBlock(groupStartBlock), breakBlock(breakBlock), continueBlock(continueBlock), parent(parent) {} }; void enterEnvironment(AST::Node *node); void leaveEnvironment(); - void enterLoop(AST::Statement *node, V4IR::BasicBlock *breakBlock, V4IR::BasicBlock *continueBlock); + void enterLoop(AST::Statement *node, V4IR::BasicBlock *startBlock, V4IR::BasicBlock *breakBlock, V4IR::BasicBlock *continueBlock); void leaveLoop(); - + V4IR::BasicBlock *groupStartBlock() const + { + for (Loop *it = _loop; it; it = it->parent) + if (it->groupStartBlock) + return it->groupStartBlock; + return 0; + } V4IR::Expr *member(V4IR::Expr *base, const QString *name); V4IR::Expr *subscript(V4IR::Expr *base, V4IR::Expr *index); diff --git a/src/qml/qml/v4/qv4jsir.cpp b/src/qml/qml/v4/qv4jsir.cpp index a7d6a3c..6957067 100644 --- a/src/qml/qml/v4/qv4jsir.cpp +++ b/src/qml/qml/v4/qv4jsir.cpp @@ -628,9 +628,9 @@ const QString *Function::newString(const QString &text) return &*strings.insert(text); } -BasicBlock *Function::newBasicBlock(BasicBlockInsertMode mode) +BasicBlock *Function::newBasicBlock(BasicBlock *containingLoop, BasicBlockInsertMode mode) { - BasicBlock *block = new BasicBlock(this); + BasicBlock *block = new BasicBlock(this, containingLoop); return mode == InsertBlock ? insertBasicBlock(block) : block; } diff --git a/src/qml/qml/v4/qv4jsir_p.h b/src/qml/qml/v4/qv4jsir_p.h index f2c0bdb..b78654a 100644 --- a/src/qml/qml/v4/qv4jsir_p.h +++ b/src/qml/qml/v4/qv4jsir_p.h @@ -717,7 +717,7 @@ struct Function { DontInsertBlock }; - BasicBlock *newBasicBlock(BasicBlockInsertMode mode = InsertBlock); + BasicBlock *newBasicBlock(BasicBlock *containingLoop, BasicBlockInsertMode mode = InsertBlock); const QString *newString(const QString &text); void RECEIVE(const QString &name) { formals.append(newString(name)); } @@ -743,10 +743,14 @@ struct BasicBlock { QBitArray liveIn; QBitArray liveOut; int index; - int offset; AST::SourceLocation nextLocation; - BasicBlock(Function *function): function(function), index(-1), offset(-1) {} + BasicBlock(Function *function, BasicBlock *containingLoop) + : function(function) + , index(-1) + , _containingGroup(containingLoop) + , _groupStart(false) + {} ~BasicBlock() {} template inline Instr i(Instr i) { statements.append(i); return i; } @@ -803,6 +807,19 @@ struct BasicBlock { void dump(QTextStream &out, Stmt::Mode mode = Stmt::HIR); void appendStatement(Stmt *statement); + + BasicBlock *containingGroup() const + { return _containingGroup; } + + bool isGroupStart() const + { return _groupStart; } + + void markAsGroupStart() + { _groupStart = true; } + +private: + BasicBlock *_containingGroup; + bool _groupStart; }; class CloneExpr: protected V4IR::ExprVisitor diff --git a/src/qml/qml/v4/qv4ssa.cpp b/src/qml/qml/v4/qv4ssa.cpp index 696a887..65c2ef4 100644 --- a/src/qml/qml/v4/qv4ssa.cpp +++ b/src/qml/qml/v4/qv4ssa.cpp @@ -1392,7 +1392,7 @@ bool doEdgeSplitting(Function *f) #endif // create the basic block: - BasicBlock *newBB = new BasicBlock(f); + BasicBlock *newBB = new BasicBlock(f, bb->containingGroup()); newBB->index = f->basicBlocks.last()->index + 1; f->basicBlocks.append(newBB); Jump *s = f->New(); -- 2.7.4