From f71ce49202d2fb3008664e59bf5b73af5ab2c609 Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Tue, 8 May 2012 14:28:32 +0200 Subject: [PATCH] Optimize local arguments --- qv4codegen.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ qv4codegen_p.h | 1 + qv4ir_p.h | 8 +++++- 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/qv4codegen.cpp b/qv4codegen.cpp index eb4ebd4..d6685c3 100644 --- a/qv4codegen.cpp +++ b/qv4codegen.cpp @@ -153,11 +153,38 @@ void liveness(IR::Function *function) } while (changed); } -struct FindLocals: Visitor +struct ScanFunctionBody: Visitor { using Visitor::visit; + // search for locals QList locals; + bool directEval; + + ScanFunctionBody() + : directEval(false) + { + } + + void operator()(Node *node) { + directEval = false; + locals.clear(); + if (node) + node->accept(this); + } + +protected: + virtual bool visit(CallExpression *ast) + { + if (! directEval) { + if (IdentifierExpression *id = cast(ast->base)) { + if (id->name == QLatin1String("eval")) { + directEval = true; + } + } + } + return true; + } virtual bool visit(VariableDeclaration *ast) { @@ -196,6 +223,7 @@ void Codegen::operator()(AST::Program *node, IR::Module *module) _module = module; IR::Function *globalCode = _module->newFunction(QLatin1String("%entry")); + globalCode->directEval = true; // ### remove _function = globalCode; _block = _function->newBasicBlock(); _exitBlock = _function->newBasicBlock(); @@ -468,8 +496,18 @@ void Codegen::variableDeclaration(VariableDeclaration *ast) if (ast->expression) { Result expr = expression(ast->expression); - if (expr.code) + if (! expr.code) + expr.code = _block->CONST(IR::UndefinedType, 0); + + if (! _function->directEval) { + const int index = tempForLocalVariable(ast->name); + if (index != -1) { + _block->MOVE(_block->TEMP(index), *expr); + return; + } + } else { _block->MOVE(_block->NAME(ast->name.toString(), ast->identifierToken.startLine, ast->identifierToken.startColumn), *expr); + } } } @@ -895,9 +933,18 @@ bool Codegen::visit(FunctionExpression *ast) bool Codegen::visit(IdentifierExpression *ast) { + if (! _function->directEval) { + int index = tempForLocalVariable(ast->name); + if (index != -1) { + _expr.code = _block->TEMP(index); + return false; + } + } + _expr.code = _block->NAME(ast->name.toString(), ast->identifierToken.startLine, ast->identifierToken.startColumn); + return false; } @@ -1235,9 +1282,21 @@ void Codegen::linearize(IR::Function *function) void Codegen::defineFunction(FunctionExpression *ast, bool /*isDeclaration*/) { + ScanFunctionBody functionInfo; + functionInfo(ast->body); + IR::Function *function = _module->newFunction(ast->name.toString()); IR::BasicBlock *entryBlock = function->newBasicBlock(); IR::BasicBlock *exitBlock = function->newBasicBlock(); + + if (! functionInfo.directEval) { + for (int i = 0; i < functionInfo.locals.size(); ++i) { + unsigned t = entryBlock->newTemp(); + Q_ASSERT(t == unsigned(i)); + entryBlock->MOVE(entryBlock->TEMP(t), entryBlock->CONST(IR::UndefinedType, 0)); + } + } + unsigned returnAddress = entryBlock->newTemp(); entryBlock->MOVE(entryBlock->TEMP(returnAddress), entryBlock->CONST(IR::UndefinedType, 0)); @@ -1252,11 +1311,7 @@ void Codegen::defineFunction(FunctionExpression *ast, bool /*isDeclaration*/) _function->RECEIVE(it->name.toString()); } - FindLocals locals; - if (ast->body) - ast->body->accept(&locals); - - foreach (const QStringRef &local, locals.locals) { + foreach (const QStringRef &local, functionInfo.locals) { _function->LOCAL(local.toString()); } @@ -1277,6 +1332,15 @@ void Codegen::defineFunction(FunctionExpression *ast, bool /*isDeclaration*/) } } +int Codegen::tempForLocalVariable(const QStringRef &string) const +{ + for (int i = 0; i < _function->locals.size(); ++i) { + if (*_function->locals.at(i) == string) + return i; + } + return -1; +} + bool Codegen::visit(IdentifierPropertyName *ast) { _property = ast->id.toString(); diff --git a/qv4codegen_p.h b/qv4codegen_p.h index f1163c1..41e2484 100644 --- a/qv4codegen_p.h +++ b/qv4codegen_p.h @@ -74,6 +74,7 @@ protected: void linearize(IR::Function *function); void defineFunction(AST::FunctionExpression *ast, bool isDeclaration = false); + int tempForLocalVariable(const QStringRef &string) const; void statement(AST::Statement *ast); void statement(AST::ExpressionNode *ast); diff --git a/qv4ir_p.h b/qv4ir_p.h index b13ebdc..a77a58f 100644 --- a/qv4ir_p.h +++ b/qv4ir_p.h @@ -591,11 +591,17 @@ struct Function { QList formals; QList locals; void (*code)(VM::Context *); + bool directEval; template _Tp *New() { return new (pool->allocate(sizeof(_Tp))) _Tp(); } Function(Module *module, const QString &name) - : module(module), pool(&module->pool), tempCount(0), code(0) { this->name = newString(name); } + : module(module) + , pool(&module->pool) + , tempCount(0) + , code(0) + , directEval(false) + { this->name = newString(name); } ~Function(); -- 2.7.4