forked from OSchip/llvm-project
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. llvm-svn: 165982
This commit is contained in:
parent
54c7432e22
commit
57e310613c
|
@ -95,9 +95,6 @@ class MachineRegisterInfo {
|
||||||
/// started.
|
/// started.
|
||||||
BitVector ReservedRegs;
|
BitVector ReservedRegs;
|
||||||
|
|
||||||
/// AllocatableRegs - From TRI->getAllocatableSet.
|
|
||||||
mutable BitVector AllocatableRegs;
|
|
||||||
|
|
||||||
/// LiveIns/LiveOuts - Keep track of the physical registers that are
|
/// LiveIns/LiveOuts - Keep track of the physical registers that are
|
||||||
/// livein/liveout of the function. Live in values are typically arguments in
|
/// livein/liveout of the function. Live in values are typically arguments in
|
||||||
/// registers, live out values are typically return values in registers.
|
/// registers, live out values are typically return values in registers.
|
||||||
|
@ -427,6 +424,34 @@ public:
|
||||||
return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
|
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
|
// LiveIn/LiveOut Management
|
||||||
|
|
|
@ -306,22 +306,18 @@ void MachineRegisterInfo::dumpUses(unsigned Reg) const {
|
||||||
|
|
||||||
void MachineRegisterInfo::freezeReservedRegs(const MachineFunction &MF) {
|
void MachineRegisterInfo::freezeReservedRegs(const MachineFunction &MF) {
|
||||||
ReservedRegs = TRI->getReservedRegs(MF);
|
ReservedRegs = TRI->getReservedRegs(MF);
|
||||||
|
assert(ReservedRegs.size() == TRI->getNumRegs() &&
|
||||||
|
"Invalid ReservedRegs vector from target");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MachineRegisterInfo::isConstantPhysReg(unsigned PhysReg,
|
bool MachineRegisterInfo::isConstantPhysReg(unsigned PhysReg,
|
||||||
const MachineFunction &MF) const {
|
const MachineFunction &MF) const {
|
||||||
assert(TargetRegisterInfo::isPhysicalRegister(PhysReg));
|
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)
|
for (MCRegAliasIterator AI(PhysReg, TRI, true); AI.isValid(); ++AI)
|
||||||
if (!def_empty(*AI))
|
if (!def_empty(*AI) || isAllocatable(*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))
|
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,6 +474,11 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
|
||||||
MRI.replaceRegWith(From, To);
|
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
|
// Release function-specific state. SDB and CurDAG are already cleared
|
||||||
// at this point.
|
// at this point.
|
||||||
FuncInfo->clear();
|
FuncInfo->clear();
|
||||||
|
|
Loading…
Reference in New Issue