From: Ahmed Bougacha Date: Fri, 31 May 2013 17:08:36 +0000 (+0000) Subject: Add a way to define the bit range covered by a SubRegIndex. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=bed23081860275c79137f65d592920e7991b8198 Add a way to define the bit range covered by a SubRegIndex. NOTE: If this broke your out-of-tree backend, in *RegisterInfo.td, change the instances of SubRegIndex that have a comps template arg to use the ComposedSubRegIndex class instead. In TableGen land, this adds Size and Offset attributes to SubRegIndex, and the ComposedSubRegIndex class, for which the Size and Offset are computed by TableGen. This also adds an accessor in MCRegisterInfo, and Size/Offsets for the X86 and ARM subreg indices. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183020 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 0c4a53f6150..002f71d5018 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -144,6 +144,13 @@ public: bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; } }; + + /// SubRegCoveredBits - Emitted by tablegen: bit range covered by a subreg + /// index, -1 in any being invalid. + struct SubRegCoveredBits { + uint16_t Offset; + uint16_t Size; + }; private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array @@ -157,6 +164,8 @@ private: const char *RegStrings; // Pointer to the string table. const uint16_t *SubRegIndices; // Pointer to the subreg lookup // array. + const SubRegCoveredBits *SubRegIdxRanges; // Pointer to the subreg covered + // bit ranges array. unsigned NumSubRegIndices; // Number of subreg indices. const uint16_t *RegEncodingTable; // Pointer to array of register // encodings. @@ -236,6 +245,7 @@ public: const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, + const SubRegCoveredBits *SubIdxRanges, const uint16_t *RET) { Desc = D; NumRegs = NR; @@ -249,6 +259,7 @@ public: NumRegUnits = NRU; SubRegIndices = SubIndices; NumSubRegIndices = NumIndices; + SubRegIdxRanges = SubIdxRanges; RegEncodingTable = RET; } @@ -327,6 +338,13 @@ public: /// otherwise. unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; + /// \brief Get the bit range covered by a given sub-register index. + /// In some cases, for instance non-contiguous synthesized indices, + /// there is no meaningful bit range to get, so return true if \p Offset + /// and \p Size were set. + bool getSubRegIdxCoveredBits(unsigned Idx, + unsigned &Offset, unsigned &Size) const; + /// \brief Return the human-readable symbolic target-specific name for the /// specified physical register. const char *getName(unsigned RegNo) const { diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 7de8b384c35..c201f6baab0 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -22,12 +22,19 @@ include "llvm/IR/Intrinsics.td" class RegisterClass; // Forward def // SubRegIndex - Use instances of SubRegIndex to identify subregisters. -class SubRegIndex comps = []> { +class SubRegIndex { string Namespace = ""; + // Size - Size (in bits) of the sub-registers represented by this index. + int Size = size; + + // Offset - Offset of the first bit that is part of this sub-register index. + int Offset = offset; + // ComposedOf - A list of two SubRegIndex instances, [A, B]. // This indicates that this SubRegIndex is the result of composing A and B. - list ComposedOf = comps; + // See ComposedSubRegIndex. + list ComposedOf = []; // CoveringSubRegIndices - A list of two or more sub-register indexes that // cover this sub-register. @@ -48,6 +55,14 @@ class SubRegIndex comps = []> { list CoveringSubRegIndices = []; } +// ComposedSubRegIndex - A sub-register that is the result of composing A and B. +// Offset is set to the sum of A and B's Offsets. Size is set to B's Size. +class ComposedSubRegIndex + : SubRegIndex { + // See SubRegIndex. + let ComposedOf = [A, B]; +} + // RegAltNameIndex - The alternate name set to use for register operands of // this register class when printing. class RegAltNameIndex { diff --git a/lib/MC/MCRegisterInfo.cpp b/lib/MC/MCRegisterInfo.cpp index 5c71106c901..06d6d9680dd 100644 --- a/lib/MC/MCRegisterInfo.cpp +++ b/lib/MC/MCRegisterInfo.cpp @@ -46,6 +46,19 @@ unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const { return 0; } +bool MCRegisterInfo::getSubRegIdxCoveredBits(unsigned Idx, unsigned &Offset, + unsigned &Size) const { + assert(Idx && Idx < getNumSubRegIndices() && + "This is not a subregister index"); + // Get a pointer to the corresponding SubRegIdxRanges struct. + const SubRegCoveredBits *Bits = &SubRegIdxRanges[Idx]; + if (Bits->Offset == (uint16_t)-1 || Bits->Size == (uint16_t)-1) + return false; + Offset = Bits->Offset; + Size = Bits->Size; + return true; +} + int MCRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs; unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize; diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 85743d8d5ad..3ffe0e908ab 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -27,31 +27,31 @@ class ARMFReg Enc, string n> : Register { // Subregister indices. let Namespace = "ARM" in { -def qqsub_0 : SubRegIndex; -def qqsub_1 : SubRegIndex; +def qqsub_0 : SubRegIndex<256>; +def qqsub_1 : SubRegIndex<256, 256>; // Note: Code depends on these having consecutive numbers. -def qsub_0 : SubRegIndex; -def qsub_1 : SubRegIndex; -def qsub_2 : SubRegIndex<[qqsub_1, qsub_0]>; -def qsub_3 : SubRegIndex<[qqsub_1, qsub_1]>; - -def dsub_0 : SubRegIndex; -def dsub_1 : SubRegIndex; -def dsub_2 : SubRegIndex<[qsub_1, dsub_0]>; -def dsub_3 : SubRegIndex<[qsub_1, dsub_1]>; -def dsub_4 : SubRegIndex<[qsub_2, dsub_0]>; -def dsub_5 : SubRegIndex<[qsub_2, dsub_1]>; -def dsub_6 : SubRegIndex<[qsub_3, dsub_0]>; -def dsub_7 : SubRegIndex<[qsub_3, dsub_1]>; - -def ssub_0 : SubRegIndex; -def ssub_1 : SubRegIndex; -def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>; -def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>; - -def gsub_0 : SubRegIndex; -def gsub_1 : SubRegIndex; +def qsub_0 : SubRegIndex<128>; +def qsub_1 : SubRegIndex<128, 128>; +def qsub_2 : ComposedSubRegIndex; +def qsub_3 : ComposedSubRegIndex; + +def dsub_0 : SubRegIndex<64>; +def dsub_1 : SubRegIndex<64, 64>; +def dsub_2 : ComposedSubRegIndex; +def dsub_3 : ComposedSubRegIndex; +def dsub_4 : ComposedSubRegIndex; +def dsub_5 : ComposedSubRegIndex; +def dsub_6 : ComposedSubRegIndex; +def dsub_7 : ComposedSubRegIndex; + +def ssub_0 : SubRegIndex<32>; +def ssub_1 : SubRegIndex<32, 32>; +def ssub_2 : ComposedSubRegIndex; +def ssub_3 : ComposedSubRegIndex; + +def gsub_0 : SubRegIndex<32>; +def gsub_1 : SubRegIndex<32, 32>; // Let TableGen synthesize the remaining 12 ssub_* indices. // We don't need to name them. } diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.td b/lib/Target/SystemZ/SystemZRegisterInfo.td index 7e4f0b96e92..7795fffb640 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.td +++ b/lib/Target/SystemZ/SystemZRegisterInfo.td @@ -24,7 +24,7 @@ let Namespace = "SystemZ" in { def subreg_32bit : SubRegIndex; // could also be known as "subreg_high32" def subreg_high : SubRegIndex; def subreg_low : SubRegIndex; -def subreg_low32 : SubRegIndex<[subreg_low, subreg_32bit]>; +def subreg_low32 : ComposedSubRegIndex; } // Define a register class that contains values of type TYPE and an diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index be6282a643b..edf22ee1127 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -21,11 +21,11 @@ class X86Reg Enc, list subregs = []> : Register // Subregister indices. let Namespace = "X86" in { - def sub_8bit : SubRegIndex; - def sub_8bit_hi : SubRegIndex; - def sub_16bit : SubRegIndex; - def sub_32bit : SubRegIndex; - def sub_xmm : SubRegIndex; + def sub_8bit : SubRegIndex<8>; + def sub_8bit_hi : SubRegIndex<8, 8>; + def sub_16bit : SubRegIndex<16>; + def sub_32bit : SubRegIndex<32>; + def sub_xmm : SubRegIndex<64>; } //===----------------------------------------------------------------------===// diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 9d72d0d4bd6..3eed3ffb5f4 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -32,12 +32,14 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) Name = R->getName(); if (R->getValue("Namespace")) Namespace = R->getValueAsString("Namespace"); + Size = R->getValueAsInt("Size"); + Offset = R->getValueAsInt("Offset"); } CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum) - : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), - LaneMask(0), AllSuperRegsCovered(true) { + : TheDef(0), Name(N), Namespace(Nspace), Size(-1), Offset(-1), + EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) { } std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -69,7 +71,7 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { if (!Parts.empty()) { if (Parts.size() < 2) PrintFatalError(TheDef->getLoc(), - "CoveredBySubRegs must have two or more entries"); + "CoveredBySubRegs must have two or more entries"); SmallVector IdxParts; for (unsigned i = 0, e = Parts.size(); i != e; ++i) IdxParts.push_back(RegBank.getSubRegIdx(Parts[i])); diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index ba62db48274..c83455149a6 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -37,6 +37,8 @@ namespace llvm { Record *const TheDef; std::string Name; std::string Namespace; + uint16_t Size; + uint16_t Offset; public: const unsigned EnumValue; @@ -52,6 +54,8 @@ namespace llvm { const std::string &getName() const { return Name; } const std::string &getNamespace() const { return Namespace; } std::string getQualifiedName() const; + uint16_t getSize() const { return Size; } + uint16_t getOffset() const { return Offset; } // Order CodeGenSubRegIndex pointers by EnumValue. struct Less { @@ -79,6 +83,15 @@ namespace llvm { assert(A && B); std::pair Ins = Composed.insert(std::make_pair(A, B)); + // Synthetic subreg indices that aren't contiguous (for instance ARM + // register tuples) don't have a bit range, so it's OK to let + // B->Offset == -1. For the other cases, accumulate the offset and set + // the size here. Only do so if there is no offset yet though. + if ((Offset != (uint16_t)-1 && A->Offset != (uint16_t)-1) && + (B->Offset == (uint16_t)-1)) { + B->Offset = Offset + A->Offset; + B->Size = A->Size; + } return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second; } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 2907c3332d5..9978237a185 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -703,6 +703,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, const std::vector &Regs = RegBank.getRegisters(); + 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; @@ -790,6 +791,19 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, 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)->getOffset() << ", " + << (*SRI)->getSize() + << " },\t// " << (*SRI)->getName() << "\n"; + } + OS << "};\n\n"; + // Emit the string table. RegStrings.layout(); OS << "extern const char " << TargetName << "RegStrings[] = {\n"; @@ -886,8 +900,6 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "};\n\n"; - ArrayRef SubRegIndices = RegBank.getSubRegIndices(); - EmitRegMappingTables(OS, Regs, false); // Emit Reg encoding table @@ -920,6 +932,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << TargetName << "RegStrings, " << TargetName << "SubRegIdxLists, " << (SubRegIndices.size() + 1) << ",\n" + << TargetName << "SubRegIdxRanges, " << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, false); @@ -1251,6 +1264,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const char " << TargetName << "RegStrings[];\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); @@ -1271,6 +1286,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " " << TargetName << "RegStrings,\n" << " " << TargetName << "SubRegIdxLists,\n" << " " << SubRegIndices.size() + 1 << ",\n" + << " " << TargetName << "SubRegIdxRanges,\n" << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, true);