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 canAllocate = setIntervalRequirement(interval);
|
||||||
|
|
||||||
bool fixed;
|
bool fixed;
|
||||||
LiveInterval *conflict;
|
LiveInterval *conflict = nullptr;
|
||||||
for (size_t attempt = 0;; attempt++) {
|
for (size_t attempt = 0;; attempt++) {
|
||||||
if (canAllocate) {
|
if (canAllocate) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@ -520,7 +520,7 @@ BacktrackingAllocator::processInterval(LiveInterval *interval)
|
|||||||
|
|
||||||
if (canAllocate && fixed)
|
if (canAllocate && fixed)
|
||||||
return splitAcrossCalls(interval);
|
return splitAcrossCalls(interval);
|
||||||
return chooseIntervalSplit(interval);
|
return chooseIntervalSplit(interval, conflict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,8 +583,13 @@ BacktrackingAllocator::setIntervalRequirement(LiveInterval *interval)
|
|||||||
|
|
||||||
// Set a hint if another interval in the same group is in a register.
|
// Set a hint if another interval in the same group is in a register.
|
||||||
if (VirtualRegisterGroup *group = reg->group()) {
|
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));
|
interval->setHint(Requirement(group->allocation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interval->index() == 0) {
|
if (interval->index() == 0) {
|
||||||
@ -594,6 +599,10 @@ BacktrackingAllocator::setIntervalRequirement(LiveInterval *interval)
|
|||||||
LDefinition::Policy policy = reg->def()->policy();
|
LDefinition::Policy policy = reg->def()->policy();
|
||||||
if (policy == LDefinition::PRESET) {
|
if (policy == LDefinition::PRESET) {
|
||||||
// Preset policies get a FIXED requirement.
|
// 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()));
|
interval->setRequirement(Requirement(*reg->def()->output()));
|
||||||
} else if (reg->ins()->isPhi()) {
|
} else if (reg->ins()->isPhi()) {
|
||||||
// Phis don't have any requirements, but they should prefer their
|
// Phis don't have any requirements, but they should prefer their
|
||||||
@ -613,6 +622,11 @@ BacktrackingAllocator::setIntervalRequirement(LiveInterval *interval)
|
|||||||
if (policy == LUse::FIXED) {
|
if (policy == LUse::FIXED) {
|
||||||
AnyRegister required = GetFixedRegister(reg->def(), iter->use);
|
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
|
// If there are multiple fixed registers which the interval is
|
||||||
// required to use, fail. The interval will need to be split before
|
// required to use, fail. The interval will need to be split before
|
||||||
// it can be allocated.
|
// it can be allocated.
|
||||||
@ -1515,10 +1529,11 @@ BacktrackingAllocator::trySplitAcrossHotcode(LiveInterval *interval, bool *succe
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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,
|
// 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;
|
CodePosition lastRegisterFrom, lastRegisterTo, lastUse;
|
||||||
|
|
||||||
@ -1533,9 +1548,11 @@ BacktrackingAllocator::trySplitAfterLastRegisterUse(LiveInterval *interval, bool
|
|||||||
JS_ASSERT(iter->pos >= lastUse);
|
JS_ASSERT(iter->pos >= lastUse);
|
||||||
lastUse = inputOf(ins);
|
lastUse = inputOf(ins);
|
||||||
|
|
||||||
if (isRegisterUse(use, ins, /* considerCopy = */ true)) {
|
if (!conflict || outputOf(ins) < conflict->start()) {
|
||||||
lastRegisterFrom = inputOf(ins);
|
if (isRegisterUse(use, ins, /* considerCopy = */ true)) {
|
||||||
lastRegisterTo = iter->pos.next();
|
lastRegisterFrom = inputOf(ins);
|
||||||
|
lastRegisterTo = iter->pos.next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1781,7 +1798,7 @@ BacktrackingAllocator::splitAcrossCalls(LiveInterval *interval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BacktrackingAllocator::chooseIntervalSplit(LiveInterval *interval)
|
BacktrackingAllocator::chooseIntervalSplit(LiveInterval *interval, LiveInterval *conflict)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
@ -1790,7 +1807,7 @@ BacktrackingAllocator::chooseIntervalSplit(LiveInterval *interval)
|
|||||||
if (success)
|
if (success)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (!trySplitAfterLastRegisterUse(interval, &success))
|
if (!trySplitAfterLastRegisterUse(interval, conflict, &success))
|
||||||
return false;
|
return false;
|
||||||
if (success)
|
if (success)
|
||||||
return true;
|
return true;
|
||||||
|
@ -236,12 +236,12 @@ class BacktrackingAllocator
|
|||||||
size_t computePriority(const VirtualRegisterGroup *group);
|
size_t computePriority(const VirtualRegisterGroup *group);
|
||||||
size_t computeSpillWeight(const VirtualRegisterGroup *group);
|
size_t computeSpillWeight(const VirtualRegisterGroup *group);
|
||||||
|
|
||||||
bool chooseIntervalSplit(LiveInterval *interval);
|
bool chooseIntervalSplit(LiveInterval *interval, LiveInterval *conflict);
|
||||||
|
|
||||||
bool splitAt(LiveInterval *interval,
|
bool splitAt(LiveInterval *interval,
|
||||||
const SplitPositionVector &splitPositions);
|
const SplitPositionVector &splitPositions);
|
||||||
bool trySplitAcrossHotcode(LiveInterval *interval, bool *success);
|
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 splitAtAllRegisterUses(LiveInterval *interval);
|
||||||
bool splitAcrossCalls(LiveInterval *interval);
|
bool splitAcrossCalls(LiveInterval *interval);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user