Specify SubRegIndex components on the index itself.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 1 Feb 2012 23:16:41 +0000 (23:16 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Wed, 1 Feb 2012 23:16:41 +0000 (23:16 +0000)
It is simpler to define a composite index directly:

  def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>;
  def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>;

Than specifying the composite indices on each register:

  CompositeIndices = [(ssub_2 dsub_1, ssub_0),
                      (ssub_3 dsub_1, ssub_1)] in ...

This also makes it clear that SubRegIndex composition is supposed to be
unique.

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

include/llvm/Target/Target.td
utils/TableGen/CodeGenRegisters.cpp
utils/TableGen/CodeGenRegisters.h

index 84e6b1bfefec9abf6579d710c527829b14993548..fa1ec5594522d3bf5818936e441c516b091cd079 100644 (file)
@@ -22,8 +22,12 @@ include "llvm/Intrinsics.td"
 class RegisterClass; // Forward def
 
 // SubRegIndex - Use instances of SubRegIndex to identify subregisters.
-class SubRegIndex {
+class SubRegIndex<list<SubRegIndex> comps = []> {
   string Namespace = "";
+
+  // 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;
 }
 
 // RegAltNameIndex - The alternate name set to use for register operands of
index 1d06f3e52876a34fa87c0c415943a0c9edaceeb5..9c61f3f7df13efe2287a1f43fe4a9e5522eb284f 100644 (file)
@@ -49,6 +49,19 @@ std::string CodeGenSubRegIndex::getQualifiedName() const {
   return N;
 }
 
+void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
+  std::vector<Record*> Comps = TheDef->getValueAsListOfDefs("ComposedOf");
+  if (Comps.empty())
+    return;
+  if (Comps.size() != 2)
+    throw TGError(TheDef->getLoc(), "ComposedOf must have exactly two entries");
+  CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]);
+  CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]);
+  CodeGenSubRegIndex *X = A->addComposite(B, this);
+  if (X)
+    throw TGError(TheDef->getLoc(), "Ambiguous ComposedOf entries");
+}
+
 void CodeGenSubRegIndex::cleanComposites() {
   // Clean out redundant mappings of the form this+X -> X.
   for (CompMap::iterator i = Composed.begin(), e = Composed.end(); i != e;) {
@@ -75,15 +88,6 @@ const std::string &CodeGenRegister::getName() const {
   return TheDef->getName();
 }
 
-namespace {
-  struct Orphan {
-    CodeGenRegister *SubReg;
-    CodeGenSubRegIndex *First, *Second;
-    Orphan(CodeGenRegister *r, CodeGenSubRegIndex *a, CodeGenSubRegIndex *b)
-      : SubReg(r), First(a), Second(b) {}
-  };
-}
-
 const CodeGenRegister::SubRegMap &
 CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
   // Only compute this map once.
@@ -92,28 +96,29 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
   SubRegsComplete = true;
 
   std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
-  std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
-  if (SubList.size() != Indices.size())
+  std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
+  if (SubList.size() != IdxList.size())
     throw TGError(TheDef->getLoc(), "Register " + getName() +
                   " SubRegIndices doesn't match SubRegs");
 
   // First insert the direct subregs and make sure they are fully indexed.
+  SmallVector<CodeGenSubRegIndex*, 8> Indices;
   for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
     CodeGenRegister *SR = RegBank.getReg(SubList[i]);
-    CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
+    CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
+    Indices.push_back(Idx);
     if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
       throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
                     " appears twice in Register " + getName());
   }
 
   // Keep track of inherited subregs and how they can be reached.
-  SmallVector<Orphan, 8> Orphans;
+  SmallPtrSet<CodeGenRegister*, 8> Orphans;
 
-  // Clone inherited subregs and place duplicate entries on Orphans.
+  // Clone inherited subregs and place duplicate entries in Orphans.
   // Here the order is important - earlier subregs take precedence.
   for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
     CodeGenRegister *SR = RegBank.getReg(SubList[i]);
-    CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
     const SubRegMap &Map = SR->getSubRegs(RegBank);
 
     // Add this as a super-register of SR now all sub-registers are in the list.
