aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2015-03-02 14:35:28 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-03-03 10:03:59 +0000
commit63f7a61cbfc787804b658729ecaf2a8d8da26e70 (patch)
tree116bd7cc6ce9f79fe7826a1914835a3f5abe4230 /src/qml/jit
parentb368fe0167666cc7ce264705653107ffc21ac8cc (diff)
V4: fix regalloc for loops with many life&changing vars.
When all registers are in use, and one needs to be spilled, the register whose use is the furthest in the future will be chosen. What needs to be taken into account is that any use that can also work from the stack can be skipped, because it does not require the value to be in a register. Task-number: QTBUG-44687 Change-Id: Ide624b190603d9a22f992d4ae5daa3ce8d94472c Reviewed-by: Fawzi Mohamed <fawzi.mohamed@theqtcompany.com>
Diffstat (limited to 'src/qml/jit')
-rw-r--r--src/qml/jit/qv4regalloc.cpp15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp
index b34cd7bd68..ae06a99d2a 100644
--- a/src/qml/jit/qv4regalloc.cpp
+++ b/src/qml/jit/qv4regalloc.cpp
@@ -1604,7 +1604,7 @@ void RegisterAllocator::tryAllocateFreeReg(LifeTimeInterval &current)
if (freeUntilPos_reg == 0) {
// no register available without spilling
if (DebugRegAlloc)
- qDebug() << "*** no register available for %" << current.temp().index;
+ qDebug("*** no register available for %u", current.temp().index);
return;
} else if (current.end() < freeUntilPos_reg) {
// register available for the whole interval
@@ -1715,7 +1715,7 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current)
Q_ASSERT(nextUse);
Q_ASSERT(!nextUse->isFixedInterval());
- split(*nextUse, position);
+ split(*nextUse, position, /*skipOptionalRegisterUses =*/ true);
// We might have chosen a register that is used by a range that has a hole in its life time.
// If that's the case, check if the current interval completely fits in the hole. Or rephrased:
@@ -1765,6 +1765,9 @@ int RegisterAllocator::nextIntersection(const LifeTimeInterval &current,
}
/// Find the first use after the start position for the given temp.
+///
+/// This is only called when all registers are in use, and when one of them has to be spilled to the
+/// stack. So, uses where a register is optional can be ignored.
int RegisterAllocator::nextUse(const Temp &t, int startPosition) const
{
typedef std::vector<Use>::const_iterator ConstIt;
@@ -1772,9 +1775,11 @@ int RegisterAllocator::nextUse(const Temp &t, int startPosition) const
const std::vector<Use> &usePositions = _info->uses(t);
const ConstIt cend = usePositions.end();
for (ConstIt it = usePositions.begin(); it != cend; ++it) {
- const int usePos = it->pos;
- if (usePos >= startPosition)
- return usePos;
+ if (it->mustHaveRegister()) {
+ const int usePos = it->pos;
+ if (usePos >= startPosition)
+ return usePos;
+ }
}
return -1;