mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Clarify rules for reserved regs, fix aarch64 ones.
No test case necessary as the problematic condition is checked with the newly introduced assertAllSuperRegsMarked() function. Differential Revision: https://reviews.llvm.org/D26648 llvm-svn: 288277
This commit is contained in:
parent
6fd9b70062
commit
32bde7b907
@ -486,8 +486,14 @@ public:
|
||||
|
||||
/// Returns a bitset indexed by physical register number indicating if a
|
||||
/// register is a special register that has particular uses and should be
|
||||
/// considered unavailable at all times, e.g. SP, RA. This is
|
||||
/// used by register scavenger to determine what registers are free.
|
||||
/// considered unavailable at all times, e.g. stack pointer, return address.
|
||||
/// A reserved register:
|
||||
/// - is not allocatable
|
||||
/// - is considered always live
|
||||
/// - is ignored by liveness tracking
|
||||
/// It is often necessary to reserve the super registers of a reserved
|
||||
/// register as well, to avoid them getting allocated indirectly. You may use
|
||||
/// markSuperRegs() and checkAllSuperRegsMarked() in this case.
|
||||
virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
|
||||
|
||||
/// Returns true if PhysReg is unallocatable and constant throughout the
|
||||
@ -942,6 +948,14 @@ public:
|
||||
/// getFrameRegister - This method should return the register used as a base
|
||||
/// for values allocated in the current stack frame.
|
||||
virtual unsigned getFrameRegister(const MachineFunction &MF) const = 0;
|
||||
|
||||
/// Mark a register and all its aliases as reserved in the given set.
|
||||
void markSuperRegs(BitVector &RegisterSet, unsigned Reg) const;
|
||||
|
||||
/// Returns true if for every register in the set all super registers are part
|
||||
/// of the set as well.
|
||||
bool checkAllSuperRegsMarked(const BitVector &RegisterSet,
|
||||
ArrayRef<MCPhysReg> Exceptions = ArrayRef<MCPhysReg>()) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -527,16 +527,6 @@ void MachineVerifier::visitMachineFunctionBefore() {
|
||||
lastIndex = SlotIndex();
|
||||
regsReserved = MRI->getReservedRegs();
|
||||
|
||||
// A sub-register of a reserved register is also reserved
|
||||
for (int Reg = regsReserved.find_first(); Reg>=0;
|
||||
Reg = regsReserved.find_next(Reg)) {
|
||||
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
|
||||
// FIXME: This should probably be:
|
||||
// assert(regsReserved.test(*SubRegs) && "Non-reserved sub-register");
|
||||
regsReserved.set(*SubRegs);
|
||||
}
|
||||
}
|
||||
|
||||
markReachable(&MF->front());
|
||||
|
||||
// Build a set of the basic blocks in the function.
|
||||
|
@ -40,6 +40,36 @@ TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
|
||||
|
||||
TargetRegisterInfo::~TargetRegisterInfo() {}
|
||||
|
||||
void TargetRegisterInfo::markSuperRegs(BitVector &RegisterSet, unsigned Reg)
|
||||
const {
|
||||
for (MCSuperRegIterator AI(Reg, this, true); AI.isValid(); ++AI)
|
||||
RegisterSet.set(*AI);
|
||||
}
|
||||
|
||||
bool TargetRegisterInfo::checkAllSuperRegsMarked(const BitVector &RegisterSet,
|
||||
ArrayRef<MCPhysReg> Exceptions) const {
|
||||
// Check that all super registers of reserved regs are reserved as well.
|
||||
BitVector Checked(getNumRegs());
|
||||
for (int Reg = RegisterSet.find_first(); Reg>=0;
|
||||
Reg = RegisterSet.find_next(Reg)) {
|
||||
if (Checked[Reg])
|
||||
continue;
|
||||
for (MCSuperRegIterator SR(Reg, this); SR.isValid(); ++SR) {
|
||||
if (!RegisterSet[*SR] && !is_contained(Exceptions, Reg)) {
|
||||
dbgs() << "Error: Super register " << PrintReg(*SR, this)
|
||||
<< " of reserved register " << PrintReg(Reg, this)
|
||||
<< " is not reserved.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// We transitively check superregs. So we can remember this for later
|
||||
// to avoid compiletime explosion in deep register hierarchies.
|
||||
Checked.set(*SR);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
|
||||
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI,
|
||||
|
@ -118,26 +118,27 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
|
||||
// FIXME: avoid re-calculating this every time.
|
||||
BitVector Reserved(getNumRegs());
|
||||
Reserved.set(AArch64::SP);
|
||||
Reserved.set(AArch64::XZR);
|
||||
Reserved.set(AArch64::WSP);
|
||||
Reserved.set(AArch64::WZR);
|
||||
markSuperRegs(Reserved, AArch64::SP);
|
||||
markSuperRegs(Reserved, AArch64::XZR);
|
||||
markSuperRegs(Reserved, AArch64::WSP);
|
||||
markSuperRegs(Reserved, AArch64::WZR);
|
||||
|
||||
if (TFI->hasFP(MF) || TT.isOSDarwin()) {
|
||||
Reserved.set(AArch64::FP);
|
||||
Reserved.set(AArch64::W29);
|
||||
markSuperRegs(Reserved, AArch64::FP);
|
||||
markSuperRegs(Reserved, AArch64::W29);
|
||||
}
|
||||
|
||||
if (MF.getSubtarget<AArch64Subtarget>().isX18Reserved()) {
|
||||
Reserved.set(AArch64::X18); // Platform register
|
||||
Reserved.set(AArch64::W18);
|
||||
markSuperRegs(Reserved, AArch64::X18); // Platform register
|
||||
markSuperRegs(Reserved, AArch64::W18);
|
||||
}
|
||||
|
||||
if (hasBasePointer(MF)) {
|
||||
Reserved.set(AArch64::X19);
|
||||
Reserved.set(AArch64::W19);
|
||||
markSuperRegs(Reserved, AArch64::X19);
|
||||
markSuperRegs(Reserved, AArch64::W19);
|
||||
}
|
||||
|
||||
assert(checkAllSuperRegsMarked(Reserved));
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
|
@ -167,27 +167,29 @@ getReservedRegs(const MachineFunction &MF) const {
|
||||
|
||||
// FIXME: avoid re-calculating this every time.
|
||||
BitVector Reserved(getNumRegs());
|
||||
Reserved.set(ARM::SP);
|
||||
Reserved.set(ARM::PC);
|
||||
Reserved.set(ARM::FPSCR);
|
||||
Reserved.set(ARM::APSR_NZCV);
|
||||
markSuperRegs(Reserved, ARM::SP);
|
||||
markSuperRegs(Reserved, ARM::PC);
|
||||
markSuperRegs(Reserved, ARM::FPSCR);
|
||||
markSuperRegs(Reserved, ARM::APSR_NZCV);
|
||||
if (TFI->hasFP(MF))
|
||||
Reserved.set(getFramePointerReg(STI));
|
||||
markSuperRegs(Reserved, getFramePointerReg(STI));
|
||||
if (hasBasePointer(MF))
|
||||
Reserved.set(BasePtr);
|
||||
markSuperRegs(Reserved, BasePtr);
|
||||
// Some targets reserve R9.
|
||||
if (STI.isR9Reserved())
|
||||
Reserved.set(ARM::R9);
|
||||
markSuperRegs(Reserved, ARM::R9);
|
||||
// Reserve D16-D31 if the subtarget doesn't support them.
|
||||
if (!STI.hasVFP3() || STI.hasD16()) {
|
||||
static_assert(ARM::D31 == ARM::D16 + 15, "Register list not consecutive!");
|
||||
Reserved.set(ARM::D16, ARM::D31 + 1);
|
||||
for (unsigned R = 0; R < 16; ++R)
|
||||
markSuperRegs(Reserved, ARM::D16 + R);
|
||||
}
|
||||
const TargetRegisterClass *RC = &ARM::GPRPairRegClass;
|
||||
for(TargetRegisterClass::iterator I = RC->begin(), E = RC->end(); I!=E; ++I)
|
||||
for (MCSubRegIterator SI(*I, this); SI.isValid(); ++SI)
|
||||
if (Reserved.test(*SI)) Reserved.set(*I);
|
||||
if (Reserved.test(*SI)) markSuperRegs(Reserved, *I);
|
||||
|
||||
assert(checkAllSuperRegsMarked(Reserved));
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
|
@ -558,6 +558,8 @@ BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
||||
}
|
||||
}
|
||||
|
||||
assert(checkAllSuperRegsMarked(Reserved,
|
||||
{X86::SIL, X86::DIL, X86::BPL, X86::SPL}));
|
||||
return Reserved;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user