diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2013-08-27 15:13:03 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-28 20:22:07 +0200 |
commit | 6e79a590c541c420e7f481bbc876c9c18669ff0b (patch) | |
tree | d75a71fc5c7976ff08a8765a2770fc18bc311722 /src | |
parent | 01f3a34eda0a6045db76c703b4c2683b7600fb60 (diff) |
V4 regalloc: fix off-by-one in availability calculation.
Simplified the algorithm, and use it to iterate over all registers. The
previous version did not initialize bestReg correctly, thereby skipping
the first register (which could also be the best one).
Change-Id: I7e33f93a27e8fe64cd00acac755cf67ca5f0b1b8
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4regalloc.cpp | 36 |
1 files changed, 10 insertions, 26 deletions
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp index ddac257d1a..a33d6e7eee 100644 --- a/src/qml/compiler/qv4regalloc.cpp +++ b/src/qml/compiler/qv4regalloc.cpp @@ -1445,35 +1445,19 @@ void RegisterAllocator::allocateBlockedReg(LifeTimeInterval ¤t, const int } void RegisterAllocator::longestAvailableReg(const QVector<int> &nextUses, int ®, - int &nextUsePos_reg, int lastUse) const + int &freeUntilPos_reg, int lastUse) const { - reg = 0; - nextUsePos_reg = nextUses[reg]; - - int bestReg = -1, nextUsePos_bestReg = INT_MAX; - - for (int i = 1, ei = nextUses.size(); i != ei; ++i) { - int nextUsePos_i = nextUses[i]; - if (nextUsePos_i > nextUsePos_reg) { - reg = i; - nextUsePos_reg = nextUsePos_i; - } - if (lastUse != -1) { - // if multiple registers are available for the whole life-time of an interval, then - // bestReg contains the one that is blocked first another interval. - if (nextUsePos_i > lastUse && nextUsePos_i < nextUsePos_bestReg) { - bestReg = i; - nextUsePos_bestReg = nextUsePos_i; - } + reg = LifeTimeInterval::Invalid; + freeUntilPos_reg = 0; + + for (int candidate = 0, candidateEnd = nextUses.size(); candidate != candidateEnd; ++candidate) { + int fp = nextUses[candidate]; + if ((freeUntilPos_reg < lastUse && fp > freeUntilPos_reg) + || (freeUntilPos_reg >= lastUse && fp >= lastUse && freeUntilPos_reg > fp)) { + reg = candidate; + freeUntilPos_reg = fp; } } - - // if the hinted register is available for the whole life-time, use that one, and if not, use - // the bestReg. - if (bestReg != -1) { - reg = bestReg; - nextUsePos_reg = nextUsePos_bestReg; - } } int RegisterAllocator::nextIntersection(const LifeTimeInterval ¤t, |