From: Matthias Braun Date: Wed, 10 Dec 2014 01:12:56 +0000 (+0000) Subject: Tablegen'erate lanemasks for register units. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84cc6ec88948083632c6aa4db586e8d576be1b31;p=llvm Tablegen'erate lanemasks for register units. Now we can relate lanemasks in a virtual register to register units. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223889 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index df556e7e50f..e02f35d2cdd 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -114,6 +114,10 @@ struct MCRegisterDesc { // RegUnits - Points to the list of register units. The low 4 bits holds the // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator. uint32_t RegUnits; + + /// Index into list with lane mask sequences. The sequence contains a lanemask + /// for every register unit. + uint16_t RegUnitLaneMasks; }; /// MCRegisterInfo base class - We assume that the target defines a static @@ -157,6 +161,8 @@ private: unsigned NumRegUnits; // Number of regunits. const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table. const MCPhysReg *DiffLists; // Pointer to the difflists array + const unsigned *RegUnitMaskSequences; // Pointer to lane mask sequences + // for register units. const char *RegStrings; // Pointer to the string table. const char *RegClassStrings; // Pointer to the class strings. const uint16_t *SubRegIndices; // Pointer to the subreg lookup @@ -229,6 +235,7 @@ public: friend class MCSubRegIterator; friend class MCSuperRegIterator; friend class MCRegUnitIterator; + friend class MCRegUnitMaskIterator; friend class MCRegUnitRootIterator; /// \brief Initialize MCRegisterInfo, called by TableGen @@ -239,6 +246,7 @@ public: const MCPhysReg (*RURoots)[2], unsigned NRU, const MCPhysReg *DL, + const unsigned *RUMS, const char *Strings, const char *ClassStrings, const uint16_t *SubIndices, @@ -251,6 +259,7 @@ public: PCReg = PC; Classes = C; DiffLists = DL; + RegUnitMaskSequences = RUMS; RegStrings = Strings; RegClassStrings = ClassStrings; NumClasses = NC; @@ -513,6 +522,36 @@ public: } }; +/// MCRegUnitIterator enumerates a list of register units and their associated +/// lane masks for Reg. The register units are in ascending numerical order. +class MCRegUnitMaskIterator { + MCRegUnitIterator RUIter; + const unsigned *MaskListIter; +public: + MCRegUnitMaskIterator() {} + /// Constructs an iterator that traverses the register units and their + /// associated LaneMasks in Reg. + MCRegUnitMaskIterator(unsigned Reg, const MCRegisterInfo *MCRI) + : RUIter(Reg, MCRI) { + uint16_t Idx = MCRI->get(Reg).RegUnitLaneMasks; + MaskListIter = &MCRI->RegUnitMaskSequences[Idx]; + } + + /// Returns a (RegUnit, LaneMask) pair. + std::pair operator*() const { + return std::make_pair(*RUIter, *MaskListIter); + } + + /// Returns true if this iterator is not yet at the end. + bool isValid() const { return RUIter.isValid(); } + + /// Moves to the next position. + void operator++() { + ++MaskListIter; + ++RUIter; + } +}; + // Each register unit has one or two root registers. The complete set of // registers containing a register unit is the union of the roots and their // super-registers. All registers aliasing Unit can be visited like this: diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index f37c3aec1ca..d252f76d939 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -1763,6 +1763,41 @@ void CodeGenRegBank::computeRegUnitSets() { } } +void CodeGenRegBank::computeRegUnitLaneMasks() { + for (auto &Register : Registers) { + // Create an initial lane mask for all register units. + const auto &RegUnits = Register.getRegUnits(); + CodeGenRegister::RegUnitLaneMaskList RegUnitLaneMasks(RegUnits.size(), 0); + // Iterate through SubRegisters. + typedef CodeGenRegister::SubRegMap SubRegMap; + const SubRegMap &SubRegs = Register.getSubRegs(); + for (SubRegMap::const_iterator S = SubRegs.begin(), + SE = SubRegs.end(); S != SE; ++S) { + CodeGenRegister *SubReg = S->second; + // Ignore non-leaf subregisters, their lane masks are fully covered by + // the leaf subregisters anyway. + if (SubReg->getSubRegs().size() != 0) + continue; + CodeGenSubRegIndex *SubRegIndex = S->first; + const CodeGenRegister *SubRegister = S->second; + unsigned LaneMask = SubRegIndex->LaneMask; + // Distribute LaneMask to Register Units touched. + for (const auto &SUI : SubRegister->getRegUnits()) { + bool Found = false; + for (size_t u = 0, ue = RegUnits.size(); u < ue; ++u) { + if (SUI == RegUnits[u]) { + RegUnitLaneMasks[u] |= LaneMask; + assert(!Found); + Found = true; + } + } + assert(Found); + } + } + Register.setRegUnitLaneMasks(RegUnitLaneMasks); + } +} + void CodeGenRegBank::computeDerivedInfo() { computeComposites(); computeSubRegLaneMasks(); @@ -1775,6 +1810,8 @@ void CodeGenRegBank::computeDerivedInfo() { // supersets for the union of overlapping sets. computeRegUnitSets(); + computeRegUnitLaneMasks(); + // Get the weight of each set. for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) RegUnitSets[Idx].Weight = getRegUnitSetWeight(RegUnitSets[Idx].Units); diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index d4668a05f33..87a0dcf7af3 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -198,6 +198,7 @@ namespace llvm { // List of register units in ascending order. typedef SmallVector RegUnitList; + typedef SmallVector RegUnitLaneMaskList; // How many entries in RegUnitList are native? unsigned NumNativeRegUnits; @@ -206,11 +207,19 @@ namespace llvm { // This is only valid after computeSubRegs() completes. const RegUnitList &getRegUnits() const { return RegUnits; } + ArrayRef getRegUnitLaneMasks() const { + return makeArrayRef(RegUnitLaneMasks).slice(0, NumNativeRegUnits); + } + // Get the native register units. This is a prefix of getRegUnits(). ArrayRef getNativeRegUnits() const { return makeArrayRef(RegUnits).slice(0, NumNativeRegUnits); } + void setRegUnitLaneMasks(const RegUnitLaneMaskList &LaneMasks) { + RegUnitLaneMasks = LaneMasks; + } + // Inherit register units from subregisters. // Return true if the RegUnits changed. bool inheritRegUnits(CodeGenRegBank &RegBank); @@ -253,6 +262,7 @@ namespace llvm { SuperRegList SuperRegs; DenseMap SubReg2Idx; RegUnitList RegUnits; + RegUnitLaneMaskList RegUnitLaneMasks; }; @@ -544,6 +554,10 @@ namespace llvm { // Compute a lane mask for each sub-register index. void computeSubRegLaneMasks(); + /// Computes a lane mask for each register unit enumerated by a physical + /// register. + void computeRegUnitLaneMasks(); + public: CodeGenRegBank(RecordKeeper&); diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index bde6a174dd1..1c3de4a2c2b 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -568,6 +568,7 @@ static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) { // 0 differential which means we can't encode repeated elements. typedef SmallVector DiffVec; +typedef SmallVector MaskVec; // 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. @@ -600,6 +601,10 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) { OS << Val; } +static void printMask(raw_ostream &OS, unsigned Val) { + OS << format("0x%08X", 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, @@ -803,6 +808,10 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, SmallVector RegUnitLists(Regs.size()); SmallVector RegUnitInitScale(Regs.size()); + // List of lane masks accompanying register unit sequences. + SequenceToOffsetTable LaneMaskSeqs; + SmallVector RegUnitLaneMasks(Regs.size()); + // Keep track of sub-register names as well. These are not differentially // encoded. typedef SmallVector SubRegIdxVec; @@ -813,7 +822,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, // Precompute register lists for the SequenceToOffsetTable. unsigned i = 0; - for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I) { + for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) { const auto &Reg = *I; RegStrings.add(Reg.getName()); @@ -860,11 +869,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, Scale = 0; RegUnitInitScale[i] = Scale; DiffSeqs.add(diffEncode(RegUnitLists[i], Scale * Reg.EnumValue, RUs)); - ++i; + + const auto &RUMasks = Reg.getRegUnitLaneMasks(); + MaskVec &LaneMaskVec = RegUnitLaneMasks[i]; + assert(LaneMaskVec.empty()); + LaneMaskVec.insert(LaneMaskVec.begin(), RUMasks.begin(), RUMasks.end()); + // Terminator mask should not be used inside of the list. +#ifndef NDEBUG + for (unsigned M : LaneMaskVec) { + assert(M != ~0u && "terminator mask should not be part of the list"); + } +#endif + LaneMaskSeqs.add(LaneMaskVec); } // Compute the final layout of the sequence table. DiffSeqs.layout(); + LaneMaskSeqs.layout(); SubRegIdxSeqs.layout(); OS << "namespace llvm {\n\n"; @@ -876,6 +897,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, DiffSeqs.emit(OS, printDiff16); OS << "};\n\n"; + // Emit the shared table of regunit lane mask sequences. + OS << "extern const unsigned " << TargetName << "LaneMaskLists[] = {\n"; + LaneMaskSeqs.emit(OS, printMask, "~0u"); + OS << "};\n\n"; + // Emit the table of sub-register indexes. OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; SubRegIdxSeqs.emit(OS, printSubRegIndex); @@ -899,7 +925,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; - OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0 },\n"; + OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n"; // Emit the register descriptors now. i = 0; @@ -907,7 +933,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << " { " << RegStrings.get(Reg.getName()) << ", " << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i]) << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", " - << (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << " },\n"; + << (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << ", " + << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << " },\n"; ++i; } OS << "};\n\n"; // End of register descriptors... @@ -1021,8 +1048,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << Regs.size() + 1 << ", RA, PC, " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, " - << TargetName << "RegStrings, " << TargetName << "RegClassStrings, " - << TargetName << "SubRegIdxLists, " + << TargetName << "LaneMaskLists, " << TargetName << "RegStrings, " + << TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, " << (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n" << TargetName << "SubRegIdxRanges, " << TargetName << "RegEncodingTable);\n\n"; @@ -1349,6 +1376,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the constructor of the class... OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n"; OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n"; + OS << "extern const unsigned " << TargetName << "LaneMaskLists[];\n"; OS << "extern const char " << TargetName << "RegStrings[];\n"; OS << "extern const char " << TargetName << "RegClassStrings[];\n"; OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n"; @@ -1372,6 +1400,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " " << TargetName << "RegUnitRoots,\n" << " " << RegBank.getNumNativeRegUnits() << ",\n" << " " << TargetName << "RegDiffLists,\n" + << " " << TargetName << "LaneMaskLists,\n" << " " << TargetName << "RegStrings,\n" << " " << TargetName << "RegClassStrings,\n" << " " << TargetName << "SubRegIdxLists,\n"