From: Erik Verbruggen Date: Fri, 22 Aug 2014 10:11:40 +0000 (+0200) Subject: V4: disable type inference and loop peeling for the interpreter. X-Git-Tag: v5.3.99+beta1~114 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b926452f6c98e35fd87706fc637240cb47bac4bf;p=platform%2Fupstream%2Fqtdeclarative.git V4: disable type inference and loop peeling for the interpreter. Loop peeling is always disabled. Type inference is still enabled for QML code, because of the static-type nature of the properties. This speeds up crypto.js by 20%. Change-Id: Ibf51cb36f8904d64df0793980d463451dfd361e2 Reviewed-by: Simon Hausmann --- diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index b960f4b..90f775f 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -218,6 +218,7 @@ bool QQmlTypeCompiler::compile() QV4::ExecutionEngine *v4 = engine->v4engine(); QScopedPointer isel(v4->iselFactory->create(engine, v4->executableAllocator, &document->jsModule, &document->jsGenerator)); isel->setUseFastLookups(false); + isel->setUseTypeInference(true); document->javaScriptCompilationUnit = isel->compile(/*generated unit data*/false); } diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index a0a8948..40a4484 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -321,7 +321,9 @@ InstructionSelection::InstructionSelection(QQmlEnginePrivate *qmlEngine, QV4::Ex , _codeEnd(0) , _currentStatement(0) , compilationUnit(new CompilationUnit) -{} +{ + setUseTypeInference(false); +} InstructionSelection::~InstructionSelection() { @@ -351,7 +353,7 @@ void InstructionSelection::run(int functionIndex) qSwap(codeEnd, _codeEnd); IR::Optimizer opt(_function); - opt.run(qmlEngine); + opt.run(qmlEngine, useTypeInference, /*peelLoops =*/ false); if (opt.isInSSA()) { static const bool doStackSlotAllocation = qgetenv("QV4_NO_INTERPRETER_STACK_SLOT_ALLOCATION").isEmpty(); diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index 9e15e45..f160954 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -51,6 +51,7 @@ using namespace QV4::IR; EvalInstructionSelection::EvalInstructionSelection(QV4::ExecutableAllocator *execAllocator, Module *module, QV4::Compiler::JSUnitGenerator *jsGenerator) : useFastLookups(true) + , useTypeInference(true) , executableAllocator(execAllocator) , irModule(module) { diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index 7048b33..984e8ab 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -60,6 +60,7 @@ public: QV4::CompiledData::CompilationUnit *compile(bool generateUnitData = true); void setUseFastLookups(bool b) { useFastLookups = b; } + void setUseTypeInference(bool onoff) { useTypeInference = onoff; } int registerString(const QString &str) { return jsGenerator->registerString(str); } uint registerIndexedGetterLookup() { return jsGenerator->registerIndexedGetterLookup(); } @@ -76,6 +77,7 @@ protected: virtual QV4::CompiledData::CompilationUnit *backendCompileStep() = 0; bool useFastLookups; + bool useTypeInference; QV4::ExecutableAllocator *executableAllocator; QV4::Compiler::JSUnitGenerator *jsGenerator; QScopedPointer ownJSGenerator; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 53d0630..e23ca1d 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -989,6 +989,9 @@ void IRPrinter::print(BasicBlock *bb) printBlockStart(); foreach (Stmt *s, currentBB->statements()) { + if (!s) + continue; + QByteArray str; QBuffer buf(&str); buf.open(QIODevice::WriteOnly); diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 774d8fb..d67b88b 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -1794,6 +1794,9 @@ public: void reset() { + worklist.assign(worklist.size(), false); + worklistSize = 0; + foreach (Stmt *s, stmts) { if (!s) continue; @@ -3934,6 +3937,7 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df) // constant propagation: if (Const *sourceConst = m->source->asConst()) { + Q_ASSERT(sourceConst->type != UnknownType); replaceUses(targetTemp, sourceConst, W); defUses.removeDef(*targetTemp); W.remove(s); @@ -3998,7 +4002,8 @@ void optimizeSSA(StatementWorklist &W, DefUses &defUses, DominatorTree &df) doneSomething = true; break; case OpUPlus: - constOperand->type = unop->type; + if (unop->type != UnknownType) + constOperand->type = unop->type; doneSomething = true; break; case OpCompl: @@ -5057,7 +5062,7 @@ Optimizer::Optimizer(IR::Function *function) , inSSA(false) {} -void Optimizer::run(QQmlEnginePrivate *qmlEngine) +void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool peelLoops) { #if defined(SHOW_SSA) qout << "##### NOW IN FUNCTION " << (function->name ? qPrintable(*function->name) : "anonymous!") @@ -5093,13 +5098,15 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine) showMeTheCode(function); // cfg2dot(function, loopDetection.allLoops()); - QVector innerLoops = loopDetection.innermostLoops(); - LoopPeeling(df).run(innerLoops); + if (peelLoops) { + QVector innerLoops = loopDetection.innermostLoops(); + LoopPeeling(df).run(innerLoops); -// cfg2dot(function, loopDetection.allLoops()); - showMeTheCode(function); - if (!innerLoops.isEmpty()) - verifyImmediateDominators(df, function); +// cfg2dot(function, loopDetection.allLoops()); + showMeTheCode(function); + if (!innerLoops.isEmpty()) + verifyImmediateDominators(df, function); + } } verifyCFG(function); @@ -5123,18 +5130,20 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine) StatementWorklist worklist(function); -// qout << "Running type inference..." << endl; - TypeInference(qmlEngine, defUses).run(worklist); - showMeTheCode(function); + if (doTypeInference) { +// qout << "Running type inference..." << endl; + TypeInference(qmlEngine, defUses).run(worklist); + showMeTheCode(function); -// qout << "Doing reverse inference..." << endl; - ReverseInference(defUses).run(function); -// showMeTheCode(function); +// qout << "Doing reverse inference..." << endl; + ReverseInference(defUses).run(function); +// showMeTheCode(function); -// qout << "Doing type propagation..." << endl; - TypePropagation(defUses).run(function, worklist); -// showMeTheCode(function); - verifyNoPointerSharing(function); +// qout << "Doing type propagation..." << endl; + TypePropagation(defUses).run(function, worklist); +// showMeTheCode(function); + verifyNoPointerSharing(function); + } static bool doOpt = qgetenv("QV4_NO_OPT").isEmpty(); if (doOpt) { diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index 72f3eb3..21a5b03 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -207,7 +207,7 @@ class Q_QML_PRIVATE_EXPORT Optimizer public: Optimizer(Function *function); - void run(QQmlEnginePrivate *qmlEngine); + void run(QQmlEnginePrivate *qmlEngine, bool doTypeInference = true, bool peelLoops = true); void convertOutOfSSA(); bool isInSSA() const