aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-08-27 15:13:03 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-28 20:22:07 +0200
commit6e79a590c541c420e7f481bbc876c9c18669ff0b (patch)
treed75a71fc5c7976ff08a8765a2770fc18bc311722 /src
parent01f3a34eda0a6045db76c703b4c2683b7600fb60 (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.cpp36
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 &current, const int
}
void RegisterAllocator::longestAvailableReg(const QVector<int> &nextUses, int &reg,
- 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 &current,