mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 983752 - Consider conflicting intervals when splitting backtracking intervals, r=sunfish.
This commit is contained in:
parent
babcab571c
commit
a4860450bf
@ -479,7 +479,7 @@ BacktrackingAllocator::processInterval(LiveInterval *interval)
|
||||
bool canAllocate = setIntervalRequirement(interval);
|
||||
|
||||
bool fixed;
|
||||
LiveInterval *conflict;
|
||||
LiveInterval *conflict = nullptr;
|
||||
for (size_t attempt = 0;; attempt++) {
|
||||
if (canAllocate) {
|
||||
bool success = false;
|
||||
@ -520,7 +520,7 @@ BacktrackingAllocator::processInterval(LiveInterval *interval)
|
||||
|
||||
if (canAllocate && fixed)
|
||||
return splitAcrossCalls(interval);
|
||||
return chooseIntervalSplit(interval);
|
||||
return chooseIntervalSplit(interval, conflict);
|
||||
}
|
||||
}
|
||||
|
||||
@ -583,9 +583,14 @@ BacktrackingAllocator::setIntervalRequirement(LiveInterval *interval)
|
||||
|
||||
// Set a hint if another interval in the same group is in a register.
|
||||
if (VirtualRegisterGroup *group = reg->group()) {
|
||||
if (group->allocation.isRegister())
|
||||
if (group->allocation.isRegister()) {
|
||||
if (IonSpewEnabled(IonSpew_RegAlloc)) {
|
||||
IonSpew(IonSpew_RegAlloc, "Hint %s, used by group allocation",
|
||||
group->allocation.toString());
|
||||
}
|
||||
interval->setHint(Requirement(group->allocation));
|
||||
}
|
||||
}
|
||||
|
||||
if (interval->index() == 0) {
|
||||
// The first interval is the definition, so deal with any definition
|
||||
@ -594,6 +599,10 @@ BacktrackingAllocator::setIntervalRequirement(LiveInterval *interval)
|
||||
LDefinition::Policy policy = reg->def()->policy();
|
||||
if (policy == LDefinition::PRESET) {
|
||||
// Preset policies get a FIXED requirement.
|
||||
if (IonSpewEnabled(IonSpew_RegAlloc)) {
|
||||
IonSpew(IonSpew_RegAlloc, "Requirement %s, preset by definition",
|
||||
reg->def()->output()->toString());
|
||||
}
|
||||
interval->setRequirement(Requirement(*reg->def()->output()));
|
||||
} else if (reg->ins()->isPhi()) {
|
||||
// Phis don't have any requirements, but they should prefer their
|
||||
@ -613,6 +622,11 @@ BacktrackingAllocator::setIntervalRequirement(LiveInterval *interval)
|
||||
if (policy == LUse::FIXED) {
|
||||
AnyRegister required = GetFixedRegister(reg->def(), iter->use);
|
||||
|
||||
if (IonSpewEnabled(IonSpew_RegAlloc)) {
|
||||
IonSpew(IonSpew_RegAlloc, "Requirement %s, due to use at %u",
|
||||
required.name(), iter->pos.pos());
|
||||
}
|
||||
|
||||
// If there are multiple fixed registers which the interval is
|
||||
// required to use, fail. The interval will need to be split before
|
||||
// it can be allocated.
|
||||
@ -1515,10 +1529,11 @@ BacktrackingAllocator::trySplitAcrossHotcode(LiveInterval *interval, bool *succe
|
||||
}
|
||||
|
||||
bool
|
||||
BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, bool *success)
|
||||
BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, LiveInterval *conflict, bool *success)
|
||||
{
|
||||
// If this interval's later uses do not require it to be in a register,
|
||||
// split it after the last use which does require a register.
|
||||
// split it after the last use which does require a register. If conflict
|
||||
// is specified, only consider register uses before the conflict starts.
|
||||
|
||||
CodePosition lastRegisterFrom, lastRegisterTo, lastUse;
|
||||
|
||||
@ -1533,11 +1548,13 @@ BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, bool
|
||||
JS_ASSERT(iter->pos >= lastUse);
|
||||
lastUse = inputOf(ins);
|
||||
|
||||
if (!conflict || outputOf(ins) < conflict->start()) {
|
||||
if (isRegisterUse(use, ins, /* considerCopy = */ true)) {
|
||||
lastRegisterFrom = inputOf(ins);
|
||||
lastRegisterTo = iter->pos.next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastRegisterFrom.pos() || lastRegisterFrom == lastUse) {
|
||||
// Can't trim non-register uses off the end by splitting.
|
||||
@ -1781,7 +1798,7 @@ BacktrackingAllocator::splitAcrossCalls(LiveInterval *interval)
|
||||
}
|
||||
|
||||
bool
|
||||
BacktrackingAllocator::chooseIntervalSplit(LiveInterval *interval)
|
||||
BacktrackingAllocator::chooseIntervalSplit(LiveInterval *interval, LiveInterval *conflict)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
@ -1790,7 +1807,7 @@ BacktrackingAllocator::chooseIntervalSplit(LiveInterval *interval)
|
||||
if (success)
|
||||
return true;
|
||||
|
||||
if (!trySplitAfterLastRegisterUse(interval, &success))
|
||||
if (!trySplitAfterLastRegisterUse(interval, conflict, &success))
|
||||
return false;
|
||||
if (success)
|
||||
return true;
|
||||
|
@ -236,12 +236,12 @@ class BacktrackingAllocator
|
||||
size_t computePriority(const VirtualRegisterGroup *group);
|
||||
size_t computeSpillWeight(const VirtualRegisterGroup *group);
|
||||
|
||||
bool chooseIntervalSplit(LiveInterval *interval);
|
||||
bool chooseIntervalSplit(LiveInterval *interval, LiveInterval *conflict);
|
||||
|
||||
bool splitAt(LiveInterval *interval,
|
||||
const SplitPositionVector &splitPositions);
|
||||
bool trySplitAcrossHotcode(LiveInterval *interval, bool *success);
|
||||
bool trySplitAfterLastRegisterUse(LiveInterval *interval, bool *success);
|
||||
bool trySplitAfterLastRegisterUse(LiveInterval *interval, LiveInterval *conflict, bool *success);
|
||||
bool splitAtAllRegisterUses(LiveInterval *interval);
|
||||
bool splitAcrossCalls(LiveInterval *interval);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user