diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-08-19 11:33:22 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-08-23 09:04:38 +0000 |
commit | 34c82d54b70409202b36c8ec51442fa56014ba8a (patch) | |
tree | 47f278cb94f32c46634f5843431057e9195da8fc /src | |
parent | fd57e1449dc974417f3409a4da7338d7e8a6e7c8 (diff) |
V4: Replace a QSet with a QVector in calculateOptionalJumps
Instead of storing a bunch of statement IDs in a QSet, the parent basic
block of the terminator statement (specifically: the jump) is used as
an index into a bit vector. If the bit is set, this indicates that the
jump can be omitted.
This reduces the number of allocations from 1 hash node per optional
jump, to 1 per function. The allocation will also be smaller then a
hash node.
Change-Id: Ia34468534b96dd9cefa837523bf89ad233de92e8
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa.cpp | 36 | ||||
-rw-r--r-- | src/qml/compiler/qv4ssa_p.h | 3 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm.cpp | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4util_p.h | 6 |
7 files changed, 42 insertions, 17 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index fda5b4cdd0..d54d939e93 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -209,7 +209,7 @@ void InstructionSelection::run(int functionIndex) ConvertTemps().toStackSlots(_function); } - QSet<IR::Jump *> removableJumps = opt.calculateOptionalJumps(); + BitVector removableJumps = opt.calculateOptionalJumps(); qSwap(_removableJumps, removableJumps); IR::Stmt *cs = 0; @@ -948,7 +948,7 @@ void InstructionSelection::visitJump(IR::Jump *s) { if (s->target == _nextBlock) return; - if (_removableJumps.contains(s)) + if (_removableJumps.at(_block->index())) return; addDebugInstruction(); diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 2d2bb91228..1d9befd7ff 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -54,6 +54,7 @@ #include <private/qv4global_p.h> #include <private/qv4isel_p.h> #include <private/qv4isel_util_p.h> +#include <private/qv4util_p.h> #include <private/qv4jsir_p.h> #include <private/qv4value_p.h> #include "qv4instr_moth_p.h" @@ -197,7 +198,7 @@ private: uchar *_codeNext; uchar *_codeEnd; - QSet<IR::Jump *> _removableJumps; + BitVector _removableJumps; IR::Stmt *_currentStatement; QScopedPointer<CompilationUnit> compilationUnit; diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index 283fb24897..6d55b43354 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -5463,14 +5463,30 @@ LifeTimeIntervals::Ptr Optimizer::lifeTimeIntervals() const return lifeRanges.intervals(); } -QSet<Jump *> Optimizer::calculateOptionalJumps() +static int countPhis(BasicBlock *bb) { - QSet<Jump *> optional; - QSet<BasicBlock *> reachableWithoutJump; + int count = 0; + for (Stmt *s : bb->statements()) { + if (s->isa<Phi>()) + ++count; + else + break; + } + return count; +} + +// Basic blocks can have only 1 terminator. This function returns a bit vector, where a 1 on a +// certain index indicates that the terminator (jump) at the end of the basic block with that index +// can be omitted. +BitVector Optimizer::calculateOptionalJumps() +{ const int maxSize = function->basicBlockCount(); - optional.reserve(maxSize); - reachableWithoutJump.reserve(maxSize); + BitVector optional(maxSize, false); + if (maxSize < 2) + return optional; + + BitVector reachableWithoutJump(maxSize, false); for (int i = maxSize - 1; i >= 0; --i) { BasicBlock *bb = function->basicBlock(i); @@ -5478,17 +5494,17 @@ QSet<Jump *> Optimizer::calculateOptionalJumps() continue; if (Jump *jump = bb->statements().last()->asJump()) { - if (reachableWithoutJump.contains(jump->target)) { - if (bb->statements().size() > 1) + if (reachableWithoutJump.at(jump->target->index())) { + if (bb->statements().size() - countPhis(bb)> 1) reachableWithoutJump.clear(); - optional.insert(jump); - reachableWithoutJump.insert(bb); + optional.setBit(bb->index()); + reachableWithoutJump.setBit(bb->index()); continue; } } reachableWithoutJump.clear(); - reachableWithoutJump.insert(bb); + reachableWithoutJump.setBit(bb->index()); } return optional; diff --git a/src/qml/compiler/qv4ssa_p.h b/src/qml/compiler/qv4ssa_p.h index 386990a9f5..0f8f9a401e 100644 --- a/src/qml/compiler/qv4ssa_p.h +++ b/src/qml/compiler/qv4ssa_p.h @@ -53,6 +53,7 @@ #include "qv4jsir_p.h" #include "qv4isel_util_p.h" +#include "qv4util_p.h" #include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE @@ -235,7 +236,7 @@ public: LifeTimeIntervals::Ptr lifeTimeIntervals() const; - QSet<IR::Jump *> calculateOptionalJumps(); + BitVector calculateOptionalJumps(); static void showMeTheCode(Function *function, const char *marker); diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 9759b72794..0baf7580da 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -294,7 +294,7 @@ void InstructionSelection::run(int functionIndex) IR::Optimizer::showMeTheCode(_function, "After stack slot allocation"); calculateRegistersToSave(Assembler::getRegisterInfo()); // FIXME: this saves all registers. We can probably do with a subset: those that are not used by the register allocator. } - QSet<IR::Jump *> removableJumps = opt.calculateOptionalJumps(); + BitVector removableJumps = opt.calculateOptionalJumps(); qSwap(_removableJumps, removableJumps); Assembler* oldAssembler = _as; @@ -1390,7 +1390,7 @@ void InstructionSelection::constructValue(IR::Expr *value, IR::ExprList *args, I void InstructionSelection::visitJump(IR::Jump *s) { - if (!_removableJumps.contains(s)) + if (!_removableJumps.at(_block->index())) _as->jumpToBlock(_block, s->target); } diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h index 5bca879a77..0e909820e7 100644 --- a/src/qml/jit/qv4isel_masm_p.h +++ b/src/qml/jit/qv4isel_masm_p.h @@ -54,6 +54,7 @@ #include "private/qv4jsir_p.h" #include "private/qv4isel_p.h" #include "private/qv4isel_util_p.h" +#include "private/qv4util_p.h" #include "private/qv4value_p.h" #include "private/qv4lookup_p.h" @@ -272,7 +273,7 @@ private: } IR::BasicBlock *_block; - QSet<IR::Jump *> _removableJumps; + BitVector _removableJumps; Assembler* _as; QScopedPointer<CompilationUnit> compilationUnit; diff --git a/src/qml/jsruntime/qv4util_p.h b/src/qml/jsruntime/qv4util_p.h index 59c12c5e46..2669a3e4bf 100644 --- a/src/qml/jsruntime/qv4util_p.h +++ b/src/qml/jsruntime/qv4util_p.h @@ -90,6 +90,9 @@ public: : bits(size, value) {} + void clear() + { bits = std::vector<bool>(bits.size(), false); } + void reserve(int size) { bits.reserve(size); } @@ -153,6 +156,9 @@ public: : bits(size, value) {} + void clear() + { bits = QBitArray(bits.size(), false); } + void reserve(int size) { Q_UNUSED(size); } |