Q_ASSERT(!current.isFixedInterval());
Q_ASSERT(current.reg() == LifeTimeInterval::Invalid);
+ const bool isPhiTarget = _info->isPhiTarget(current.temp());
+ if (isPhiTarget && !current.isSplitFromInterval()) {
+ split(current, position + 1, true);
+ _inactive.append(current);
+ return;
+ }
+
const bool needsFPReg = isFP(current.temp());
QVector<int> nextUsePos(needsFPReg ? _fpRegisters.size() : _normalRegisters.size(), INT_MAX);
QVector<LifeTimeInterval *> nextUseRangeForReg(nextUsePos.size(), 0);
Q_ASSERT(nextUsePos.size() > 0);
- const bool isPhiTarget = _info->isPhiTarget(current.temp());
for (int i = 0, ei = _active.size(); i != ei; ++i) {
LifeTimeInterval &it = _active[i];
if (it.isFP() == needsFPReg) {
if (nu != -1 && nu < nextUsePos[it.reg()]) {
nextUsePos[it.reg()] = nu;
nextUseRangeForReg[it.reg()] = ⁢
+ } else if (nu == -1 && nextUsePos[it.reg()] == INT_MAX) {
+ // in a loop, the range can be active, but only used before the current position (e.g. in a loop header or phi node)
+ nextUseRangeForReg[it.reg()] = ⁢
}
}
}
}
int reg, nextUsePos_reg;
- longestAvailableReg(nextUsePos, reg, nextUsePos_reg);
+ longestAvailableReg(nextUsePos, reg, nextUsePos_reg, current.end());
if (current.start() > nextUsePos_reg) {
// all other intervals are used before current, so it is best to spill current itself
- // Note: even if we absolutely need a register (e.g. with a floating-point add), we have
- // a scratch register available, and so we can still use a spill slot as the destination.
#ifdef DEBUG_REGALLOC
QTextStream out(stderr, QIODevice::WriteOnly);
out << "*** splitting current for range ";current.dump(out);out<<endl;
current.setReg(reg);
_lastAssignedRegister.insert(current.temp(), reg);
Q_ASSERT(nextUseRangeForReg[reg]);
+ Q_ASSERT(!nextUseRangeForReg[reg]->isFixedInterval());
split(*nextUseRangeForReg[reg], position);
splitInactiveAtEndOfLifetimeHole(reg, needsFPReg, position);
#ifdef DEBUG_REGALLOC
out << "***-- current range intersects with a fixed reg use at "<<ni<<", so splitting it."<<endl;
#endif // DEBUG_REGALLOC
- split(current, ni);
+ split(current, ni, true);
}
}
}
{
for (int i = 0, ei = _inactive.size(); i != ei; ++i) {
LifeTimeInterval &interval = _inactive[i];
+ if (interval.isFixedInterval())
+ continue;
if (isFPReg == interval.isFP() && interval.reg() == reg) {
LifeTimeInterval::Ranges ranges = interval.ranges();
int endOfLifetimeHole = -1;
void tryAllocateFreeReg(LifeTimeInterval ¤t, const int position);
void allocateBlockedReg(LifeTimeInterval ¤t, const int position);
void longestAvailableReg(const QVector<int> &nextUses, int ®, int &nextUsePos_reg,
- int lastUse = -1) const;
+ int lastUse) const;
int nextIntersection(const LifeTimeInterval ¤t, const LifeTimeInterval &another,
const int position) const;
int nextUse(const V4IR::Temp &t, int startPosition) const;