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>
This commit is contained in:
parent
39286a50c3
commit
b926452f6c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue