diff options
-rw-r--r-- | include/llvm/Target/TargetCallingConv.td | 11 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.cpp | 23 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 9 | ||||
-rw-r--r-- | utils/TableGen/RegisterInfoEmitter.cpp | 24 |
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"; } |