Add TargetRegisterInfo::getCoveringLanes().
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 16 May 2013 18:03:08 +0000 (18:03 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 16 May 2013 18:03:08 +0000 (18:03 +0000)
This lane mask provides information about which register lanes
completely cover super-registers. See the block comment before
getCoveringLanes().

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182034 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetRegisterInfo.h
lib/CodeGen/TargetRegisterInfo.cpp
utils/TableGen/CodeGenRegisters.cpp
utils/TableGen/CodeGenRegisters.h
utils/TableGen/RegisterInfoEmitter.cpp

index 6b1e70bba11b24d732d4bc4970f36be90a8dcd53..82fccde8de831534c589226745d80c1691c9e9c6 100644 (file)
@@ -226,13 +226,15 @@ private:
   const unsigned *SubRegIndexLaneMasks;
 
   regclass_iterator RegClassBegin, RegClassEnd;   // List of regclasses
+  unsigned CoveringLanes;
 
 protected:
   TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
                      regclass_iterator RegClassBegin,
                      regclass_iterator RegClassEnd,
                      const char *const *SRINames,
-                     const unsigned *SRILaneMasks);
+                     const unsigned *SRILaneMasks,
+                     unsigned CoveringLanes);
   virtual ~TargetRegisterInfo();
 public:
 
@@ -362,6 +364,31 @@ public:
     return SubRegIndexLaneMasks[SubIdx];
   }
 
+  /// The lane masks returned by getSubRegIndexLaneMask() above can only be
+  /// used to determine if sub-registers overlap - they can't be used to
+  /// determine if a set of sub-registers completely cover another
+  /// sub-register.
+  ///
+  /// The X86 general purpose registers have two lanes corresponding to the
+  /// sub_8bit and sub_8bit_hi sub-registers. Both sub_32bit and sub_16bit have
+  /// lane masks '3', but the sub_16bit sub-register doesn't fully cover the
+  /// sub_32bit sub-register.
+  ///
+  /// On the other hand, the ARM NEON lanes fully cover their registers: The
+  /// dsub_0 sub-register is completely covered by the ssub_0 and ssub_1 lanes.
+  /// This is related to the CoveredBySubRegs property on register definitions.
+  ///
+  /// This function returns a bit mask of lanes that completely cover their
+  /// sub-registers. More precisely, given:
+  ///
+  ///   Covering = getCoveringLanes();
+  ///   MaskA = getSubRegIndexLaneMask(SubA);
+  ///   MaskB = getSubRegIndexLaneMask(SubB);
+  ///
+  /// If (MaskA & ~(MaskB & Covering)) == 0, then SubA is completely covered by
+  /// SubB.
+  unsigned getCoveringLanes() const { return CoveringLanes; }
+
   /// regsOverlap - Returns true if the two registers are equal or alias each
   /// other. The registers may be virtual register.
   bool regsOverlap(unsigned regA, unsigned regB) const {
index 84b4bfc33221724548feea05a4989a76390326e2..4c21daf07a5c9362cd26ea4a6ae998283d682c4e 100644 (file)
@@ -23,10 +23,12 @@ using namespace llvm;
 TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
                              regclass_iterator RCB, regclass_iterator RCE,
                              const char *const *SRINames,
-                             const unsigned *SRILaneMasks)
+                             const unsigned *SRILaneMasks,
+                             unsigned SRICoveringLanes)
   : InfoDesc(ID), SubRegIndexNames(SRINames),
     SubRegIndexLaneMasks(SRILaneMasks),
-    RegClassBegin(RCB), RegClassEnd(RCE) {
+    RegClassBegin(RCB), RegClassEnd(RCE),
+    CoveringLanes(SRICoveringLanes) {
 }
 
 TargetRegisterInfo::~TargetRegisterInfo() {}
index 993b8dba426730089627597aeec36767aaf8b098..1fe08b84b899f7212e1658b73438964fb5382232 100644 (file)
@@ -28,7 +28,7 @@ using namespace llvm;
 //===----------------------------------------------------------------------===//
 
 CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
-  : TheDef(R), EnumValue(Enum), LaneMask(0) {
+  : TheDef(R), EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) {
   Name = R->getName();
   if (R->getValue("Namespace"))
     Namespace = R->getValueAsString("Namespace");
@@ -36,7 +36,8 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
 
 CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace,
                                        unsigned Enum)
-  : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), LaneMask(0) {
+  : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum),
+    LaneMask(0), AllSuperRegsCovered(true) {
 }
 
 std::string CodeGenSubRegIndex::getQualifiedName() const {
@@ -312,6 +313,11 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
       PrintFatalError(Loc, "Register " + getName() +
                       " has itself as a sub-register");
     }
