[llvm] r183020 - Add a way to define the bit range covered by a SubRegIndex.

Ahmed Bougacha ahmed.bougacha at gmail.com
Fri May 31 10:08:36 PDT 2013


Author: ab
Date: Fri May 31 12:08:36 2013
New Revision: 183020

URL: http://llvm.org/viewvc/llvm-project?rev=183020&view=rev
Log:
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.


Modified:
    llvm/trunk/include/llvm/MC/MCRegisterInfo.h
    llvm/trunk/include/llvm/Target/Target.td
    llvm/trunk/lib/MC/MCRegisterInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td
    llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td
    llvm/trunk/lib/Target/X86/X86RegisterInfo.td
    llvm/trunk/utils/TableGen/CodeGenRegisters.cpp
    llvm/trunk/utils/TableGen/CodeGenRegisters.h
    llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp

Modified: llvm/trunk/include/llvm/MC/MCRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCRegisterInfo.h?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCRegisterInfo.h (original)
+++ llvm/trunk/include/llvm/MC/MCRegisterInfo.h Fri May 31 12:08:36 2013
@@ -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 {

Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Fri May 31 12:08:36 2013
@@ -22,12 +22,19 @@ include "llvm/IR/Intrinsics.td"
 class RegisterClass; // Forward def
 
 // SubRegIndex - Use instances of SubRegIndex to identify subregisters.
-class SubRegIndex<list<SubRegIndex> comps = []> {
+class SubRegIndex<int size = -1, int offset = 0> {
   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<SubRegIndex> ComposedOf = comps;
+  // See ComposedSubRegIndex.
+  list<SubRegIndex> ComposedOf = [];
 
   // CoveringSubRegIndices - A list of two or more sub-register indexes that
   // cover this sub-register.
@@ -48,6 +55,14 @@ class SubRegIndex<list<SubRegIndex> comp
   list<SubRegIndex> 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 A, SubRegIndex B>
+  : SubRegIndex<B.Size, -1> {
+  // See SubRegIndex.
+  let ComposedOf = [A, B];
+}
+
 // RegAltNameIndex - The alternate name set to use for register operands of
 // this register class when printing.
 class RegAltNameIndex {

Modified: llvm/trunk/lib/MC/MCRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCRegisterInfo.cpp?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCRegisterInfo.cpp (original)
+++ llvm/trunk/lib/MC/MCRegisterInfo.cpp Fri May 31 12:08:36 2013
@@ -46,6 +46,19 @@ unsigned MCRegisterInfo::getSubRegIndex(
   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;

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td Fri May 31 12:08:36 2013
@@ -27,31 +27,31 @@ class ARMFReg<bits<16> Enc, string n> :
 
 // 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 qsub_0 : SubRegIndex<128>;
+def qsub_1 : SubRegIndex<128, 128>;
+def qsub_2 : ComposedSubRegIndex<qqsub_1, qsub_0>;
+def qsub_3 : ComposedSubRegIndex<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 dsub_0 : SubRegIndex<64>;
+def dsub_1 : SubRegIndex<64, 64>;
+def dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>;
+def dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>;
+def dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>;
+def dsub_5 : ComposedSubRegIndex<qsub_2, dsub_1>;
+def dsub_6 : ComposedSubRegIndex<qsub_3, dsub_0>;
+def dsub_7 : ComposedSubRegIndex<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 ssub_0  : SubRegIndex<32>;
+def ssub_1  : SubRegIndex<32, 32>;
+def ssub_2  : ComposedSubRegIndex<dsub_1, ssub_0>;
+def ssub_3  : ComposedSubRegIndex<dsub_1, ssub_1>;
 
-def gsub_0  : SubRegIndex;
-def gsub_1  : SubRegIndex;
+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.
 }

Modified: llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZRegisterInfo.td Fri May 31 12:08:36 2013
@@ -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<subreg_low, subreg_32bit>;
 }
 
 // Define a register class that contains values of type TYPE and an

Modified: llvm/trunk/lib/Target/X86/X86RegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86RegisterInfo.td?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86RegisterInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86RegisterInfo.td Fri May 31 12:08:36 2013
@@ -21,11 +21,11 @@ class X86Reg<string n, bits<16> Enc, lis
 
 // 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>;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Fri May 31 12:08:36 2013
@@ -32,12 +32,14 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(R
   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::updateComponent
   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<CodeGenSubRegIndex*, 8> IdxParts;
     for (unsigned i = 0, e = Parts.size(); i != e; ++i)
       IdxParts.push_back(RegBank.getSubRegIdx(Parts[i]));

Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.h?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenRegisters.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenRegisters.h Fri May 31 12:08:36 2013
@@ -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<CompMap::iterator, bool> 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;
     }
 

Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=183020&r1=183019&r2=183020&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Fri May 31 12:08:36 2013
@@ -703,6 +703,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostre
 
   const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
 
+  ArrayRef<CodeGenSubRegIndex*> 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<const CodeGenRegister*> RegVec;
@@ -790,6 +791,19 @@ RegisterInfoEmitter::runMCDesc(raw_ostre
   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<CodeGenSubRegIndex*>::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_ostre
 
   OS << "};\n\n";
 
-  ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
-
   EmitRegMappingTables(OS, Regs, false);
 
   // Emit Reg encoding table
@@ -920,6 +932,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostre
      << 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_o
   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_o
      << "                     " << TargetName << "RegStrings,\n"
      << "                     " << TargetName << "SubRegIdxLists,\n"
      << "                     " << SubRegIndices.size() + 1 << ",\n"
+     << "                     " << TargetName << "SubRegIdxRanges,\n"
      << "                     " << TargetName << "RegEncodingTable);\n\n";
 
   EmitRegMapping(OS, Regs, true);





More information about the llvm-commits mailing list