diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-08-22 12:11:40 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-08-26 16:45:26 +0200 |
commit | b926452f6c98e35fd87706fc637240cb47bac4bf (patch) | |
tree | 4cda0562b5544115177b732ad5df6f092d87d0a6 | |
parent | 39286a50c32321981adb82ea47c93b7398b257d8 (diff) |
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 <simon.hausmann@digia.com>
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.cpp | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4jsir.cpp | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 45 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa_p.h | 2 |
7 files changed, 39 insertions, 21 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index b960f4bb2d..90f775f781 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<QV4::EvalInstructionSelection> 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 a0a89482d6..40a44844ce 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 9e15e457cf..f160954f84 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 7048b33202..984e8ab4bf 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<QV4::Compiler::JSUnitGenerator> ownJSGenerator; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index 53d06303c3..e23ca1d516 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 774d8fb88c..d67b88b718 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<LoopDetection::LoopInfo *> innerLoops = loopDetection.innermostLoops(); - LoopPeeling(df).run(innerLoops); + if (peelLoops) { + QVector<LoopDetection::LoopInfo *> 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 72f3eb3716..21a5b038b6 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 |