aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-17 22:46:58 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-17 22:46:58 +0000
commitec572539dd5660f9ca42027ac04df3a3f8c0cab1 (patch)
tree5f338c468ad356a3096c0b411e471d334fb3cbda
parent97af768ccc00962a2c16e990b89c9028f8e247be (diff)
downloadexternal_llvm-ec572539dd5660f9ca42027ac04df3a3f8c0cab1.zip
external_llvm-ec572539dd5660f9ca42027ac04df3a3f8c0cab1.tar.gz
external_llvm-ec572539dd5660f9ca42027ac04df3a3f8c0cab1.tar.bz2
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
-rw-r--r--include/llvm/Target/TargetCallingConv.td11
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp23
-rw-r--r--utils/TableGen/CodeGenRegisters.h9
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp24
4 files changed, 67 insertions, 0 deletions
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
index 6da3ba1..a53ed29 100644
--- a/include/llvm/Target/TargetCallingConv.td
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -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;
+}
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 889acdd..89358c8 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -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;
+}
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 1d1454c..6153fe5 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -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);
};
}
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 5fa2fe0..1263e3d 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -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";
}