+
+    // Compute AllSuperRegsCovered.
+    if (!CoveredBySubRegs)
+      SI->first->AllSuperRegsCovered = false;
+
     // Ensure that every sub-register has a unique name.
     DenseMap<const CodeGenRegister*, CodeGenSubRegIndex*>::iterator Ins =
       SubReg2Idx.insert(std::make_pair(SI->second, SI->first)).first;
@@ -1195,6 +1201,8 @@ void CodeGenRegBank::computeComposites() {
 void CodeGenRegBank::computeSubRegIndexLaneMasks() {
   // First assign individual bits to all the leaf indices.
   unsigned Bit = 0;
+  // Determine mask of lanes that cover their registers.
+  CoveringLanes = ~0u;
   for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
     CodeGenSubRegIndex *Idx = SubRegIndices[i];
     if (Idx->getComposites().empty()) {
@@ -1206,7 +1214,12 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
       // view of lanes beyond the 32nd.
       //
       // See also the comment for getSubRegIndexLaneMask().
-      if (Bit < 31) ++Bit;
+      if (Bit < 31)
+        ++Bit;
+      else
+        // Once bit 31 is shared among multiple leafs, the 'lane' it represents
+        // is no longer covering its registers.
+        CoveringLanes &= ~(1u << Bit);
     } else {
       Idx->LaneMask = 0;
     }
@@ -1216,8 +1229,13 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() {
   // by the sub-register graph? This doesn't occur in any known targets.
 
   // Inherit lanes from composites.
-  for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
-    SubRegIndices[i]->computeLaneMask();
+  for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
+    unsigned Mask = SubRegIndices[i]->computeLaneMask();
+    // If some super-registers without CoveredBySubRegs use this index, we can
+    // no longer assume that the lanes are covering their registers.
+    if (!SubRegIndices[i]->AllSuperRegsCovered)
+      CoveringLanes &= ~Mask;
+  }
 }
 
 namespace {
index 4f2cc28d492497aa323b307fc5d1a99efbd40efc..b56555dade65155d2a0178832239d85a7acd5451 100644 (file)
@@ -42,6 +42,10 @@ namespace llvm {
     const unsigned EnumValue;
     unsigned LaneMask;
 
+    // Are all super-registers containing this SubRegIndex covered by their
+    // sub-registers?
+    bool AllSuperRegsCovered;
+
     CodeGenSubRegIndex(Record *R, unsigned Enum);
     CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum);
 
@@ -649,6 +653,11 @@ namespace llvm {
     // This is used to compute the mask of call-preserved registers from a list
     // of callee-saves.
     BitVector computeCoveredRegisters(ArrayRef<Record*> Regs);
+
+    // Bit mask of lanes that cover their registers. A sub-register index whose
+    // LaneMask is contained in CoveringLanes will be completely covered by
+    // another sub-register with the same or larger lane mask.
+    unsigned CoveringLanes;
   };
 }
 
index 1b5d90b8bda260537e193c1e276d6c9b5eec52bb..f519b21de067370fc2b92cd90b722a3430430dfa 100644 (file)
@@ -1270,7 +1270,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
      << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
      << "  : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
      << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
-     << "             SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
+     << "             SubRegIndexNameTable, SubRegIndexLaneMaskTable, 0x";
+  OS.write_hex(RegBank.CoveringLanes);
+  OS << ") {\n"
      << "  InitMCRegisterInfo(" << TargetName << "RegDesc, "
      << Regs.size()+1 << ", RA, PC,\n                     " << TargetName
      << "MCRegisterClasses, " << RegisterClasses.size() << ",\n"