aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/TargetRegisterInfo.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-05-03 01:14:37 +0000
committerAndrew Trick <atrick@apple.com>2012-05-03 01:14:37 +0000
commitf12f6dff9784805e8f89309787231c1ec53a8c6e (patch)
tree2cff0b5f490ffbf44c24d6aaeac8620c10107033 /lib/Target/TargetRegisterInfo.cpp
parente8cd3f249133406c9b2a8dc6b6dbd2752fc605b4 (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.cpp29
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)