V4 RegAlloc: fix callee saved register range handling
authorErik Verbruggen <erik.verbruggen@digia.com>
Fri, 8 Aug 2014 14:05:54 +0000 (16:05 +0200)
committerErik Verbruggen <erik.verbruggen@digia.com>
Wed, 13 Aug 2014 10:53:11 +0000 (12:53 +0200)
This makes sure that the index of the fixed(FP)RegisterRanges matches
the indexes for normal-/fpRegisters, because this index is used to check
if a chosen register intersects with a fixed (= caller saved) register
at call sites.

Change-Id: Ie31554dbe8ed99cb38ca6b2506da663be41d82f6
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jit/qv4regalloc.cpp

index 50f35e3..588b6d9 100644 (file)
@@ -1350,24 +1350,26 @@ void RegisterAllocator::prepareRanges()
         ltiWithCalls.addRange(callPosition, callPosition);
 
     const int regCount = _normalRegisters.size();
-    _fixedRegisterRanges.reserve(regCount);
+    _fixedRegisterRanges.resize(regCount);
     for (int reg = 0; reg < regCount; ++reg) {
         if (_normalRegisters.at(reg)->isCallerSaved()) {
             LifeTimeInterval *lti = cloneFixedInterval(reg, false, ltiWithCalls);
-            _fixedRegisterRanges.append(lti);
-            if (lti->isValid())
+            if (lti->isValid()) {
+                _fixedRegisterRanges[reg] = lti;
                 _active.append(lti);
+            }
         }
     }
 
     const int fpRegCount = _fpRegisters.size();
-    _fixedFPRegisterRanges.reserve(fpRegCount);
+    _fixedFPRegisterRanges.resize(fpRegCount);
     for (int fpReg = 0; fpReg < fpRegCount; ++fpReg) {
         if (_fpRegisters.at(fpReg)->isCallerSaved()) {
             LifeTimeInterval *lti = cloneFixedInterval(fpReg, true, ltiWithCalls);
-            _fixedFPRegisterRanges.append(lti);
-            if (lti->isValid())
+            if (lti->isValid()) {
+                _fixedFPRegisterRanges[fpReg] = lti;
                 _active.append(lti);
+            }
         }
     }
 }
@@ -1681,16 +1683,18 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval &current)
     splitInactiveAtEndOfLifetimeHole(reg, needsFPReg, position);
 
     // make sure that current does not intersect with the fixed interval for reg
-    const LifeTimeInterval &fixedRegRange = needsFPReg ? *_fixedFPRegisterRanges.at(reg)
-                                                       : *_fixedRegisterRanges.at(reg);
-    int ni = nextIntersection(current, fixedRegRange);
-    if (ni != -1) {
-        if (DebugRegAlloc) {
-            QTextStream out(stderr, QIODevice::WriteOnly);
-            out << "***-- current range intersects with a fixed reg use at " << ni << ", so splitting it." << endl;
+    const LifeTimeInterval *fixedRegRange = needsFPReg ? _fixedFPRegisterRanges.at(reg)
+                                                       : _fixedRegisterRanges.at(reg);
+    if (fixedRegRange) {
+        int ni = nextIntersection(current, *fixedRegRange);
+        if (ni != -1) {
+            if (DebugRegAlloc) {
+                QTextStream out(stderr, QIODevice::WriteOnly);
+                out << "***-- current range intersects with a fixed reg use at " << ni << ", so splitting it." << endl;
+            }
+            // current does overlap with a fixed interval, so split current before that intersection.
+            split(current, ni, true);
         }
-        // current does overlap with a fixed interval, so split current before that intersection.
-        split(current, ni, true);
     }
 }