mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-10 22:46:20 +00:00
Restructure code to allow renaming of multiple-register groups for anti-dep breaking.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89511 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c26abd9487
commit
00621efb40
@ -465,7 +465,7 @@ public:
|
|||||||
virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
|
virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
|
||||||
|
|
||||||
/// getSubRegIndex - For a given register pair, return the sub-register index
|
/// getSubRegIndex - For a given register pair, return the sub-register index
|
||||||
/// if they are second register is a sub-register of the second. Return zero
|
/// if the are second register is a sub-register of the first. Return zero
|
||||||
/// otherwise.
|
/// otherwise.
|
||||||
virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0;
|
virtual unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const = 0;
|
||||||
|
|
||||||
|
@ -587,79 +587,108 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod
|
||||||
|
if (DebugDiv > 0) {
|
||||||
|
static int renamecnt = 0;
|
||||||
|
if (renamecnt++ % DebugDiv != DebugMod)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
errs() << "*** Performing rename " << TRI->getName(SuperReg) <<
|
||||||
|
" for debug ***\n";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check each possible rename register for SuperReg in round-robin
|
// Check each possible rename register for SuperReg in round-robin
|
||||||
// order. If that register is available, and the corresponding
|
// order. If that register is available, and the corresponding
|
||||||
// registers are available for the other group subregisters, then we
|
// registers are available for the other group subregisters, then we
|
||||||
// can use those registers to rename.
|
// can use those registers to rename.
|
||||||
BitVector SuperBV = RenameRegisterMap[SuperReg];
|
|
||||||
const TargetRegisterClass *SuperRC =
|
const TargetRegisterClass *SuperRC =
|
||||||
TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);
|
TRI->getPhysicalRegisterRegClass(SuperReg, MVT::Other);
|
||||||
|
|
||||||
const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);
|
const TargetRegisterClass::iterator RB = SuperRC->allocation_order_begin(MF);
|
||||||
const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);
|
const TargetRegisterClass::iterator RE = SuperRC->allocation_order_end(MF);
|
||||||
if (RB == RE) {
|
if (RB == RE) {
|
||||||
DEBUG(errs() << "\tEmpty Regclass!!\n");
|
DEBUG(errs() << "\tEmpty Super Regclass!!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
DEBUG(errs() << "\tFind Registers:");
|
||||||
// If DebugDiv > 0 then only rename (renamecnt % DebugDiv) == DebugMod
|
|
||||||
if (DebugDiv > 0) {
|
|
||||||
static int renamecnt = 0;
|
|
||||||
if (renamecnt++ % DebugDiv != DebugMod)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
errs() << "*** Performing rename " << TRI->getName(SuperReg) <<
|
|
||||||
" for debug ***\n";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (RenameOrder.count(SuperRC) == 0)
|
if (RenameOrder.count(SuperRC) == 0)
|
||||||
RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE));
|
RenameOrder.insert(RenameOrderType::value_type(SuperRC, RE));
|
||||||
|
|
||||||
DEBUG(errs() << "\tFind Register:");
|
|
||||||
|
|
||||||
const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC];
|
const TargetRegisterClass::iterator OrigR = RenameOrder[SuperRC];
|
||||||
const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR);
|
const TargetRegisterClass::iterator EndR = ((OrigR == RE) ? RB : OrigR);
|
||||||
TargetRegisterClass::iterator R = OrigR;
|
TargetRegisterClass::iterator R = OrigR;
|
||||||
do {
|
do {
|
||||||
if (R == RB) R = RE;
|
if (R == RB) R = RE;
|
||||||
--R;
|
--R;
|
||||||
const unsigned Reg = *R;
|
const unsigned NewSuperReg = *R;
|
||||||
// Don't replace a register with itself.
|
// Don't replace a register with itself.
|
||||||
if (Reg == SuperReg) continue;
|
if (NewSuperReg == SuperReg) continue;
|
||||||
|
|
||||||
DEBUG(errs() << " " << TRI->getName(Reg));
|
DEBUG(errs() << " [" << TRI->getName(NewSuperReg) << ':');
|
||||||
|
RenameMap.clear();
|
||||||
// If Reg is dead and Reg's most recent def is not before
|
|
||||||
// SuperRegs's kill, it's safe to replace SuperReg with Reg. We
|
// For each referenced group register (which must be a SuperReg or
|
||||||
// must also check all aliases of Reg. because we can't define a
|
// a subregister of SuperReg), find the corresponding subregister
|
||||||
// register when any sub or super is already live.
|
// of NewSuperReg and make sure it is free to be renamed.
|
||||||
if (State->IsLive(Reg) || (KillIndices[SuperReg] > DefIndices[Reg])) {
|
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
||||||
DEBUG(errs() << "(live)");
|
unsigned Reg = Regs[i];
|
||||||
continue;
|
unsigned NewReg = 0;
|
||||||
} else {
|
if (Reg == SuperReg) {
|
||||||
bool found = false;
|
NewReg = NewSuperReg;
|
||||||
for (const unsigned *Alias = TRI->getAliasSet(Reg);
|
} else {
|
||||||
*Alias; ++Alias) {
|
unsigned NewSubRegIdx = TRI->getSubRegIndex(SuperReg, Reg);
|
||||||
unsigned AliasReg = *Alias;
|
if (NewSubRegIdx != 0)
|
||||||
if (State->IsLive(AliasReg) || (KillIndices[SuperReg] > DefIndices[AliasReg])) {
|
NewReg = TRI->getSubReg(NewSuperReg, NewSubRegIdx);
|
||||||
DEBUG(errs() << "(alias " << TRI->getName(AliasReg) << " live)");
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (found)
|
|
||||||
continue;
|
DEBUG(errs() << " " << TRI->getName(NewReg));
|
||||||
|
|
||||||
|
// Check if Reg can be renamed to NewReg.
|
||||||
|
BitVector BV = RenameRegisterMap[Reg];
|
||||||
|
if (!BV.test(NewReg)) {
|
||||||
|
DEBUG(errs() << "(no rename)");
|
||||||
|
goto next_super_reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If NewReg is dead and NewReg's most recent def is not before
|
||||||
|
// Regs's kill, it's safe to replace Reg with NewReg. We
|
||||||
|
// must also check all aliases of NewReg, because we can't define a
|
||||||
|
// register when any sub or super is already live.
|
||||||
|
if (State->IsLive(NewReg) || (KillIndices[Reg] > DefIndices[NewReg])) {
|
||||||
|
DEBUG(errs() << "(live)");
|
||||||
|
goto next_super_reg;
|
||||||
|
} else {
|
||||||
|
bool found = false;
|
||||||
|
for (const unsigned *Alias = TRI->getAliasSet(NewReg);
|
||||||
|
*Alias; ++Alias) {
|
||||||
|
unsigned AliasReg = *Alias;
|
||||||
|
if (State->IsLive(AliasReg) || (KillIndices[Reg] > DefIndices[AliasReg])) {
|
||||||
|
DEBUG(errs() << "(alias " << TRI->getName(AliasReg) << " live)");
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
goto next_super_reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record that 'Reg' can be renamed to 'NewReg'.
|
||||||
|
RenameMap.insert(std::pair<unsigned, unsigned>(Reg, NewReg));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Reg != 0) {
|
// If we fall-out here, then every register in the group can be
|
||||||
DEBUG(errs() << '\n');
|
// renamed, as recorded in RenameMap.
|
||||||
RenameOrder.erase(SuperRC);
|
RenameOrder.erase(SuperRC);
|
||||||
RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
|
RenameOrder.insert(RenameOrderType::value_type(SuperRC, R));
|
||||||
RenameMap.insert(std::pair<unsigned, unsigned>(SuperReg, Reg));
|
DEBUG(errs() << "]\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
next_super_reg:
|
||||||
|
DEBUG(errs() << ']');
|
||||||
} while (R != EndR);
|
} while (R != EndR);
|
||||||
|
|
||||||
DEBUG(errs() << '\n');
|
DEBUG(errs() << '\n');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user