From 4f3a02c7cde6589ecbdbc4f0dcf20793d2d604db Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Wed, 23 Apr 2014 15:13:56 +0200 Subject: [PATCH] V4 regalloc: fix register spill choice under high pressure. 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 Reviewed-by: Fawzi Mohamed Reviewed-by: Lars Knoll --- src/qml/jit/qv4regalloc.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index 506fd8d..ba128c1 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -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 ¤t, const int QVector 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()] = ⁢ } else if (nu == -1 && nextUsePos[it.reg()] == INT_MAX) { -- 2.7.4