diff options
-rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 7 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth_p.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 39 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa_p.h | 2 |
6 files changed, 55 insertions, 1 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index 1146c08d6c..98558bf9bc 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -667,6 +667,8 @@ void InstructionSelection::run(int functionIndex) ConvertTemps().toStackSlots(_function); } V4IR::Optimizer::showMeTheCode(_function); + QSet<V4IR::Jump *> removableJumps = opt.calculateOptionalJumps(); + qSwap(_removableJumps, removableJumps); Assembler* oldAssembler = _as; _as = new Assembler(this, _function, executableAllocator, 6); // 6 == max argc for calls to built-ins with an argument array @@ -715,6 +717,7 @@ void InstructionSelection::run(int functionIndex) qSwap(_reentryBlocks, reentryBlocks); delete _as; _as = oldAssembler; + qSwap(_removableJumps, removableJumps); } void *InstructionSelection::addConstantTable(QVector<Primitive> *values) @@ -1675,7 +1678,8 @@ void InstructionSelection::constructValue(V4IR::Temp *value, V4IR::ExprList *arg void InstructionSelection::visitJump(V4IR::Jump *s) { - _as->jumpToBlock(_block, s->target); + if (!_removableJumps.contains(s)) + _as->jumpToBlock(_block, s->target); } void InstructionSelection::visitCJump(V4IR::CJump *s) diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h index 013c2ef8ed..1a8df9a833 100644 --- a/src/qml/compiler/qv4isel_masm_p.h +++ b/src/qml/compiler/qv4isel_masm_p.h @@ -1550,6 +1550,7 @@ private: V4IR::BasicBlock *_block; V4IR::Function* _function; + QSet<V4IR::Jump *> _removableJumps; Assembler* _as; QSet<V4IR::BasicBlock*> _reentryBlocks; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 7c999edb59..0b9473b1d3 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -252,7 +252,11 @@ void InstructionSelection::run(int functionIndex) stackSlotAllocator = new StackSlotAllocator(opt.lifeRanges(), _function->tempCount); opt.convertOutOfSSA(); } + qSwap(_stackSlotAllocator, stackSlotAllocator); + QSet<V4IR::Jump *> removableJumps = opt.calculateOptionalJumps(); + qSwap(_removableJumps, removableJumps); + V4IR::Stmt *cs = 0; qSwap(_currentStatement, cs); @@ -289,6 +293,7 @@ void InstructionSelection::run(int functionIndex) codeRefs.insert(_function, squeezeCode()); qSwap(_currentStatement, cs); + qSwap(_removableJumps, removableJumps); qSwap(_stackSlotAllocator, stackSlotAllocator); delete stackSlotAllocator; qSwap(_function, function); @@ -629,6 +634,8 @@ void InstructionSelection::visitJump(V4IR::Jump *s) { if (s->target == _nextBlock) return; + if (_removableJumps.contains(s)) + return; Instruction::Jump jump; jump.offset = 0; diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index ca03c5fa30..725dd264aa 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -175,6 +175,7 @@ private: uchar *_codeEnd; StackSlotAllocator *_stackSlotAllocator; + QSet<V4IR::Jump *> _removableJumps; V4IR::Stmt *_currentStatement; CompilationUnit *compilationUnit; diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 6ad9a5731f..c41c9cfe80 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -2976,6 +2976,45 @@ QVector<LifeTimeInterval> Optimizer::lifeRanges() const return lifeRanges.ranges(); } +QSet<Jump *> Optimizer::calculateOptionalJumps() +{ + QSet<Jump *> optional; + QSet<BasicBlock *> reachableWithoutJump; + + const int maxSize = function->basicBlocks.size(); + optional.reserve(maxSize); + reachableWithoutJump.reserve(maxSize); + + for (int i = function->basicBlocks.size() - 1; i >= 0; --i) { + BasicBlock *bb = function->basicBlocks[i]; + + if (Jump *jump = bb->statements.last()->asJump()) { + if (reachableWithoutJump.contains(jump->target)) { + if (bb->statements.size() > 1) + reachableWithoutJump.clear(); + optional.insert(jump); + reachableWithoutJump.insert(bb); + continue; + } + } + + reachableWithoutJump.clear(); + reachableWithoutJump.insert(bb); + } + +#if 0 + QTextStream out(stdout, QIODevice::WriteOnly); + out << "Jumps to ignore:" << endl; + foreach (Jump *j, removed) { + out << "\t" << j->id << ": "; + j->dump(out, Stmt::MIR); + out << endl; + } +#endif + + return optional; +} + void Optimizer::showMeTheCode(Function *function) { ::showMeTheCode(function); diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index ceaef9f938..fc84ffd551 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -141,6 +141,8 @@ public: QVector<LifeTimeInterval> lifeRanges() const; + QSet<V4IR::Jump *> calculateOptionalJumps(); + static void showMeTheCode(Function *function); private: |