diff options
| author | Andrew Trick <atrick@apple.com> | 2012-05-03 01:14:37 +0000 |
|---|---|---|
| committer | Andrew Trick <atrick@apple.com> | 2012-05-03 01:14:37 +0000 |
| commit | f12f6dff9784805e8f89309787231c1ec53a8c6e (patch) | |
| tree | 2cff0b5f490ffbf44c24d6aaeac8620c10107033 /lib/Target/TargetRegisterInfo.cpp | |
| parent | e8cd3f249133406c9b2a8dc6b6dbd2752fc605b4 (diff) | |
Added TargetRegisterInfo::getAllocatableClass.
The ensures that virtual registers always belong to an allocatable class.
If your target attempts to create a vreg for an operand that has no
allocatable register subclass, you will crash quickly.
This ensures that targets define register classes as intended.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156046 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/TargetRegisterInfo.cpp')
| -rw-r--r-- | lib/Target/TargetRegisterInfo.cpp | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp index 1716423eee..10970f0c59 100644 --- a/lib/Target/TargetRegisterInfo.cpp +++ b/lib/Target/TargetRegisterInfo.cpp @@ -46,6 +46,29 @@ void PrintReg::print(raw_ostream &OS) const { } } +/// getAllocatableClass - Return the maximal subclass of the given register +/// class that is alloctable, or NULL. +const TargetRegisterClass * +TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const { + if (!RC || RC->isAllocatable()) + return RC; + + const unsigned *SubClass = RC->getSubClassMask(); + for (unsigned Base = 0, BaseE = getNumRegClasses(); + Base < BaseE; Base += 32) { + unsigned Idx = Base; + for (unsigned Mask = *SubClass++; Mask; Mask >>= 1) { + unsigned Offset = CountTrailingZeros_32(Mask); + const TargetRegisterClass *SubRC = getRegClass(Idx + Offset); + if (SubRC->isAllocatable()) + return SubRC; + Mask >>= Offset; + Idx += Offset + 1; + } + } + return NULL; +} + /// getMinimalPhysRegClass - Returns the Register Class of a physical /// register of the given type, picking the most sub register class of /// the right type that contains this physreg. @@ -71,6 +94,7 @@ TargetRegisterInfo::getMinimalPhysRegClass(unsigned reg, EVT VT) const { /// registers for the specific register class. static void getAllocatableSetForRC(const MachineFunction &MF, const TargetRegisterClass *RC, BitVector &R){ + assert(RC->isAllocatable() && "invalid for nonallocatable sets"); ArrayRef<uint16_t> Order = RC->getRawAllocationOrder(MF); for (unsigned i = 0; i != Order.size(); ++i) R.set(Order[i]); @@ -80,7 +104,10 @@ BitVector TargetRegisterInfo::getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC) const { BitVector Allocatable(getNumRegs()); if (RC) { - getAllocatableSetForRC(MF, RC, Allocatable); + // A register class with no allocatable subclass returns an empty set. + const TargetRegisterClass *SubClass = getAllocatableClass(RC); + if (SubClass) + getAllocatableSetForRC(MF, SubClass, Allocatable); } else { for (TargetRegisterInfo::regclass_iterator I = regclass_begin(), E = regclass_end(); I != E; ++I) |
