X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FRegisterInfoEmitter.cpp;h=942163e77dc1c4a97217664212b8b129eeb86bae;hb=a0ec3f9b7b826b9b40b80199923b664bad808cce;hp=0d0c3251fac3344c59042142359acd477275e2bd;hpb=f52baf72c116d9cf8680d25a8e751ce354c7d44b;p=oota-llvm.git diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 0d0c3251fac..942163e77dc 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -13,21 +13,58 @@ // //===----------------------------------------------------------------------===// -#include "RegisterInfoEmitter.h" -#include "CodeGenTarget.h" #include "CodeGenRegisters.h" +#include "CodeGenTarget.h" #include "SequenceToOffsetTable.h" -#include "llvm/TableGen/Error.h" -#include "llvm/TableGen/Record.h" #include "llvm/ADT/BitVector.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Format.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" #include #include +#include using namespace llvm; +namespace { +class RegisterInfoEmitter { + RecordKeeper &Records; +public: + RegisterInfoEmitter(RecordKeeper &R) : Records(R) {} + + // runEnums - Print out enum values for all of the registers. + void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); + + // runMCDesc - Print out MC register descriptions. + void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); + + // runTargetHeader - Emit a header fragment for the register info emitter. + void runTargetHeader(raw_ostream &o, CodeGenTarget &Target, + CodeGenRegBank &Bank); + + // runTargetDesc - Output the target register and register file descriptions. + void runTargetDesc(raw_ostream &o, CodeGenTarget &Target, + CodeGenRegBank &Bank); + + // run - Output the register file description. + void run(raw_ostream &o); + +private: + void EmitRegMapping(raw_ostream &o, + const std::vector &Regs, bool isCtor); + void EmitRegMappingTables(raw_ostream &o, + const std::vector &Regs, + bool isCtor); + void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, + const std::string &ClassName); + void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank, + const std::string &ClassName); +}; +} // End anonymous namespace + // runEnums - Print out enum values for all of the registers. void RegisterInfoEmitter::runEnums(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &Bank) { @@ -38,7 +75,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, std::string Namespace = Registers[0]->TheDef->getValueAsString("Namespace"); - EmitSourceFileHeader("Target Register Enum Values", OS); + emitSourceFileHeader("Target Register Enum Values", OS); OS << "\n#ifdef GET_REGINFO_ENUM\n"; OS << "#undef GET_REGINFO_ENUM\n"; @@ -108,9 +145,9 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS, if (!Namespace.empty()) OS << "namespace " << Namespace << " {\n"; OS << "enum {\n NoSubRegister,\n"; - for (unsigned i = 0, e = Bank.getNumNamedIndices(); i != e; ++i) + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) OS << " " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n"; - OS << " NUM_TARGET_NAMED_SUBREGS\n};\n"; + OS << " NUM_TARGET_SUBREGS\n};\n"; if (!Namespace.empty()) OS << "}\n"; } @@ -146,6 +183,36 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, << " return RCWeightTable[RC->getID()];\n" << "}\n\n"; + // Reasonable targets (not ARMv7) have unit weight for all units, so don't + // bother generating a table. + bool RegUnitsHaveUnitWeight = true; + for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); + UnitIdx < UnitEnd; ++UnitIdx) { + if (RegBank.getRegUnit(UnitIdx).Weight > 1) + RegUnitsHaveUnitWeight = false; + } + OS << "/// Get the weight in units of pressure for this register unit.\n" + << "unsigned " << ClassName << "::\n" + << "getRegUnitWeight(unsigned RegUnit) const {\n" + << " assert(RegUnit < " << RegBank.getNumNativeRegUnits() + << " && \"invalid register unit\");\n"; + if (!RegUnitsHaveUnitWeight) { + OS << " static const uint8_t RUWeightTable[] = {\n "; + for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); + UnitIdx < UnitEnd; ++UnitIdx) { + const RegUnit &RU = RegBank.getRegUnit(UnitIdx); + assert(RU.Weight < 256 && "RegUnit too heavy"); + OS << RU.Weight << ", "; + } + OS << "0 };\n" + << " return RUWeightTable[RegUnit];\n"; + } + else { + OS << " // All register units have unit weight.\n" + << " return 1;\n"; + } + OS << "}\n\n"; + OS << "\n" << "// Get the number of dimensions of register pressure.\n" << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n" @@ -176,14 +243,13 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, << " return PressureLimitTable[Idx];\n" << "}\n\n"; - OS << "/// Get the dimensions of register pressure " - << "impacted by this register class.\n" - << "/// Returns a -1 terminated array of pressure set IDs\n" - << "const int* " << ClassName << "::\n" - << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n" - << " static const int RCSetsTable[] = {\n "; - std::vector RCSetStarts(NumRCs); - for (unsigned i = 0, StartIdx = 0, e = NumRCs; i != e; ++i) { + // This table may be larger than NumRCs if some register units needed a list + // of unit sets that did not correspond to a register class. + unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists(); + OS << "/// Table of pressure sets per register class or unit.\n" + << "static const int RCSetsTable[] = {\n "; + std::vector RCSetStarts(NumRCUnitSets); + for (unsigned i = 0, StartIdx = 0, e = NumRCUnitSets; i != e; ++i) { RCSetStarts[i] = StartIdx; ArrayRef PSetIDs = RegBank.getRCPressureSetIDs(i); for (ArrayRef::iterator PSetI = PSetIDs.begin(), @@ -191,10 +257,26 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, OS << *PSetI << ", "; ++StartIdx; } - OS << "-1, \t// " << RegBank.getRegClasses()[i]->getName() << "\n "; + OS << "-1, \t// #" << RCSetStarts[i] << " "; + if (i < NumRCs) + OS << RegBank.getRegClasses()[i]->getName(); + else { + OS << "inferred"; + for (ArrayRef::iterator PSetI = PSetIDs.begin(), + PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) { + OS << "~" << RegBank.getRegPressureSet(*PSetI).Name; + } + } + OS << "\n "; ++StartIdx; } - OS << "-1 };\n"; + OS << "-1 };\n\n"; + + OS << "/// Get the dimensions of register pressure impacted by this " + << "register class.\n" + << "/// Returns a -1 terminated array of pressure set IDs\n" + << "const int* " << ClassName << "::\n" + << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n"; OS << " static const unsigned RCSetStartTable[] = {\n "; for (unsigned i = 0, e = NumRCs; i != e; ++i) { OS << RCSetStarts[i] << ","; @@ -203,6 +285,23 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, << " unsigned SetListStart = RCSetStartTable[RC->getID()];\n" << " return &RCSetsTable[SetListStart];\n" << "}\n\n"; + + OS << "/// Get the dimensions of register pressure impacted by this " + << "register unit.\n" + << "/// Returns a -1 terminated array of pressure set IDs\n" + << "const int* " << ClassName << "::\n" + << "getRegUnitPressureSets(unsigned RegUnit) const {\n" + << " assert(RegUnit < " << RegBank.getNumNativeRegUnits() + << " && \"invalid register unit\");\n"; + OS << " static const unsigned RUSetStartTable[] = {\n "; + for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); + UnitIdx < UnitEnd; ++UnitIdx) { + OS << RCSetStarts[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx] << ","; + } + OS << "0 };\n" + << " unsigned SetListStart = RUSetStartTable[RegUnit];\n" + << " return &RCSetsTable[SetListStart];\n" + << "}\n\n"; } void @@ -210,7 +309,7 @@ RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, const std::vector &Regs, bool isCtor) { // Collect all information about dwarf register numbers - typedef std::map, LessRecord> DwarfRegNumsMapTy; + typedef std::map, LessRecordRegister> DwarfRegNumsMapTy; DwarfRegNumsMapTy DwarfRegNums; // First, just pull all provided information to the map @@ -288,7 +387,7 @@ RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS, if (!V || !V->getValue()) continue; - DefInit *DI = dynamic_cast(V->getValue()); + DefInit *DI = cast(V->getValue()); Record *Alias = DI->getDef(); DwarfRegNums[Reg] = DwarfRegNums[Alias]; } @@ -442,16 +541,12 @@ public: } }; -static void printRegister(raw_ostream &OS, const CodeGenRegister *Reg) { - OS << getQualifiedName(Reg->TheDef); -} - static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) { OS << getEnumName(VT); } static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) { - OS << Idx->getQualifiedName(); + OS << Idx->EnumValue; } // Differentially encoded register and regunit lists allow for better @@ -468,6 +563,7 @@ typedef SmallVector DiffVec; // Differentially encode a sequence of numbers into V. The starting value and // terminating 0 are not added to V, so it will have the same size as List. +static DiffVec &diffEncode(DiffVec &V, unsigned InitVal, ArrayRef List) { assert(V.empty() && "Clear DiffVec before diffEncode."); uint16_t Val = uint16_t(InitVal); @@ -479,8 +575,117 @@ DiffVec &diffEncode(DiffVec &V, unsigned InitVal, ArrayRef List) { return V; } +template +static +DiffVec &diffEncode(DiffVec &V, unsigned InitVal, Iter Begin, Iter End) { + assert(V.empty() && "Clear DiffVec before diffEncode."); + uint16_t Val = uint16_t(InitVal); + for (Iter I = Begin; I != End; ++I) { + uint16_t Cur = (*I)->EnumValue; + V.push_back(Cur - Val); + Val = Cur; + } + return V; +} + static void printDiff16(raw_ostream &OS, uint16_t Val) { - OS << SignExtend32<16>(Val); + OS << Val; +} + +// Try to combine Idx's compose map into Vec if it is compatible. +// Return false if it's not possible. +static bool combine(const CodeGenSubRegIndex *Idx, + SmallVectorImpl &Vec) { + const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites(); + for (CodeGenSubRegIndex::CompMap::const_iterator + I = Map.begin(), E = Map.end(); I != E; ++I) { + CodeGenSubRegIndex *&Entry = Vec[I->first->EnumValue - 1]; + if (Entry && Entry != I->second) + return false; + } + + // All entries are compatible. Make it so. + for (CodeGenSubRegIndex::CompMap::const_iterator + I = Map.begin(), E = Map.end(); I != E; ++I) + Vec[I->first->EnumValue - 1] = I->second; + return true; +} + +static const char *getMinimalTypeForRange(uint64_t Range) { + assert(Range < 0xFFFFFFFFULL && "Enum too large"); + if (Range > 0xFFFF) + return "uint32_t"; + if (Range > 0xFF) + return "uint16_t"; + return "uint8_t"; +} + +void +RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS, + CodeGenRegBank &RegBank, + const std::string &ClName) { + ArrayRef SubRegIndices = RegBank.getSubRegIndices(); + OS << "unsigned " << ClName + << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n"; + + // Many sub-register indexes are composition-compatible, meaning that + // + // compose(IdxA, IdxB) == compose(IdxA', IdxB) + // + // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed. + // The illegal entries can be use as wildcards to compress the table further. + + // Map each Sub-register index to a compatible table row. + SmallVector RowMap; + SmallVector, 4> Rows; + + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + unsigned Found = ~0u; + for (unsigned r = 0, re = Rows.size(); r != re; ++r) { + if (combine(SubRegIndices[i], Rows[r])) { + Found = r; + break; + } + } + if (Found == ~0u) { + Found = Rows.size(); + Rows.resize(Found + 1); + Rows.back().resize(SubRegIndices.size()); + combine(SubRegIndices[i], Rows.back()); + } + RowMap.push_back(Found); + } + + // Output the row map if there is multiple rows. + if (Rows.size() > 1) { + OS << " static const " << getMinimalTypeForRange(Rows.size()) + << " RowMap[" << SubRegIndices.size() << "] = {\n "; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) + OS << RowMap[i] << ", "; + OS << "\n };\n"; + } + + // Output the rows. + OS << " static const " << getMinimalTypeForRange(SubRegIndices.size()+1) + << " Rows[" << Rows.size() << "][" << SubRegIndices.size() << "] = {\n"; + for (unsigned r = 0, re = Rows.size(); r != re; ++r) { + OS << " { "; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) + if (Rows[r][i]) + OS << Rows[r][i]->EnumValue << ", "; + else + OS << "0, "; + OS << "},\n"; + } + OS << " };\n\n"; + + OS << " --IdxA; assert(IdxA < " << SubRegIndices.size() << ");\n" + << " --IdxB; assert(IdxB < " << SubRegIndices.size() << ");\n"; + if (Rows.size() > 1) + OS << " return Rows[RowMap[IdxA]][IdxB];\n"; + else + OS << " return Rows[0][IdxB];\n"; + OS << "}\n\n"; } // @@ -489,25 +694,31 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) { void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &RegBank) { - EmitSourceFileHeader("MC Register Information", OS); + emitSourceFileHeader("MC Register Information", OS); OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; OS << "#undef GET_REGINFO_MC_DESC\n"; const std::vector &Regs = RegBank.getRegisters(); - // The lists of sub-registers, super-registers, and overlaps all go in the - // same array. That allows us to share suffixes. + ArrayRef SubRegIndices = RegBank.getSubRegIndices(); + // The lists of sub-registers and super-registers go in the same array. That + // allows us to share suffixes. typedef std::vector RegVec; - SmallVector SubRegLists(Regs.size()); - SmallVector OverlapLists(Regs.size()); - SequenceToOffsetTable RegSeqs; // Differentially encoded lists. SequenceToOffsetTable DiffSeqs; + SmallVector SubRegLists(Regs.size()); + SmallVector SuperRegLists(Regs.size()); SmallVector RegUnitLists(Regs.size()); SmallVector RegUnitInitScale(Regs.size()); + // Keep track of sub-register names as well. These are not differentially + // encoded. + typedef SmallVector SubRegIdxVec; + SequenceToOffsetTable SubRegIdxSeqs; + SmallVector SubRegIdxLists(Regs.size()); + SequenceToOffsetTable RegStrings; // Precompute register lists for the SequenceToOffsetTable. @@ -519,37 +730,20 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, // Compute the ordered sub-register list. SetVector SR; Reg->addSubRegsPreOrder(SR, RegBank); - RegVec &SubRegList = SubRegLists[i]; - SubRegList.assign(SR.begin(), SR.end()); - RegSeqs.add(SubRegList); + diffEncode(SubRegLists[i], Reg->EnumValue, SR.begin(), SR.end()); + DiffSeqs.add(SubRegLists[i]); + + // Compute the corresponding sub-register indexes. + SubRegIdxVec &SRIs = SubRegIdxLists[i]; + for (unsigned j = 0, je = SR.size(); j != je; ++j) + SRIs.push_back(Reg->getSubRegIndex(SR[j])); + SubRegIdxSeqs.add(SRIs); // Super-registers are already computed. const RegVec &SuperRegList = Reg->getSuperRegs(); - RegSeqs.add(SuperRegList); - - // The list of overlaps doesn't need to have any particular order, except - // Reg itself must be the first element. Pick an ordering that has one of - // the other lists as a suffix. - RegVec &OverlapList = OverlapLists[i]; - const RegVec &Suffix = SubRegList.size() > SuperRegList.size() ? - SubRegList : SuperRegList; - CodeGenRegister::Set Omit(Suffix.begin(), Suffix.end()); - - // First element is Reg itself. - OverlapList.push_back(Reg); - Omit.insert(Reg); - - // Any elements not in Suffix. - CodeGenRegister::Set OSet; - Reg->computeOverlaps(OSet, RegBank); - std::set_difference(OSet.begin(), OSet.end(), - Omit.begin(), Omit.end(), - std::back_inserter(OverlapList), - CodeGenRegister::Less()); - - // Finally, Suffix itself. - OverlapList.insert(OverlapList.end(), Suffix.begin(), Suffix.end()); - RegSeqs.add(OverlapList); + diffEncode(SuperRegLists[i], Reg->EnumValue, + SuperRegList.begin(), SuperRegList.end()); + DiffSeqs.add(SuperRegLists[i]); // Differentially encode the register unit list, seeded by register number. // First compute a scale factor that allows more diff-lists to be reused: @@ -578,23 +772,36 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, } // Compute the final layout of the sequence table. - RegSeqs.layout(); DiffSeqs.layout(); + SubRegIdxSeqs.layout(); OS << "namespace llvm {\n\n"; const std::string &TargetName = Target.getName(); - // Emit the shared table of register lists. - OS << "extern const uint16_t " << TargetName << "RegLists[] = {\n"; - RegSeqs.emit(OS, printRegister); - OS << "};\n\n"; - // Emit the shared table of differential lists. - OS << "extern const uint16_t " << TargetName << "RegDiffLists[] = {\n"; + OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n"; DiffSeqs.emit(OS, printDiff16); OS << "};\n\n"; + // Emit the table of sub-register indexes. + OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; + SubRegIdxSeqs.emit(OS, printSubRegIndex); + OS << "};\n\n"; + + // Emit the table of sub-register index sizes. + OS << "extern const MCRegisterInfo::SubRegCoveredBits " + << TargetName << "SubRegIdxRanges[] = {\n"; + OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n"; + for (ArrayRef::const_iterator + SRI = SubRegIndices.begin(), SRE = SubRegIndices.end(); + SRI != SRE; ++SRI) { + OS << " { " << (*SRI)->Offset << ", " + << (*SRI)->Size + << " },\t// " << (*SRI)->getName() << "\n"; + } + OS << "};\n\n"; + // Emit the string table. RegStrings.layout(); OS << "extern const char " << TargetName << "RegStrings[] = {\n"; @@ -609,13 +816,27 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, for (unsigned i = 0, e = Regs.size(); i != e; ++i) { const CodeGenRegister *Reg = Regs[i]; OS << " { " << RegStrings.get(Reg->getName()) << ", " - << RegSeqs.get(OverlapLists[i]) << ", " - << RegSeqs.get(SubRegLists[i]) << ", " - << RegSeqs.get(Reg->getSuperRegs()) << ", " + << DiffSeqs.get(SubRegLists[i]) << ", " + << DiffSeqs.get(SuperRegLists[i]) << ", " + << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", " << (DiffSeqs.get(RegUnitLists[i])*16 + RegUnitInitScale[i]) << " },\n"; } OS << "};\n\n"; // End of register descriptors... + // Emit the table of register unit roots. Each regunit has one or two root + // registers. + OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2] = {\n"; + for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) { + ArrayRef Roots = RegBank.getRegUnit(i).getRoots(); + assert(!Roots.empty() && "All regunits must have a root register."); + assert(Roots.size() <= 2 && "More than two roots not supported yet."); + OS << " { " << getQualifiedName(Roots.front()->TheDef); + for (unsigned r = 1; r != Roots.size(); ++r) + OS << ", " << getQualifiedName(Roots[r]->TheDef); + OS << " },\n"; + } + OS << "};\n\n"; + ArrayRef RegisterClasses = RegBank.getRegClasses(); // Loop over all of the register classes... emitting each one. @@ -677,38 +898,6 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "};\n\n"; - // Emit the data table for getSubReg(). - ArrayRef SubRegIndices = RegBank.getSubRegIndices(); - if (SubRegIndices.size()) { - OS << "const uint16_t " << TargetName << "SubRegTable[][" - << SubRegIndices.size() << "] = {\n"; - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs(); - OS << " /* " << Regs[i]->TheDef->getName() << " */\n"; - if (SRM.empty()) { - OS << " {0},\n"; - continue; - } - OS << " {"; - for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) { - // FIXME: We really should keep this to 80 columns... - CodeGenRegister::SubRegMap::const_iterator SubReg = - SRM.find(SubRegIndices[j]); - if (SubReg != SRM.end()) - OS << getQualifiedName(SubReg->second->TheDef); - else - OS << "0"; - if (j != je - 1) - OS << ", "; - } - OS << "}" << (i != e ? "," : "") << "\n"; - } - OS << "};\n\n"; - OS << "const uint16_t *get" << TargetName - << "SubRegTable() {\n return (const uint16_t *)" << TargetName - << "SubRegTable;\n}\n\n"; - } - EmitRegMappingTables(OS, Regs, false); // Emit Reg encoding table @@ -721,7 +910,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding"); uint64_t Value = 0; for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) { - if (BitInit *B = dynamic_cast(BI->getBit(b))) + if (BitInit *B = dyn_cast(BI->getBit(b))) Value |= (uint64_t)B->getValue() << b; } OS << " " << Value << ",\n"; @@ -731,21 +920,18 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " - << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; - OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " + << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) {\n" + << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " + << Regs.size()+1 << ", RA, PC, " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ", " + << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", " - << TargetName << "RegLists, " << TargetName << "RegDiffLists, " - << TargetName << "RegStrings, "; - if (SubRegIndices.size() != 0) - OS << "(uint16_t*)" << TargetName << "SubRegTable, " - << SubRegIndices.size() << ",\n"; - else - OS << "NULL, 0,\n"; - - OS << " " << TargetName << "RegEncodingTable);\n\n"; + << TargetName << "RegStrings, " + << TargetName << "SubRegIdxLists, " + << (SubRegIndices.size() + 1) << ",\n" + << TargetName << "SubRegIdxRanges, " + << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, false); @@ -758,7 +944,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &RegBank) { - EmitSourceFileHeader("Register Information Header Fragment", OS); + emitSourceFileHeader("Register Information Header Fragment", OS); OS << "\n#ifdef GET_REGINFO_HEADER\n"; OS << "#undef GET_REGINFO_HEADER\n"; @@ -772,21 +958,24 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, OS << "struct " << ClassName << " : public TargetRegisterInfo {\n" << " explicit " << ClassName - << "(unsigned RA, unsigned D = 0, unsigned E = 0);\n" + << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n" << " virtual bool needsStackRealignment(const MachineFunction &) const\n" << " { return false; }\n"; if (!RegBank.getSubRegIndices().empty()) { - OS << " unsigned composeSubRegIndices(unsigned, unsigned) const;\n" - << " const TargetRegisterClass *" + OS << " virtual unsigned composeSubRegIndicesImpl" + << "(unsigned, unsigned) const;\n" + << " virtual const TargetRegisterClass *" "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n"; } - OS << " const RegClassWeight &getRegClassWeight(" + OS << " virtual const RegClassWeight &getRegClassWeight(" << "const TargetRegisterClass *RC) const;\n" - << " unsigned getNumRegPressureSets() const;\n" - << " const char *getRegPressureSetName(unsigned Idx) const;\n" - << " unsigned getRegPressureSetLimit(unsigned Idx) const;\n" - << " const int *getRegClassPressureSets(" + << " virtual unsigned getRegUnitWeight(unsigned RegUnit) const;\n" + << " virtual unsigned getNumRegPressureSets() const;\n" + << " virtual const char *getRegPressureSetName(unsigned Idx) const;\n" + << " virtual unsigned getRegPressureSetLimit(unsigned Idx) const;\n" + << " virtual const int *getRegClassPressureSets(" << "const TargetRegisterClass *RC) const;\n" + << " virtual const int *getRegUnitPressureSets(unsigned RegUnit) const;\n" << "};\n\n"; ArrayRef RegisterClasses = RegBank.getRegClasses(); @@ -814,7 +1003,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, CodeGenRegBank &RegBank){ - EmitSourceFileHeader("Target Register and Register Classes Information", OS); + emitSourceFileHeader("Target Register and Register Classes Information", OS); OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n"; OS << "#undef GET_REGINFO_TARGET_DESC\n"; @@ -842,7 +1031,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, } // Build a shared array of value types. - SequenceToOffsetTable > VTSeqs; + SequenceToOffsetTable > VTSeqs; for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) VTSeqs.add(RegisterClasses[rc]->VTs); VTSeqs.layout(); @@ -850,26 +1039,23 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, VTSeqs.emit(OS, printSimpleValueType, "MVT::Other"); OS << "};\n"; - // Emit SubRegIndex names, skipping 0 - OS << "\nstatic const char *const SubRegIndexTable[] = { \""; + // Emit SubRegIndex names, skipping 0. + OS << "\nstatic const char *const SubRegIndexNameTable[] = { \""; for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { OS << SubRegIndices[i]->getName(); - if (i+1 != e) + if (i + 1 != e) OS << "\", \""; } OS << "\" };\n\n"; - // Emit names of the anonymous subreg indices. - unsigned NamedIndices = RegBank.getNumNamedIndices(); - if (SubRegIndices.size() > NamedIndices) { - OS << " enum {"; - for (unsigned i = NamedIndices, e = SubRegIndices.size(); i != e; ++i) { - OS << "\n " << SubRegIndices[i]->getName() << " = " << i+1; - if (i+1 != e) - OS << ','; - } - OS << "\n };\n\n"; + // Emit SubRegIndex lane masks, including 0. + OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n"; + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + OS << format(" 0x%08x, // ", SubRegIndices[i]->LaneMask) + << SubRegIndices[i]->getName() << '\n'; } + OS << " };\n\n"; + OS << "\n"; // Now that all of the structs have been emitted, emit the instances. @@ -952,12 +1138,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "\nstatic inline unsigned " << RC.getName() << "AltOrderSelect(const MachineFunction &MF) {" << RC.AltOrderSelect << "}\n\n" - << "static ArrayRef " << RC.getName() + << "static ArrayRef " << RC.getName() << "GetRawAllocationOrder(const MachineFunction &MF) {\n"; for (unsigned oi = 1 , oe = RC.getNumOrders(); oi != oe; ++oi) { ArrayRef Elems = RC.getOrder(oi); if (!Elems.empty()) { - OS << " static const uint16_t AltOrder" << oi << "[] = {"; + OS << " static const MCPhysReg AltOrder" << oi << "[] = {"; for (unsigned elem = 0; elem != Elems.size(); ++elem) OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]); OS << " };\n"; @@ -965,11 +1151,11 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << " const MCRegisterClass &MCR = " << Target.getName() << "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n" - << " const ArrayRef Order[] = {\n" + << " const ArrayRef Order[] = {\n" << " makeArrayRef(MCR.begin(), MCR.getNumRegs()"; for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi) if (RC.getOrder(oi).empty()) - OS << "),\n ArrayRef("; + OS << "),\n ArrayRef("; else OS << "),\n makeArrayRef(AltOrder" << oi; OS << ")\n };\n const unsigned Select = " << RC.getName() @@ -1031,31 +1217,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, std::string ClassName = Target.getName() + "GenRegisterInfo"; - // Emit composeSubRegIndices - if (!SubRegIndices.empty()) { - OS << "unsigned " << ClassName - << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n" - << " switch (IdxA) {\n" - << " default:\n return IdxB;\n"; - for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { - bool Open = false; - for (unsigned j = 0; j != e; ++j) { - if (CodeGenSubRegIndex *Comp = - SubRegIndices[i]->compose(SubRegIndices[j])) { - if (!Open) { - OS << " case " << SubRegIndices[i]->getQualifiedName() - << ": switch(IdxB) {\n default: return IdxB;\n"; - Open = true; - } - OS << " case " << SubRegIndices[j]->getQualifiedName() - << ": return " << Comp->getQualifiedName() << ";\n"; - } - } - if (Open) - OS << " }\n"; - } - OS << " }\n}\n\n"; - } + if (!SubRegIndices.empty()) + emitComposeSubRegIndices(OS, RegBank, ClassName); // Emit getSubClassWithSubReg. if (!SubRegIndices.empty()) { @@ -1069,7 +1232,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, else if (RegisterClasses.size() < UINT16_MAX) OS << " static const uint16_t Table["; else - throw "Too many register classes."; + PrintFatalError("Too many register classes."); OS << RegisterClasses.size() << "][" << SubRegIndices.size() << "] = {\n"; for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) { const CodeGenRegisterClass &RC = *RegisterClasses[rci]; @@ -1095,36 +1258,34 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the constructor of the class... OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n"; - OS << "extern const uint16_t " << TargetName << "RegLists[];\n"; - OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n"; + OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n"; OS << "extern const char " << TargetName << "RegStrings[];\n"; - if (SubRegIndices.size() != 0) - OS << "extern const uint16_t *get" << TargetName - << "SubRegTable();\n"; + OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n"; + OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n"; + OS << "extern const MCRegisterInfo::SubRegCoveredBits " + << TargetName << "SubRegIdxRanges[];\n"; OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n"; EmitRegMappingTables(OS, Regs, true); OS << ClassName << "::\n" << ClassName - << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n" + << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n" << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc" << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" - << " SubRegIndexTable) {\n" + << " SubRegIndexNameTable, SubRegIndexLaneMaskTable, 0x"; + OS.write_hex(RegBank.CoveringLanes); + OS << ") {\n" << " InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ", RA,\n " << TargetName + << Regs.size()+1 << ", RA, PC,\n " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" + << " " << TargetName << "RegUnitRoots,\n" << " " << RegBank.getNumNativeRegUnits() << ",\n" - << " " << TargetName << "RegLists,\n" << " " << TargetName << "RegDiffLists,\n" << " " << TargetName << "RegStrings,\n" - << " "; - if (SubRegIndices.size() != 0) - OS << "get" << TargetName << "SubRegTable(), " - << SubRegIndices.size() << ",\n"; - else - OS << "NULL, 0,\n"; - - OS << " " << TargetName << "RegEncodingTable);\n\n"; + << " " << TargetName << "SubRegIdxLists,\n" + << " " << SubRegIndices.size() + 1 << ",\n" + << " " << TargetName << "SubRegIdxRanges,\n" + << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, true); @@ -1140,7 +1301,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, assert(Regs && "Cannot expand CalleeSavedRegs instance"); // Emit the *_SaveList list of callee-saved registers. - OS << "static const uint16_t " << CSRSet->getName() + OS << "static const MCPhysReg " << CSRSet->getName() << "_SaveList[] = { "; for (unsigned r = 0, re = Regs->size(); r != re; ++r) OS << getQualifiedName((*Regs)[r]) << ", "; @@ -1168,3 +1329,11 @@ void RegisterInfoEmitter::run(raw_ostream &OS) { runTargetHeader(OS, Target, RegBank); runTargetDesc(OS, Target, RegBank); } + +namespace llvm { + +void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS) { + RegisterInfoEmitter(RK).run(OS); +} + +} // End llvm namespace