Add TableGen support for callee saved registers.

Targets can now add CalleeSavedRegs defs to their *CallingConv.td file.
TableGen will use this to create a *_SaveList array suitable for
returning from getCalleeSavedRegs() as well as a *_RegMask bit mask
suitable for returning from getCallPreservedMask().

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148346 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-01-17 22:46:58 +00:00
parent 97af768ccc
commit ec572539dd
4 changed files with 67 additions and 0 deletions

View File

@ -133,3 +133,14 @@ class CCDelegateTo<CallingConv cc> : CCAction {
class CallingConv<list<CCAction> actions> {
list<CCAction> Actions = actions;
}
/// CalleeSavedRegs - A list of callee saved registers for a given calling
/// convention. The order of registers is used by PrologEpilogInsertion when
/// allocation stack slots for saved registers.
///
/// For each CalleeSavedRegs def, TableGen will emit a FOO_SaveList array for
/// returning from getCalleeSavedRegs(), and a FOO_RegMask bit mask suitable for
/// returning from getCallPreservedMask().
class CalleeSavedRegs<dag saves> {
dag SaveList = saves;
}

View File

@ -526,6 +526,7 @@ CodeGenRegisterClass::getSuperRegClasses(Record *SubIdx, BitVector &Out) const {
CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
// Configure register Sets to understand register classes and tuples.
Sets.addFieldExpander("RegisterClass", "MemberList");
Sets.addFieldExpander("CalleeSavedRegs", "SaveList");
Sets.addExpander("RegisterTuples", new TupleExpander());
// Read in the user-defined (named) sub-register indices.
@ -991,3 +992,25 @@ CodeGenRegBank::getRegClassForRegister(Record *R) {
}
return FoundRC;
}
BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef<Record*> Regs) {
SetVector<CodeGenRegister*> Set;
// First add Regs with all sub-registers.
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
CodeGenRegister *Reg = getReg(Regs[i]);
if (Set.insert(Reg))
// Reg is new, add all sub-registers.
// The pre-ordering is not important here.
Reg->addSubRegsPreOrder(Set);
}
// Second, find all super-registers that are completely covered by the set.
// FIXME: Implement CoveredBySubRegs bit.
// Convert to BitVector.
BitVector BV(Registers.size() + 1);
for (unsigned i = 0, e = Set.size(); i != e; ++i)
BV.set(Set[i]->EnumValue);
return BV;
}

View File

@ -320,6 +320,15 @@ namespace llvm {
// If R1 is a sub-register of R2, Map[R1] is a subset of Map[R2].
void computeOverlaps(std::map<const CodeGenRegister*,
CodeGenRegister::Set> &Map);
// Compute the set of registers completely covered by the registers in Regs.
// The returned BitVector will have a bit set for each register in Regs,
// all sub-registers, and all super-registers that are covered by the
// registers in Regs.
//
// This is used to compute the mask of call-preserved registers from a list
// of callee-saves.
BitVector computeCoveredRegisters(ArrayRef<Record*> Regs);
};
}

View File

@ -879,6 +879,30 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << "}\n\n";
// Emit CalleeSavedRegs information.
std::vector<Record*> CSRSets =
Records.getAllDerivedDefinitions("CalleeSavedRegs");
for (unsigned i = 0, e = CSRSets.size(); i != e; ++i) {
Record *CSRSet = CSRSets[i];
const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);
assert(Regs && "Cannot expand CalleeSavedRegs instance");
// Emit the *_SaveList list of callee-saved registers.
OS << "static const unsigned " << CSRSet->getName()
<< "_SaveList[] = { ";
for (unsigned r = 0, re = Regs->size(); r != re; ++r)
OS << getQualifiedName((*Regs)[r]) << ", ";
OS << "0 };\n";
// Emit the *_RegMask bit mask of call-preserved registers.
OS << "static const uint32_t " << CSRSet->getName()
<< "_RegMask[] = { ";
printBitVectorAsHex(OS, RegBank.computeCoveredRegisters(*Regs), 32);
OS << "};\n";
}
OS << "\n\n";
OS << "} // End llvm namespace \n";
OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
}