V4 regalloc: fix register spill choice under high pressure.
authorErik Verbruggen <erik.verbruggen@digia.com>
Wed, 23 Apr 2014 13:13:56 +0000 (15:13 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Thu, 24 Apr 2014 13:36:48 +0000 (15:36 +0200)
When a register is needed for an input parameter of an operation, and
all registers are already in use, do not select a register for spilling
when it is also used in the current operation.

Task-number: QTBUG-38451
Change-Id: I4a8f28cbaadce2dbb9d0c450ccac0ed572936c24
Reviewed-by: Albert Astals Cid <albert.astals@canonical.com>
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@digia.com>
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/jit/qv4regalloc.cpp

index 506fd8d..ba128c1 100644 (file)
@@ -1222,6 +1222,10 @@ void RegisterAllocator::linearScan()
 
         Q_ASSERT(!current.isFixedInterval());
 
+#ifdef DEBUG_REGALLOC
+        qDebug() << "** Position" << position;
+#endif // DEBUG_REGALLOC
+
         if (_info->canHaveRegister(current.temp())) {
             tryAllocateFreeReg(current, position);
             if (current.reg() == LifeTimeInterval::Invalid)
@@ -1374,11 +1378,15 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current, const int
     QVector<LifeTimeInterval *> nextUseRangeForReg(nextUsePos.size(), 0);
     Q_ASSERT(nextUsePos.size() > 0);
 
+    const bool definedAtCurrentPosition = !current.isSplitFromInterval() && current.start() == position;
+
     for (int i = 0, ei = _active.size(); i != ei; ++i) {
         LifeTimeInterval &it = _active[i];
         if (it.isFP() == needsFPReg) {
             int nu = it.isFixedInterval() ? 0 : nextUse(it.temp(), current.firstPossibleUsePosition(isPhiTarget));
-            if (nu != -1 && nu < nextUsePos[it.reg()]) {
+            if (nu == position && !definedAtCurrentPosition) {
+                nextUsePos[it.reg()] = 0;
+            } else if (nu != -1 && nu < nextUsePos[it.reg()]) {
                 nextUsePos[it.reg()] = nu;
                 nextUseRangeForReg[it.reg()] = &it;
             } else if (nu == -1 && nextUsePos[it.reg()] == INT_MAX) {