mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Factor out the code for finding an available register for use
in breaking an anti-dependence into a separate function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78767 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -158,6 +158,9 @@ namespace {
|
|||||||
void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
|
void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle);
|
||||||
void ListScheduleTopDown();
|
void ListScheduleTopDown();
|
||||||
bool BreakAntiDependencies();
|
bool BreakAntiDependencies();
|
||||||
|
unsigned findSuitableFreeRegister(unsigned AntiDepReg,
|
||||||
|
unsigned LastNewReg,
|
||||||
|
const TargetRegisterClass *);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +513,36 @@ void SchedulePostRATDList::ScanInstruction(MachineInstr *MI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
SchedulePostRATDList::findSuitableFreeRegister(unsigned AntiDepReg,
|
||||||
|
unsigned LastNewReg,
|
||||||
|
const TargetRegisterClass *RC) {
|
||||||
|
for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF),
|
||||||
|
RE = RC->allocation_order_end(MF); R != RE; ++R) {
|
||||||
|
unsigned NewReg = *R;
|
||||||
|
// Don't replace a register with itself.
|
||||||
|
if (NewReg == AntiDepReg) continue;
|
||||||
|
// Don't replace a register with one that was recently used to repair
|
||||||
|
// an anti-dependence with this AntiDepReg, because that would
|
||||||
|
// re-introduce that anti-dependence.
|
||||||
|
if (NewReg == LastNewReg) continue;
|
||||||
|
// If NewReg is dead and NewReg's most recent def is not before
|
||||||
|
// AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg.
|
||||||
|
assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) &&
|
||||||
|
"Kill and Def maps aren't consistent for AntiDepReg!");
|
||||||
|
assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) &&
|
||||||
|
"Kill and Def maps aren't consistent for NewReg!");
|
||||||
|
if (KillIndices[NewReg] == ~0u &&
|
||||||
|
Classes[NewReg] != reinterpret_cast<TargetRegisterClass *>(-1) &&
|
||||||
|
KillIndices[AntiDepReg] <= DefIndices[NewReg])
|
||||||
|
continue;
|
||||||
|
return NewReg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No registers are free and available!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path
|
/// BreakAntiDependencies - Identifiy anti-dependencies along the critical path
|
||||||
/// of the ScheduleDAG and break them by renaming registers.
|
/// of the ScheduleDAG and break them by renaming registers.
|
||||||
///
|
///
|
||||||
@@ -674,60 +707,43 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
|
|||||||
// TODO: Instead of picking the first free register, consider which might
|
// TODO: Instead of picking the first free register, consider which might
|
||||||
// be the best.
|
// be the best.
|
||||||
if (AntiDepReg != 0) {
|
if (AntiDepReg != 0) {
|
||||||
for (TargetRegisterClass::iterator R = RC->allocation_order_begin(MF),
|
if (unsigned NewReg = findSuitableFreeRegister(AntiDepReg,
|
||||||
RE = RC->allocation_order_end(MF); R != RE; ++R) {
|
LastNewReg[AntiDepReg],
|
||||||
unsigned NewReg = *R;
|
RC)) {
|
||||||
// Don't replace a register with itself.
|
DEBUG(errs() << "Breaking anti-dependence edge on "
|
||||||
if (NewReg == AntiDepReg) continue;
|
<< TRI->getName(AntiDepReg)
|
||||||
// Don't replace a register with one that was recently used to repair
|
<< " with " << RegRefs.count(AntiDepReg) << " references"
|
||||||
// an anti-dependence with this AntiDepReg, because that would
|
<< " using " << TRI->getName(NewReg) << "!\n");
|
||||||
// re-introduce that anti-dependence.
|
|
||||||
if (NewReg == LastNewReg[AntiDepReg]) continue;
|
|
||||||
// If NewReg is dead and NewReg's most recent def is not before
|
|
||||||
// AntiDepReg's kill, it's safe to replace AntiDepReg with NewReg.
|
|
||||||
assert(((KillIndices[AntiDepReg] == ~0u) != (DefIndices[AntiDepReg] == ~0u)) &&
|
|
||||||
"Kill and Def maps aren't consistent for AntiDepReg!");
|
|
||||||
assert(((KillIndices[NewReg] == ~0u) != (DefIndices[NewReg] == ~0u)) &&
|
|
||||||
"Kill and Def maps aren't consistent for NewReg!");
|
|
||||||
if (KillIndices[NewReg] == ~0u &&
|
|
||||||
Classes[NewReg] != reinterpret_cast<TargetRegisterClass *>(-1) &&
|
|
||||||
KillIndices[AntiDepReg] <= DefIndices[NewReg]) {
|
|
||||||
DEBUG(errs() << "Breaking anti-dependence edge on "
|
|
||||||
<< TRI->getName(AntiDepReg)
|
|
||||||
<< " with " << RegRefs.count(AntiDepReg) << " references"
|
|
||||||
<< " using " << TRI->getName(NewReg) << "!\n");
|
|
||||||
|
|
||||||
// Update the references to the old register to refer to the new
|
// Update the references to the old register to refer to the new
|
||||||
// register.
|
// register.
|
||||||
std::pair<std::multimap<unsigned, MachineOperand *>::iterator,
|
std::pair<std::multimap<unsigned, MachineOperand *>::iterator,
|
||||||
std::multimap<unsigned, MachineOperand *>::iterator>
|
std::multimap<unsigned, MachineOperand *>::iterator>
|
||||||
Range = RegRefs.equal_range(AntiDepReg);
|
Range = RegRefs.equal_range(AntiDepReg);
|
||||||
for (std::multimap<unsigned, MachineOperand *>::iterator
|
for (std::multimap<unsigned, MachineOperand *>::iterator
|
||||||
Q = Range.first, QE = Range.second; Q != QE; ++Q)
|
Q = Range.first, QE = Range.second; Q != QE; ++Q)
|
||||||
Q->second->setReg(NewReg);
|
Q->second->setReg(NewReg);
|
||||||
|
|
||||||
// We just went back in time and modified history; the
|
// We just went back in time and modified history; the
|
||||||
// liveness information for the anti-depenence reg is now
|
// liveness information for the anti-depenence reg is now
|
||||||
// inconsistent. Set the state as if it were dead.
|
// inconsistent. Set the state as if it were dead.
|
||||||
Classes[NewReg] = Classes[AntiDepReg];
|
Classes[NewReg] = Classes[AntiDepReg];
|
||||||
DefIndices[NewReg] = DefIndices[AntiDepReg];
|
DefIndices[NewReg] = DefIndices[AntiDepReg];
|
||||||
KillIndices[NewReg] = KillIndices[AntiDepReg];
|
KillIndices[NewReg] = KillIndices[AntiDepReg];
|
||||||
assert(((KillIndices[NewReg] == ~0u) !=
|
assert(((KillIndices[NewReg] == ~0u) !=
|
||||||
(DefIndices[NewReg] == ~0u)) &&
|
(DefIndices[NewReg] == ~0u)) &&
|
||||||
"Kill and Def maps aren't consistent for NewReg!");
|
"Kill and Def maps aren't consistent for NewReg!");
|
||||||
|
|
||||||
Classes[AntiDepReg] = 0;
|
Classes[AntiDepReg] = 0;
|
||||||
DefIndices[AntiDepReg] = KillIndices[AntiDepReg];
|
DefIndices[AntiDepReg] = KillIndices[AntiDepReg];
|
||||||
KillIndices[AntiDepReg] = ~0u;
|
KillIndices[AntiDepReg] = ~0u;
|
||||||
assert(((KillIndices[AntiDepReg] == ~0u) !=
|
assert(((KillIndices[AntiDepReg] == ~0u) !=
|
||||||
(DefIndices[AntiDepReg] == ~0u)) &&
|
(DefIndices[AntiDepReg] == ~0u)) &&
|
||||||
"Kill and Def maps aren't consistent for AntiDepReg!");
|
"Kill and Def maps aren't consistent for AntiDepReg!");
|
||||||
|
|
||||||
RegRefs.erase(AntiDepReg);
|
RegRefs.erase(AntiDepReg);
|
||||||
Changed = true;
|
Changed = true;
|
||||||
LastNewReg[AntiDepReg] = NewReg;
|
LastNewReg[AntiDepReg] = NewReg;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user