@@ -124,7 +129,7 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
     for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
          ++SI) {
       if (!SubRegs.insert(*SI).second)
-        Orphans.push_back(Orphan(SI->second, Idx, SI->first));
+        Orphans.insert(SI->second);
 
       // Noop sub-register indexes are possible, so avoid duplicates.
       if (SI->second != SR)
@@ -132,6 +137,33 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
     }
   }
 
+  // Expand any composed subreg indices.
+  // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
+  // qsub_1 subreg, add a dsub_2 subreg.  Keep growing Indices and process
+  // expanded subreg indices recursively.
+  for (unsigned i = 0; i != Indices.size(); ++i) {
+    CodeGenSubRegIndex *Idx = Indices[i];
+    const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
+    CodeGenRegister *SR = SubRegs[Idx];
+    const SubRegMap &Map = SR->getSubRegs(RegBank);
+
+    // Look at the possible compositions of Idx.
+    // They may not all be supported by SR.
+    for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
+           E = Comps.end(); I != E; ++I) {
+      SubRegMap::const_iterator SRI = Map.find(I->first);
+      if (SRI == Map.end())
+        continue; // Idx + I->first doesn't exist in SR.
+      // Add I->second as a name for the subreg SRI->second, assuming it is
+      // orphaned, and the name isn't already used for something else.
+      if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
+        continue;
+      // We found a new name for the orphaned sub-register.
+      SubRegs.insert(std::make_pair(I->second, SRI->second));
+      Indices.push_back(I->second);
+    }
+  }
+
   // Process the composites.
   ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
   for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
@@ -167,19 +199,33 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
     SubRegs[BaseIdx] = R2;
 
     // R2 is no longer an orphan.
-    for (unsigned j = 0, je = Orphans.size(); j != je; ++j)
-      if (Orphans[j].SubReg == R2)
-          Orphans[j].SubReg = 0;
+    Orphans.erase(R2);
   }
 
   // Now Orphans contains the inherited subregisters without a direct index.
   // Create inferred indexes for all missing entries.
-  for (unsigned i = 0, e = Orphans.size(); i != e; ++i) {
-    Orphan &O = Orphans[i];
-    if (!O.SubReg)
-      continue;
-    SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second)] =
-      O.SubReg;
+  // Work backwards in the Indices vector in order to compose subregs bottom-up.
+  // Consider this subreg sequence:
+  //
+  //   qsub_1 -> dsub_0 -> ssub_0
+  //
+  // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register
+  // can be reached in two different ways:
+  //
+  //   qsub_1 -> ssub_0
+  //   dsub_2 -> ssub_0
+  //
+  // We pick the latter composition because another register may have [dsub_0,
+  // dsub_1, dsub_2] subregs without neccessarily having a qsub_1 subreg.  The
+  // dsub_2 -> ssub_0 composition can be shared.
+  while (!Indices.empty() && !Orphans.empty()) {
+    CodeGenSubRegIndex *Idx = Indices.pop_back_val();
+    CodeGenRegister *SR = SubRegs[Idx];
+    const SubRegMap &Map = SR->getSubRegs(RegBank);
+    for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
+         ++SI)
+      if (Orphans.erase(SI->second))
+        SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second;
   }
   return SubRegs;
 }
@@ -590,6 +636,9 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
   NumNamedIndices = SRIs.size();
   for (unsigned i = 0, e = SRIs.size(); i != e; ++i)
     getSubRegIdx(SRIs[i]);
+  // Build composite maps from ComposedOf fields.
+  for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+    SubRegIndices[i]->updateComponents(*this);
 
   // Read in the register definitions.
   std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
index b83ad6e78502ab7946761bb8ddb0276737b91b75..5fc0f657392573a48923dc77ddfbb0fb5b712cce 100644 (file)
@@ -71,6 +71,9 @@ namespace llvm {
       return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second;
     }
 
+    // Update the composite maps of components specified in 'ComposedOf'.
+    void updateComponents(CodeGenRegBank&);
+
     // Clean out redundant composite mappings.
     void cleanComposites();