Fix a couple of bugs in aggressive anti-dep breaking.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85522 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Goodwin 2009-10-29 19:17:04 +00:00
parent 7b888b8ad0
commit 67a8a7b3bd
2 changed files with 62 additions and 36 deletions

View File

@ -277,29 +277,55 @@ static void AntiDepPathStep(SUnit *SU, std::vector<SDep*>& Edges) {
}
}
void AggressiveAntiDepBreaker::HandleLastUse(unsigned Reg, unsigned KillIdx,
const char *tag) {
unsigned *KillIndices = State->GetKillIndices();
unsigned *DefIndices = State->GetDefIndices();
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
RegRefs = State->GetRegRefs();
if (!State->IsLive(Reg)) {
KillIndices[Reg] = KillIdx;
DefIndices[Reg] = ~0u;
RegRefs.erase(Reg);
State->LeaveGroup(Reg);
DEBUG(errs() << "->g" << State->GetGroup(Reg) << tag);
}
// Repeat for subregisters.
for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
*Subreg; ++Subreg) {
unsigned SubregReg = *Subreg;
if (!State->IsLive(SubregReg)) {
KillIndices[SubregReg] = KillIdx;
DefIndices[SubregReg] = ~0u;
RegRefs.erase(SubregReg);
State->LeaveGroup(SubregReg);
DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" <<
State->GetGroup(SubregReg) << tag);
}
}
}
void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Count,
std::set<unsigned>& PassthruRegs) {
unsigned *DefIndices = State->GetDefIndices();
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
RegRefs = State->GetRegRefs();
// Scan the register defs for this instruction and update
// live-ranges, groups and RegRefs.
// Handle dead defs by simulating a last-use of the register just
// after the def. A dead def can occur because the def is truely
// dead, or because only a subregister is live at the def. If we
// don't do this the dead def will be incorrectly merged into the
// previous def.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isDef()) continue;
unsigned Reg = MO.getReg();
if (Reg == 0) continue;
// Ignore passthru registers for liveness...
if (PassthruRegs.count(Reg) != 0) continue;
// Update Def for Reg and subregs.
DefIndices[Reg] = Count;
for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
*Subreg; ++Subreg) {
unsigned SubregReg = *Subreg;
DefIndices[SubregReg] = Count;
}
DEBUG(errs() << "\tDead Def: " << TRI->getName(Reg));
HandleLastUse(Reg, Count + 1, "");
DEBUG(errs() << '\n');
}
DEBUG(errs() << "\tDef Groups:");
@ -311,7 +337,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
DEBUG(errs() << " " << TRI->getName(Reg) << "=g" << State->GetGroup(Reg));
// If MI's defs have special allocation requirement, don't allow
// If MI's defs have a special allocation requirement, don't allow
// any def registers to be changed. Also assume all registers
// defined in a call must not be changed (ABI).
if (MI->getDesc().isCall() || MI->getDesc().hasExtraDefRegAllocReq()) {
@ -320,7 +346,7 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
}
// Any aliased that are live at this point are completely or
// partially defined here, so group those subregisters with Reg.
// partially defined here, so group those aliases with Reg.
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
unsigned AliasReg = *Alias;
if (State->IsLive(AliasReg)) {
@ -339,13 +365,30 @@ void AggressiveAntiDepBreaker::PrescanInstruction(MachineInstr *MI, unsigned Cou
}
DEBUG(errs() << '\n');
// Scan the register defs for this instruction and update
// live-ranges.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isDef()) continue;
unsigned Reg = MO.getReg();
if (Reg == 0) continue;
// Ignore passthru registers for liveness...
if (PassthruRegs.count(Reg) != 0) continue;
// Update def for Reg and subregs.
DefIndices[Reg] = Count;
for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
*Subreg; ++Subreg) {
unsigned SubregReg = *Subreg;
DefIndices[SubregReg] = Count;
}
}
}
void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
unsigned Count) {
DEBUG(errs() << "\tUse Groups:");
unsigned *KillIndices = State->GetKillIndices();
unsigned *DefIndices = State->GetDefIndices();
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
RegRefs = State->GetRegRefs();
@ -363,26 +406,7 @@ void AggressiveAntiDepBreaker::ScanInstruction(MachineInstr *MI,
// It wasn't previously live but now it is, this is a kill. Forget
// the previous live-range information and start a new live-range
// for the register.
if (!State->IsLive(Reg)) {
KillIndices[Reg] = Count;
DefIndices[Reg] = ~0u;
RegRefs.erase(Reg);
State->LeaveGroup(Reg);
DEBUG(errs() << "->g" << State->GetGroup(Reg) << "(last-use)");
}
// Repeat, for subregisters.
for (const unsigned *Subreg = TRI->getSubRegisters(Reg);
*Subreg; ++Subreg) {
unsigned SubregReg = *Subreg;
if (!State->IsLive(SubregReg)) {
KillIndices[SubregReg] = Count;
DefIndices[SubregReg] = ~0u;
RegRefs.erase(SubregReg);
State->LeaveGroup(SubregReg);
DEBUG(errs() << " " << TRI->getName(SubregReg) << "->g" <<
State->GetGroup(SubregReg) << "(last-use)");
}
}
HandleLastUse(Reg, Count, "(last-use)");
// If MI's uses have special allocation requirement, don't allow
// any use registers to be changed. Also assume all registers
@ -511,6 +535,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
}
// FIXME: for now just handle single register in group case...
// FIXME: check only regs that have references...
if (Regs.size() > 1)
return false;

View File

@ -159,6 +159,7 @@ namespace llvm {
/// return that register and all subregisters.
void GetPassthruRegs(MachineInstr *MI, std::set<unsigned>& PassthruRegs);
void HandleLastUse(unsigned Reg, unsigned KillIdx, const char *tag);
void PrescanInstruction(MachineInstr *MI, unsigned Count,
std::set<unsigned>& PassthruRegs);
void ScanInstruction(MachineInstr *MI, unsigned Count);