Break anti-dependencies using free registers in a round-robin manner to avoid introducing new anti-dependencies.

llvm-svn: 86098
This commit is contained in:
David Goodwin 2009-11-05 01:19:35 +00:00
parent 274be49480
commit 7d8878add2
3 changed files with 49 additions and 18 deletions

View File

@ -491,8 +491,9 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) {
} }
bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters( bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
unsigned AntiDepGroupIndex, unsigned AntiDepGroupIndex,
std::map<unsigned, unsigned> &RenameMap) { RenameOrderType& RenameOrder,
std::map<unsigned, unsigned> &RenameMap) {
unsigned *KillIndices = State->GetKillIndices(); unsigned *KillIndices = State->GetKillIndices();
unsigned *DefIndices = State->GetDefIndices(); unsigned *DefIndices = State->GetDefIndices();
std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>& std::multimap<unsigned, AggressiveAntiDepState::RegisterReference>&
@ -547,22 +548,41 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
if (Regs.size() > 1) if (Regs.size() > 1)
return false; return false;
// Check each possible rename register for SuperReg. If that register // Check each possible rename register for SuperReg in round-robin
// is available, and the corresponding registers are available for // order. If that register is available, and the corresponding
// the other group subregisters, then we can use those registers to // registers are available for the other group subregisters, then we
// rename. // can use those registers to rename.
DEBUG(errs() << "\tFind Register:");
BitVector SuperBV = RenameRegisterMap[SuperReg]; BitVector SuperBV = RenameRegisterMap[SuperReg];
for (int r = SuperBV.find_first(); r != -1; r = SuperBV.find_next(r)) { const TargetRegisterClass *SuperRC =
const unsigned Reg = (unsigned)r; TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);
const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);
const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);
if (RB == RE) {
DEBUG(errs() << "\tEmpty Regclass!!\n");
return false;
}
if (RenameOrder.count(SuperRC) == 0)
RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE));
DEBUG(errs() << "\tFind Register:");
const TargetRegisterClass::iterator OrigR = RenameOrder.at(SuperRC);
const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR);
TargetRegisterClass::iterator R = OrigR;
do {
if (R == RB) R = RE;
--R;
const unsigned Reg = *R;
// Don't replace a register with itself. // Don't replace a register with itself.
if (Reg == SuperReg) continue; if (Reg == SuperReg) continue;
DEBUG(errs() << " " << TRI->getName(Reg)); DEBUG(errs() << " " << TRI->getName(Reg));
// If Reg is dead and Reg's most recent def is not before // If Reg is dead and Reg's most recent def is not before
// SuperRegs's kill, it's safe to replace SuperReg with // SuperRegs's kill, it's safe to replace SuperReg with Reg. We
// Reg. We must also check all subregisters of Reg. // must also check all subregisters of Reg.
if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) { if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) {
DEBUG(errs() << "(live)"); DEBUG(errs() << "(live)");
continue; continue;
@ -580,13 +600,15 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
if (found) if (found)
continue; continue;
} }
if (Reg != 0) { if (Reg != 0) {
DEBUG(errs() << '\n'); DEBUG(errs() << '\n');
RenameOrder.erase(SuperRC);
RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg)); RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg));
return true; return true;
} }
} } while (R != EndR);
DEBUG(errs() << '\n'); DEBUG(errs() << '\n');
@ -627,6 +649,9 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
State = new AggressiveAntiDepState(*SavedState); State = new AggressiveAntiDepState(*SavedState);
} }
} }
// For each regclass the next register to use for renaming.
RenameOrderType RenameOrder;
// ...need a map from MI to SUnit. // ...need a map from MI to SUnit.
std::map<MachineInstr *, SUnit *> MISUnitMap; std::map<MachineInstr *, SUnit *> MISUnitMap;
@ -738,7 +763,7 @@ unsigned AggressiveAntiDepBreaker::BreakAntiDependencies(
// Look for a suitable register to use to break the anti-dependence. // Look for a suitable register to use to break the anti-dependence.
std::map<unsigned, unsigned> RenameMap; std::map<unsigned, unsigned> RenameMap;
if (FindSuitableFreeRegisters(GroupIndex, RenameMap)) { if (FindSuitableFreeRegisters(GroupIndex, RenameOrder, RenameMap)) {
DEBUG(errs() << "\tBreaking anti-dependence edge on " DEBUG(errs() << "\tBreaking anti-dependence edge on "
<< TRI->getName(AntiDepReg) << ":"); << TRI->getName(AntiDepReg) << ":");

View File

@ -155,6 +155,9 @@ namespace llvm {
void FinishBlock(); void FinishBlock();
private: private:
typedef std::map<const TargetRegisterClass *,
TargetRegisterClass::const_iterator> RenameOrderType;
/// IsImplicitDefUse - Return true if MO represents a register /// IsImplicitDefUse - Return true if MO represents a register
/// that is both implicitly used and defined in MI /// that is both implicitly used and defined in MI
bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO); bool IsImplicitDefUse(MachineInstr *MI, MachineOperand& MO);
@ -169,6 +172,7 @@ namespace llvm {
void ScanInstruction(MachineInstr *MI, unsigned Count); void ScanInstruction(MachineInstr *MI, unsigned Count);
BitVector GetRenameRegisters(unsigned Reg); BitVector GetRenameRegisters(unsigned Reg);
bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex, bool FindSuitableFreeRegisters(unsigned AntiDepGroupIndex,
RenameOrderType& RenameOrder,
std::map<unsigned, unsigned> &RenameMap); std::map<unsigned, unsigned> &RenameMap);
}; };
} }

View File

@ -770,7 +770,8 @@ void SchedulePostRATDList::ListScheduleTopDown(
// just advance the current cycle and try again. // just advance the current cycle and try again.
DEBUG(errs() << "*** Stall in cycle " << CurCycle << '\n'); DEBUG(errs() << "*** Stall in cycle " << CurCycle << '\n');
HazardRec->AdvanceCycle(); HazardRec->AdvanceCycle();
++NumStalls; if (!IgnoreAntiDep)
++NumStalls;
} else { } else {
// Otherwise, we have no instructions to issue and we have instructions // Otherwise, we have no instructions to issue and we have instructions
// that will fault if we don't do this right. This is the case for // that will fault if we don't do this right. This is the case for
@ -778,7 +779,8 @@ void SchedulePostRATDList::ListScheduleTopDown(
DEBUG(errs() << "*** Emitting noop in cycle " << CurCycle << '\n'); DEBUG(errs() << "*** Emitting noop in cycle " << CurCycle << '\n');
HazardRec->EmitNoop(); HazardRec->EmitNoop();
Sequence.push_back(0); // NULL here means noop Sequence.push_back(0); // NULL here means noop
++NumNoops; if (!IgnoreAntiDep)
++NumNoops;
} }
++CurCycle; ++CurCycle;