Freeze the reserved registers as soon as isel is complete.

Also provide an MRI::getReservedRegs() function to access the frozen
register set, and isReserved() and isAllocatable() methods to test
individual registers.

The various implementations of TRI::getReservedRegs() are quite
complicated, and many passes need to look at the reserved register set.
This patch makes it possible for these passes to use the cached copy in
MRI, avoiding a lot of malloc traffic and repeated calculations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165982 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-10-15 21:33:06 +00:00
parent 64ba635209
commit e4f273908b
3 changed files with 38 additions and 12 deletions

View File

@ -95,9 +95,6 @@ class MachineRegisterInfo {
/// started.
BitVector ReservedRegs;
/// AllocatableRegs - From TRI->getAllocatableSet.
mutable BitVector AllocatableRegs;
/// LiveIns/LiveOuts - Keep track of the physical registers that are
/// livein/liveout of the function. Live in values are typically arguments in
/// registers, live out values are typically return values in registers.
@ -427,6 +424,34 @@ public:
return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
}
/// getReservedRegs - Returns a reference to the frozen set of reserved
/// registers. This method should always be preferred to calling
/// TRI::getReservedRegs() when possible.
const BitVector &getReservedRegs() const {
assert(reservedRegsFrozen() &&
"Reserved registers haven't been frozen yet. "
"Use TRI::getReservedRegs().");
return ReservedRegs;
}
/// isReserved - Returns true when PhysReg is a reserved register.
///
/// Reserved registers may belong to an allocatable register class, but the
/// target has explicitly requested that they are not used.
///
bool isReserved(unsigned PhysReg) const {
return getReservedRegs().test(PhysReg);
}
/// isAllocatable - Returns true when PhysReg belongs to an allocatable
/// register class and it hasn't been reserved.
///
/// Allocatable registers may show up in the allocation order of some virtual
/// register, so a register allocator needs to track its liveness and
/// availability.
bool isAllocatable(unsigned PhysReg) const {
return TRI->isInAllocatableClass(PhysReg) && !isReserved(PhysReg);
}
//===--------------------------------------------------------------------===//
// LiveIn/LiveOut Management

View File

@ -306,22 +306,18 @@ void MachineRegisterInfo::dumpUses(unsigned Reg) const {
void MachineRegisterInfo::freezeReservedRegs(const MachineFunction &MF) {
ReservedRegs = TRI->getReservedRegs(MF);
assert(ReservedRegs.size() == TRI->getNumRegs() &&
"Invalid ReservedRegs vector from target");
}
bool MachineRegisterInfo::isConstantPhysReg(unsigned PhysReg,
const MachineFunction &MF) const {
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
// Check if any overlapping register is modified.
// Check if any overlapping register is modified, or allocatable so it may be
// used later.
for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI)
if (!def_empty(*AI))
return false;
// Check if any overlapping register is allocatable so it may be used later.
if (AllocatableRegs.empty())
AllocatableRegs = TRI->getAllocatableSet(MF);
for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI)
if (AllocatableRegs.test(*AI))
if (!def_empty(*AI) || isAllocatable(*AI))
return false;
return true;
}

View File

@ -474,6 +474,11 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
MRI.replaceRegWith(From, To);
}
// Freeze the set of reserved registers now that MachineFrameInfo has been
// set up. All the information required by getReservedRegs() should be
// available now.
MRI.freezeReservedRegs(*MF);
// Release function-specific state. SDB and CurDAG are already cleared
// at this point.
FuncInfo->clear();