Bug 1126629 - Refine handling of minimal intervals in the backtracking allocator, r=sunfish.

This commit is contained in:
Brian Hackett 2015-02-10 04:40:06 -07:00
parent 170b656ad6
commit 9db9368ef2

View File

@ -1678,9 +1678,11 @@ BacktrackingAllocator::minimalInterval(const LiveInterval *interval, bool *pfixe
return minimalDef(interval, reg.ins());
}
bool fixed = false, minimal = false;
bool fixed = false, minimal = false, multiple = false;
for (UsePositionIterator iter = interval->usesBegin(); iter != interval->usesEnd(); iter++) {
if (iter != interval->usesBegin())
multiple = true;
LUse *use = iter->use;
switch (use->policy()) {
@ -1702,6 +1704,11 @@ BacktrackingAllocator::minimalInterval(const LiveInterval *interval, bool *pfixe
}
}
// If an interval contains a fixed use and at least one other use,
// splitAtAllRegisterUses will split each use into a different interval.
if (multiple && fixed)
minimal = false;
if (pfixed)
*pfixed = fixed;
return minimal;
@ -2024,11 +2031,15 @@ BacktrackingAllocator::splitAtAllRegisterUses(LiveInterval *interval)
// interval that covers both the instruction's input and output, so
// that the register is not reused for an output.
CodePosition from = inputOf(ins);
CodePosition to = iter->pos.next();
CodePosition to = iter->use->usedAtStart() ? outputOf(ins) : iter->pos.next();
// Use the same interval for duplicate use positions, except when
// the uses are fixed (they may require incompatible registers).
if (newIntervals.empty() || newIntervals.back()->end() != to || iter->use->policy() == LUse::FIXED) {
if (newIntervals.empty() ||
newIntervals.back()->end() != to ||
newIntervals.back()->usesBegin()->use->policy() == LUse::FIXED ||
iter->use->policy() == LUse::FIXED)
{
if (!addLiveInterval(newIntervals, vreg, spillInterval, from, to))
return false;
}