168d6d8abSJakob Stoklund Olesen //===- CodeGenRegisters.cpp - Register and RegisterClass Info -------------===//
268d6d8abSJakob Stoklund Olesen //
368d6d8abSJakob Stoklund Olesen //                     The LLVM Compiler Infrastructure
468d6d8abSJakob Stoklund Olesen //
568d6d8abSJakob Stoklund Olesen // This file is distributed under the University of Illinois Open Source
668d6d8abSJakob Stoklund Olesen // License. See LICENSE.TXT for details.
768d6d8abSJakob Stoklund Olesen //
868d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
968d6d8abSJakob Stoklund Olesen //
1068d6d8abSJakob Stoklund Olesen // This file defines structures to encapsulate information gleaned from the
1168d6d8abSJakob Stoklund Olesen // target register and register class definitions.
1268d6d8abSJakob Stoklund Olesen //
1368d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
1468d6d8abSJakob Stoklund Olesen 
1568d6d8abSJakob Stoklund Olesen #include "CodeGenRegisters.h"
1668d6d8abSJakob Stoklund Olesen #include "CodeGenTarget.h"
1784c287e3SPeter Collingbourne #include "llvm/TableGen/Error.h"
1884bd44ebSJakob Stoklund Olesen #include "llvm/ADT/SmallVector.h"
19c0fc173dSJakob Stoklund Olesen #include "llvm/ADT/STLExtras.h"
2068d6d8abSJakob Stoklund Olesen #include "llvm/ADT/StringExtras.h"
2168d6d8abSJakob Stoklund Olesen 
2268d6d8abSJakob Stoklund Olesen using namespace llvm;
2368d6d8abSJakob Stoklund Olesen 
2468d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
25f1bb1519SJakob Stoklund Olesen //                             CodeGenSubRegIndex
26f1bb1519SJakob Stoklund Olesen //===----------------------------------------------------------------------===//
27f1bb1519SJakob Stoklund Olesen 
28f1bb1519SJakob Stoklund Olesen CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum)
29f1bb1519SJakob Stoklund Olesen   : TheDef(R),
30f1bb1519SJakob Stoklund Olesen     EnumValue(Enum)
31f1bb1519SJakob Stoklund Olesen {}
32f1bb1519SJakob Stoklund Olesen 
33f1bb1519SJakob Stoklund Olesen std::string CodeGenSubRegIndex::getNamespace() const {
34f1bb1519SJakob Stoklund Olesen   if (TheDef->getValue("Namespace"))
35f1bb1519SJakob Stoklund Olesen     return TheDef->getValueAsString("Namespace");
36f1bb1519SJakob Stoklund Olesen   else
37f1bb1519SJakob Stoklund Olesen     return "";
38f1bb1519SJakob Stoklund Olesen }
39f1bb1519SJakob Stoklund Olesen 
40f1bb1519SJakob Stoklund Olesen const std::string &CodeGenSubRegIndex::getName() const {
41f1bb1519SJakob Stoklund Olesen   return TheDef->getName();
42f1bb1519SJakob Stoklund Olesen }
43f1bb1519SJakob Stoklund Olesen 
44f1bb1519SJakob Stoklund Olesen std::string CodeGenSubRegIndex::getQualifiedName() const {
45f1bb1519SJakob Stoklund Olesen   std::string N = getNamespace();
46f1bb1519SJakob Stoklund Olesen   if (!N.empty())
47f1bb1519SJakob Stoklund Olesen     N += "::";
48f1bb1519SJakob Stoklund Olesen   N += getName();
49f1bb1519SJakob Stoklund Olesen   return N;
50f1bb1519SJakob Stoklund Olesen }
51f1bb1519SJakob Stoklund Olesen 
5221231609SJakob Stoklund Olesen void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
5321231609SJakob Stoklund Olesen   std::vector<Record*> Comps = TheDef->getValueAsListOfDefs("ComposedOf");
5421231609SJakob Stoklund Olesen   if (Comps.empty())
5521231609SJakob Stoklund Olesen     return;
5621231609SJakob Stoklund Olesen   if (Comps.size() != 2)
5721231609SJakob Stoklund Olesen     throw TGError(TheDef->getLoc(), "ComposedOf must have exactly two entries");
5821231609SJakob Stoklund Olesen   CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]);
5921231609SJakob Stoklund Olesen   CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]);
6021231609SJakob Stoklund Olesen   CodeGenSubRegIndex *X = A->addComposite(B, this);
6121231609SJakob Stoklund Olesen   if (X)
6221231609SJakob Stoklund Olesen     throw TGError(TheDef->getLoc(), "Ambiguous ComposedOf entries");
6321231609SJakob Stoklund Olesen }
6421231609SJakob Stoklund Olesen 
659a44ad70SJakob Stoklund Olesen void CodeGenSubRegIndex::cleanComposites() {
669a44ad70SJakob Stoklund Olesen   // Clean out redundant mappings of the form this+X -> X.
679a44ad70SJakob Stoklund Olesen   for (CompMap::iterator i = Composed.begin(), e = Composed.end(); i != e;) {
689a44ad70SJakob Stoklund Olesen     CompMap::iterator j = i;
699a44ad70SJakob Stoklund Olesen     ++i;
709a44ad70SJakob Stoklund Olesen     if (j->first == j->second)
719a44ad70SJakob Stoklund Olesen       Composed.erase(j);
729a44ad70SJakob Stoklund Olesen   }
739a44ad70SJakob Stoklund Olesen }
749a44ad70SJakob Stoklund Olesen 
75f1bb1519SJakob Stoklund Olesen //===----------------------------------------------------------------------===//
7668d6d8abSJakob Stoklund Olesen //                              CodeGenRegister
7768d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
7868d6d8abSJakob Stoklund Olesen 
7984bd44ebSJakob Stoklund Olesen CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum)
8084bd44ebSJakob Stoklund Olesen   : TheDef(R),
8184bd44ebSJakob Stoklund Olesen     EnumValue(Enum),
8284bd44ebSJakob Stoklund Olesen     CostPerUse(R->getValueAsInt("CostPerUse")),
83f43b5995SJakob Stoklund Olesen     CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
8484bd44ebSJakob Stoklund Olesen     SubRegsComplete(false)
8584bd44ebSJakob Stoklund Olesen {}
8668d6d8abSJakob Stoklund Olesen 
8768d6d8abSJakob Stoklund Olesen const std::string &CodeGenRegister::getName() const {
8868d6d8abSJakob Stoklund Olesen   return TheDef->getName();
8968d6d8abSJakob Stoklund Olesen }
9068d6d8abSJakob Stoklund Olesen 
91*cdefdf1fSAndrew Trick // Merge two RegUnitLists maintaining the order and removing duplicates.
921a004ca0SAndrew Trick // Overwrites MergedRU in the process.
931a004ca0SAndrew Trick static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU,
941a004ca0SAndrew Trick                           const CodeGenRegister::RegUnitList &RRU)
951a004ca0SAndrew Trick {
961a004ca0SAndrew Trick   CodeGenRegister::RegUnitList LRU = MergedRU;
971a004ca0SAndrew Trick   MergedRU.clear();
981a004ca0SAndrew Trick   for (CodeGenRegister::RegUnitList::const_iterator
991a004ca0SAndrew Trick          RI = RRU.begin(), RE = RRU.end(), LI = LRU.begin(), LE = LRU.end();
1001a004ca0SAndrew Trick        RI != RE || LI != LE;) {
1011a004ca0SAndrew Trick 
1021a004ca0SAndrew Trick     CodeGenRegister::RegUnitList::const_iterator &NextI =
1031a004ca0SAndrew Trick       (RI != RE && (LI == LE || *RI < *LI)) ? RI : LI;
1041a004ca0SAndrew Trick 
1051a004ca0SAndrew Trick     if (MergedRU.empty() || *NextI != MergedRU.back())
1061a004ca0SAndrew Trick       MergedRU.push_back(*NextI);
1071a004ca0SAndrew Trick     ++NextI;
1081a004ca0SAndrew Trick   }
1091a004ca0SAndrew Trick }
1101a004ca0SAndrew Trick 
11184bd44ebSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &
11284bd44ebSJakob Stoklund Olesen CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
11384bd44ebSJakob Stoklund Olesen   // Only compute this map once.
11484bd44ebSJakob Stoklund Olesen   if (SubRegsComplete)
11584bd44ebSJakob Stoklund Olesen     return SubRegs;
11684bd44ebSJakob Stoklund Olesen   SubRegsComplete = true;
11784bd44ebSJakob Stoklund Olesen 
11884bd44ebSJakob Stoklund Olesen   std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
11921231609SJakob Stoklund Olesen   std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
12021231609SJakob Stoklund Olesen   if (SubList.size() != IdxList.size())
12184bd44ebSJakob Stoklund Olesen     throw TGError(TheDef->getLoc(), "Register " + getName() +
12284bd44ebSJakob Stoklund Olesen                   " SubRegIndices doesn't match SubRegs");
12384bd44ebSJakob Stoklund Olesen 
12484bd44ebSJakob Stoklund Olesen   // First insert the direct subregs and make sure they are fully indexed.
12521231609SJakob Stoklund Olesen   SmallVector<CodeGenSubRegIndex*, 8> Indices;
12684bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
12784bd44ebSJakob Stoklund Olesen     CodeGenRegister *SR = RegBank.getReg(SubList[i]);
12821231609SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
12921231609SJakob Stoklund Olesen     Indices.push_back(Idx);
130f1bb1519SJakob Stoklund Olesen     if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
131f1bb1519SJakob Stoklund Olesen       throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
13284bd44ebSJakob Stoklund Olesen                     " appears twice in Register " + getName());
13384bd44ebSJakob Stoklund Olesen   }
13484bd44ebSJakob Stoklund Olesen 
13584bd44ebSJakob Stoklund Olesen   // Keep track of inherited subregs and how they can be reached.
13621231609SJakob Stoklund Olesen   SmallPtrSet<CodeGenRegister*, 8> Orphans;
13784bd44ebSJakob Stoklund Olesen 
13821231609SJakob Stoklund Olesen   // Clone inherited subregs and place duplicate entries in Orphans.
13984bd44ebSJakob Stoklund Olesen   // Here the order is important - earlier subregs take precedence.
14084bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
14184bd44ebSJakob Stoklund Olesen     CodeGenRegister *SR = RegBank.getReg(SubList[i]);
14284bd44ebSJakob Stoklund Olesen     const SubRegMap &Map = SR->getSubRegs(RegBank);
143d2b4713eSJakob Stoklund Olesen 
144d2b4713eSJakob Stoklund Olesen     // Add this as a super-register of SR now all sub-registers are in the list.
145d2b4713eSJakob Stoklund Olesen     // This creates a topological ordering, the exact order depends on the
146d2b4713eSJakob Stoklund Olesen     // order getSubRegs is called on all registers.
147d2b4713eSJakob Stoklund Olesen     SR->SuperRegs.push_back(this);
148d2b4713eSJakob Stoklund Olesen 
14984bd44ebSJakob Stoklund Olesen     for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
150d2b4713eSJakob Stoklund Olesen          ++SI) {
15184bd44ebSJakob Stoklund Olesen       if (!SubRegs.insert(*SI).second)
15221231609SJakob Stoklund Olesen         Orphans.insert(SI->second);
153d2b4713eSJakob Stoklund Olesen 
154d2b4713eSJakob Stoklund Olesen       // Noop sub-register indexes are possible, so avoid duplicates.
155d2b4713eSJakob Stoklund Olesen       if (SI->second != SR)
156d2b4713eSJakob Stoklund Olesen         SI->second->SuperRegs.push_back(this);
157d2b4713eSJakob Stoklund Olesen     }
15884bd44ebSJakob Stoklund Olesen   }
15984bd44ebSJakob Stoklund Olesen 
16021231609SJakob Stoklund Olesen   // Expand any composed subreg indices.
16121231609SJakob Stoklund Olesen   // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
16221231609SJakob Stoklund Olesen   // qsub_1 subreg, add a dsub_2 subreg.  Keep growing Indices and process
16321231609SJakob Stoklund Olesen   // expanded subreg indices recursively.
16421231609SJakob Stoklund Olesen   for (unsigned i = 0; i != Indices.size(); ++i) {
16521231609SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = Indices[i];
16621231609SJakob Stoklund Olesen     const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
16721231609SJakob Stoklund Olesen     CodeGenRegister *SR = SubRegs[Idx];
16821231609SJakob Stoklund Olesen     const SubRegMap &Map = SR->getSubRegs(RegBank);
16921231609SJakob Stoklund Olesen 
17021231609SJakob Stoklund Olesen     // Look at the possible compositions of Idx.
17121231609SJakob Stoklund Olesen     // They may not all be supported by SR.
17221231609SJakob Stoklund Olesen     for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
17321231609SJakob Stoklund Olesen            E = Comps.end(); I != E; ++I) {
17421231609SJakob Stoklund Olesen       SubRegMap::const_iterator SRI = Map.find(I->first);
17521231609SJakob Stoklund Olesen       if (SRI == Map.end())
17621231609SJakob Stoklund Olesen         continue; // Idx + I->first doesn't exist in SR.
17721231609SJakob Stoklund Olesen       // Add I->second as a name for the subreg SRI->second, assuming it is
17821231609SJakob Stoklund Olesen       // orphaned, and the name isn't already used for something else.
17921231609SJakob Stoklund Olesen       if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
18021231609SJakob Stoklund Olesen         continue;
18121231609SJakob Stoklund Olesen       // We found a new name for the orphaned sub-register.
18221231609SJakob Stoklund Olesen       SubRegs.insert(std::make_pair(I->second, SRI->second));
18321231609SJakob Stoklund Olesen       Indices.push_back(I->second);
18421231609SJakob Stoklund Olesen     }
18521231609SJakob Stoklund Olesen   }
18621231609SJakob Stoklund Olesen 
18784bd44ebSJakob Stoklund Olesen   // Process the composites.
188af8ee2cdSDavid Greene   ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
18984bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
190af8ee2cdSDavid Greene     DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
19184bd44ebSJakob Stoklund Olesen     if (!Pat)
19284bd44ebSJakob Stoklund Olesen       throw TGError(TheDef->getLoc(), "Invalid dag '" +
19384bd44ebSJakob Stoklund Olesen                     Comps->getElement(i)->getAsString() +
19484bd44ebSJakob Stoklund Olesen                     "' in CompositeIndices");
195af8ee2cdSDavid Greene     DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
19684bd44ebSJakob Stoklund Olesen     if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
19784bd44ebSJakob Stoklund Olesen       throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
19884bd44ebSJakob Stoklund Olesen                     Pat->getAsString());
199f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef());
20084bd44ebSJakob Stoklund Olesen 
20184bd44ebSJakob Stoklund Olesen     // Resolve list of subreg indices into R2.
20284bd44ebSJakob Stoklund Olesen     CodeGenRegister *R2 = this;
20384bd44ebSJakob Stoklund Olesen     for (DagInit::const_arg_iterator di = Pat->arg_begin(),
20484bd44ebSJakob Stoklund Olesen          de = Pat->arg_end(); di != de; ++di) {
205af8ee2cdSDavid Greene       DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
20684bd44ebSJakob Stoklund Olesen       if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
20784bd44ebSJakob Stoklund Olesen         throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
20884bd44ebSJakob Stoklund Olesen                       Pat->getAsString());
209f1bb1519SJakob Stoklund Olesen       CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef());
21084bd44ebSJakob Stoklund Olesen       const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
211f1bb1519SJakob Stoklund Olesen       SubRegMap::const_iterator ni = R2Subs.find(Idx);
21284bd44ebSJakob Stoklund Olesen       if (ni == R2Subs.end())
21384bd44ebSJakob Stoklund Olesen         throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() +
21484bd44ebSJakob Stoklund Olesen                       " refers to bad index in " + R2->getName());
21584bd44ebSJakob Stoklund Olesen       R2 = ni->second;
21684bd44ebSJakob Stoklund Olesen     }
21784bd44ebSJakob Stoklund Olesen 
21884bd44ebSJakob Stoklund Olesen     // Insert composite index. Allow overriding inherited indices etc.
219f1bb1519SJakob Stoklund Olesen     SubRegs[BaseIdx] = R2;
22084bd44ebSJakob Stoklund Olesen 
22184bd44ebSJakob Stoklund Olesen     // R2 is no longer an orphan.
22221231609SJakob Stoklund Olesen     Orphans.erase(R2);
22384bd44ebSJakob Stoklund Olesen   }
22484bd44ebSJakob Stoklund Olesen 
22584bd44ebSJakob Stoklund Olesen   // Now Orphans contains the inherited subregisters without a direct index.
22684bd44ebSJakob Stoklund Olesen   // Create inferred indexes for all missing entries.
22721231609SJakob Stoklund Olesen   // Work backwards in the Indices vector in order to compose subregs bottom-up.
22821231609SJakob Stoklund Olesen   // Consider this subreg sequence:
22921231609SJakob Stoklund Olesen   //
23021231609SJakob Stoklund Olesen   //   qsub_1 -> dsub_0 -> ssub_0
23121231609SJakob Stoklund Olesen   //
23221231609SJakob Stoklund Olesen   // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register
23321231609SJakob Stoklund Olesen   // can be reached in two different ways:
23421231609SJakob Stoklund Olesen   //
23521231609SJakob Stoklund Olesen   //   qsub_1 -> ssub_0
23621231609SJakob Stoklund Olesen   //   dsub_2 -> ssub_0
23721231609SJakob Stoklund Olesen   //
23821231609SJakob Stoklund Olesen   // We pick the latter composition because another register may have [dsub_0,
23921231609SJakob Stoklund Olesen   // dsub_1, dsub_2] subregs without neccessarily having a qsub_1 subreg.  The
24021231609SJakob Stoklund Olesen   // dsub_2 -> ssub_0 composition can be shared.
24121231609SJakob Stoklund Olesen   while (!Indices.empty() && !Orphans.empty()) {
24221231609SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = Indices.pop_back_val();
24321231609SJakob Stoklund Olesen     CodeGenRegister *SR = SubRegs[Idx];
24421231609SJakob Stoklund Olesen     const SubRegMap &Map = SR->getSubRegs(RegBank);
24521231609SJakob Stoklund Olesen     for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
24621231609SJakob Stoklund Olesen          ++SI)
24721231609SJakob Stoklund Olesen       if (Orphans.erase(SI->second))
24821231609SJakob Stoklund Olesen         SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second;
24984bd44ebSJakob Stoklund Olesen   }
2501a004ca0SAndrew Trick 
2511a004ca0SAndrew Trick   // Initialize RegUnitList. A register with no subregisters creates its own
2521a004ca0SAndrew Trick   // unit. Otherwise, it inherits all its subregister's units. Because
2531a004ca0SAndrew Trick   // getSubRegs is called recursively, this processes the register hierarchy in
2541a004ca0SAndrew Trick   // postorder.
2551a004ca0SAndrew Trick   //
2561a004ca0SAndrew Trick   // TODO: We currently assume all register units correspond to a named "leaf"
2571a004ca0SAndrew Trick   // register. We should also unify register units for ad-hoc register
2581a004ca0SAndrew Trick   // aliases. This can be done by iteratively merging units for aliasing
2591a004ca0SAndrew Trick   // registers using a worklist.
2601a004ca0SAndrew Trick   assert(RegUnits.empty() && "Should only initialize RegUnits once");
2611a004ca0SAndrew Trick   if (SubRegs.empty()) {
2621a004ca0SAndrew Trick     RegUnits.push_back(RegBank.newRegUnit());
2631a004ca0SAndrew Trick   }
2641a004ca0SAndrew Trick   else {
2651a004ca0SAndrew Trick     for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
2661a004ca0SAndrew Trick          I != E; ++I) {
2671a004ca0SAndrew Trick       // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM.
2681a004ca0SAndrew Trick       CodeGenRegister *SR = I->second;
2691a004ca0SAndrew Trick       if (SR == this) {
2701a004ca0SAndrew Trick         if (RegUnits.empty())
2711a004ca0SAndrew Trick           RegUnits.push_back(RegBank.newRegUnit());
2721a004ca0SAndrew Trick         continue;
2731a004ca0SAndrew Trick       }
2741a004ca0SAndrew Trick       // Merge the subregister's units into this register's RegUnits.
2751a004ca0SAndrew Trick       mergeRegUnits(RegUnits, SR->RegUnits);
2761a004ca0SAndrew Trick     }
2771a004ca0SAndrew Trick   }
27884bd44ebSJakob Stoklund Olesen   return SubRegs;
27984bd44ebSJakob Stoklund Olesen }
28084bd44ebSJakob Stoklund Olesen 
281d2b4713eSJakob Stoklund Olesen void
28200296815SJakob Stoklund Olesen CodeGenRegister::addSubRegsPreOrder(SetVector<const CodeGenRegister*> &OSet,
283f1bb1519SJakob Stoklund Olesen                                     CodeGenRegBank &RegBank) const {
284d2b4713eSJakob Stoklund Olesen   assert(SubRegsComplete && "Must precompute sub-registers");
285d2b4713eSJakob Stoklund Olesen   std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
286d2b4713eSJakob Stoklund Olesen   for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
287f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
288f1bb1519SJakob Stoklund Olesen     CodeGenRegister *SR = SubRegs.find(Idx)->second;
289d2b4713eSJakob Stoklund Olesen     if (OSet.insert(SR))
290f1bb1519SJakob Stoklund Olesen       SR->addSubRegsPreOrder(OSet, RegBank);
291d2b4713eSJakob Stoklund Olesen   }
292d2b4713eSJakob Stoklund Olesen }
293d2b4713eSJakob Stoklund Olesen 
29468d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
2953bd1b65eSJakob Stoklund Olesen //                               RegisterTuples
2963bd1b65eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
2973bd1b65eSJakob Stoklund Olesen 
2983bd1b65eSJakob Stoklund Olesen // A RegisterTuples def is used to generate pseudo-registers from lists of
2993bd1b65eSJakob Stoklund Olesen // sub-registers. We provide a SetTheory expander class that returns the new
3003bd1b65eSJakob Stoklund Olesen // registers.
3013bd1b65eSJakob Stoklund Olesen namespace {
3023bd1b65eSJakob Stoklund Olesen struct TupleExpander : SetTheory::Expander {
3033bd1b65eSJakob Stoklund Olesen   void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) {
3043bd1b65eSJakob Stoklund Olesen     std::vector<Record*> Indices = Def->getValueAsListOfDefs("SubRegIndices");
3053bd1b65eSJakob Stoklund Olesen     unsigned Dim = Indices.size();
306af8ee2cdSDavid Greene     ListInit *SubRegs = Def->getValueAsListInit("SubRegs");
3073bd1b65eSJakob Stoklund Olesen     if (Dim != SubRegs->getSize())
3083bd1b65eSJakob Stoklund Olesen       throw TGError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch");
3093bd1b65eSJakob Stoklund Olesen     if (Dim < 2)
3103bd1b65eSJakob Stoklund Olesen       throw TGError(Def->getLoc(), "Tuples must have at least 2 sub-registers");
3113bd1b65eSJakob Stoklund Olesen 
3123bd1b65eSJakob Stoklund Olesen     // Evaluate the sub-register lists to be zipped.
3133bd1b65eSJakob Stoklund Olesen     unsigned Length = ~0u;
3143bd1b65eSJakob Stoklund Olesen     SmallVector<SetTheory::RecSet, 4> Lists(Dim);
3153bd1b65eSJakob Stoklund Olesen     for (unsigned i = 0; i != Dim; ++i) {
3163bd1b65eSJakob Stoklund Olesen       ST.evaluate(SubRegs->getElement(i), Lists[i]);
3173bd1b65eSJakob Stoklund Olesen       Length = std::min(Length, unsigned(Lists[i].size()));
3183bd1b65eSJakob Stoklund Olesen     }
3193bd1b65eSJakob Stoklund Olesen 
3203bd1b65eSJakob Stoklund Olesen     if (Length == 0)
3213bd1b65eSJakob Stoklund Olesen       return;
3223bd1b65eSJakob Stoklund Olesen 
3233bd1b65eSJakob Stoklund Olesen     // Precompute some types.
3243bd1b65eSJakob Stoklund Olesen     Record *RegisterCl = Def->getRecords().getClass("Register");
325abcfdceaSJakob Stoklund Olesen     RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl);
326af8ee2cdSDavid Greene     StringInit *BlankName = StringInit::get("");
3273bd1b65eSJakob Stoklund Olesen 
3283bd1b65eSJakob Stoklund Olesen     // Zip them up.
3293bd1b65eSJakob Stoklund Olesen     for (unsigned n = 0; n != Length; ++n) {
3303bd1b65eSJakob Stoklund Olesen       std::string Name;
3313bd1b65eSJakob Stoklund Olesen       Record *Proto = Lists[0][n];
332af8ee2cdSDavid Greene       std::vector<Init*> Tuple;
3333bd1b65eSJakob Stoklund Olesen       unsigned CostPerUse = 0;
3343bd1b65eSJakob Stoklund Olesen       for (unsigned i = 0; i != Dim; ++i) {
3353bd1b65eSJakob Stoklund Olesen         Record *Reg = Lists[i][n];
3363bd1b65eSJakob Stoklund Olesen         if (i) Name += '_';
3373bd1b65eSJakob Stoklund Olesen         Name += Reg->getName();
338abcfdceaSJakob Stoklund Olesen         Tuple.push_back(DefInit::get(Reg));
3393bd1b65eSJakob Stoklund Olesen         CostPerUse = std::max(CostPerUse,
3403bd1b65eSJakob Stoklund Olesen                               unsigned(Reg->getValueAsInt("CostPerUse")));
3413bd1b65eSJakob Stoklund Olesen       }
3423bd1b65eSJakob Stoklund Olesen 
3433bd1b65eSJakob Stoklund Olesen       // Create a new Record representing the synthesized register. This record
3443bd1b65eSJakob Stoklund Olesen       // is only for consumption by CodeGenRegister, it is not added to the
3453bd1b65eSJakob Stoklund Olesen       // RecordKeeper.
3463bd1b65eSJakob Stoklund Olesen       Record *NewReg = new Record(Name, Def->getLoc(), Def->getRecords());
3473bd1b65eSJakob Stoklund Olesen       Elts.insert(NewReg);
3483bd1b65eSJakob Stoklund Olesen 
3493bd1b65eSJakob Stoklund Olesen       // Copy Proto super-classes.
3503bd1b65eSJakob Stoklund Olesen       for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i)
3513bd1b65eSJakob Stoklund Olesen         NewReg->addSuperClass(Proto->getSuperClasses()[i]);
3523bd1b65eSJakob Stoklund Olesen 
3533bd1b65eSJakob Stoklund Olesen       // Copy Proto fields.
3543bd1b65eSJakob Stoklund Olesen       for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
3553bd1b65eSJakob Stoklund Olesen         RecordVal RV = Proto->getValues()[i];
3563bd1b65eSJakob Stoklund Olesen 
357f43b5995SJakob Stoklund Olesen         // Skip existing fields, like NAME.
358f43b5995SJakob Stoklund Olesen         if (NewReg->getValue(RV.getNameInit()))
359071c69cdSJakob Stoklund Olesen           continue;
360071c69cdSJakob Stoklund Olesen 
361f43b5995SJakob Stoklund Olesen         StringRef Field = RV.getName();
362f43b5995SJakob Stoklund Olesen 
3633bd1b65eSJakob Stoklund Olesen         // Replace the sub-register list with Tuple.
364f43b5995SJakob Stoklund Olesen         if (Field == "SubRegs")
365e32ebf22SDavid Greene           RV.setValue(ListInit::get(Tuple, RegisterRecTy));
3663bd1b65eSJakob Stoklund Olesen 
3673bd1b65eSJakob Stoklund Olesen         // Provide a blank AsmName. MC hacks are required anyway.
368f43b5995SJakob Stoklund Olesen         if (Field == "AsmName")
3693bd1b65eSJakob Stoklund Olesen           RV.setValue(BlankName);
3703bd1b65eSJakob Stoklund Olesen 
3713bd1b65eSJakob Stoklund Olesen         // CostPerUse is aggregated from all Tuple members.
372f43b5995SJakob Stoklund Olesen         if (Field == "CostPerUse")
373e32ebf22SDavid Greene           RV.setValue(IntInit::get(CostPerUse));
3743bd1b65eSJakob Stoklund Olesen 
375f43b5995SJakob Stoklund Olesen         // Composite registers are always covered by sub-registers.
376f43b5995SJakob Stoklund Olesen         if (Field == "CoveredBySubRegs")
377f43b5995SJakob Stoklund Olesen           RV.setValue(BitInit::get(true));
378f43b5995SJakob Stoklund Olesen 
3793bd1b65eSJakob Stoklund Olesen         // Copy fields from the RegisterTuples def.
380f43b5995SJakob Stoklund Olesen         if (Field == "SubRegIndices" ||
381f43b5995SJakob Stoklund Olesen             Field == "CompositeIndices") {
382f43b5995SJakob Stoklund Olesen           NewReg->addValue(*Def->getValue(Field));
3833bd1b65eSJakob Stoklund Olesen           continue;
3843bd1b65eSJakob Stoklund Olesen         }
3853bd1b65eSJakob Stoklund Olesen 
3863bd1b65eSJakob Stoklund Olesen         // Some fields get their default uninitialized value.
387f43b5995SJakob Stoklund Olesen         if (Field == "DwarfNumbers" ||
388f43b5995SJakob Stoklund Olesen             Field == "DwarfAlias" ||
389f43b5995SJakob Stoklund Olesen             Field == "Aliases") {
390f43b5995SJakob Stoklund Olesen           if (const RecordVal *DefRV = RegisterCl->getValue(Field))
391d9149a45SJakob Stoklund Olesen             NewReg->addValue(*DefRV);
3923bd1b65eSJakob Stoklund Olesen           continue;
3933bd1b65eSJakob Stoklund Olesen         }
3943bd1b65eSJakob Stoklund Olesen 
3953bd1b65eSJakob Stoklund Olesen         // Everything else is copied from Proto.
3963bd1b65eSJakob Stoklund Olesen         NewReg->addValue(RV);
3973bd1b65eSJakob Stoklund Olesen       }
3983bd1b65eSJakob Stoklund Olesen     }
3993bd1b65eSJakob Stoklund Olesen   }
4003bd1b65eSJakob Stoklund Olesen };
4013bd1b65eSJakob Stoklund Olesen }
4023bd1b65eSJakob Stoklund Olesen 
4033bd1b65eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
40468d6d8abSJakob Stoklund Olesen //                            CodeGenRegisterClass
40568d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
40668d6d8abSJakob Stoklund Olesen 
407d7bc5c26SJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
408bd92dc60SJakob Stoklund Olesen   : TheDef(R), Name(R->getName()), EnumValue(-1) {
40968d6d8abSJakob Stoklund Olesen   // Rename anonymous register classes.
41068d6d8abSJakob Stoklund Olesen   if (R->getName().size() > 9 && R->getName()[9] == '.') {
41168d6d8abSJakob Stoklund Olesen     static unsigned AnonCounter = 0;
41268d6d8abSJakob Stoklund Olesen     R->setName("AnonRegClass_"+utostr(AnonCounter++));
41368d6d8abSJakob Stoklund Olesen   }
41468d6d8abSJakob Stoklund Olesen 
41568d6d8abSJakob Stoklund Olesen   std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
41668d6d8abSJakob Stoklund Olesen   for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
41768d6d8abSJakob Stoklund Olesen     Record *Type = TypeList[i];
41868d6d8abSJakob Stoklund Olesen     if (!Type->isSubClassOf("ValueType"))
41968d6d8abSJakob Stoklund Olesen       throw "RegTypes list member '" + Type->getName() +
42068d6d8abSJakob Stoklund Olesen         "' does not derive from the ValueType class!";
42168d6d8abSJakob Stoklund Olesen     VTs.push_back(getValueType(Type));
42268d6d8abSJakob Stoklund Olesen   }
42368d6d8abSJakob Stoklund Olesen   assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");
42468d6d8abSJakob Stoklund Olesen 
425331534e5SJakob Stoklund Olesen   // Allocation order 0 is the full set. AltOrders provides others.
426331534e5SJakob Stoklund Olesen   const SetTheory::RecVec *Elements = RegBank.getSets().expand(R);
427331534e5SJakob Stoklund Olesen   ListInit *AltOrders = R->getValueAsListInit("AltOrders");
428331534e5SJakob Stoklund Olesen   Orders.resize(1 + AltOrders->size());
429331534e5SJakob Stoklund Olesen 
43035cea3daSJakob Stoklund Olesen   // Default allocation order always contains all registers.
431331534e5SJakob Stoklund Olesen   for (unsigned i = 0, e = Elements->size(); i != e; ++i) {
432331534e5SJakob Stoklund Olesen     Orders[0].push_back((*Elements)[i]);
4335ee87726SJakob Stoklund Olesen     Members.insert(RegBank.getReg((*Elements)[i]));
434331534e5SJakob Stoklund Olesen   }
43568d6d8abSJakob Stoklund Olesen 
43635cea3daSJakob Stoklund Olesen   // Alternative allocation orders may be subsets.
43735cea3daSJakob Stoklund Olesen   SetTheory::RecSet Order;
438331534e5SJakob Stoklund Olesen   for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) {
439331534e5SJakob Stoklund Olesen     RegBank.getSets().evaluate(AltOrders->getElement(i), Order);
440331534e5SJakob Stoklund Olesen     Orders[1 + i].append(Order.begin(), Order.end());
44135cea3daSJakob Stoklund Olesen     // Verify that all altorder members are regclass members.
44235cea3daSJakob Stoklund Olesen     while (!Order.empty()) {
44335cea3daSJakob Stoklund Olesen       CodeGenRegister *Reg = RegBank.getReg(Order.back());
44435cea3daSJakob Stoklund Olesen       Order.pop_back();
44535cea3daSJakob Stoklund Olesen       if (!contains(Reg))
44635cea3daSJakob Stoklund Olesen         throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() +
44735cea3daSJakob Stoklund Olesen                       " is not a class member");
44835cea3daSJakob Stoklund Olesen     }
44935cea3daSJakob Stoklund Olesen   }
45035cea3daSJakob Stoklund Olesen 
45168d6d8abSJakob Stoklund Olesen   // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
452af8ee2cdSDavid Greene   ListInit *SRC = R->getValueAsListInit("SubRegClasses");
45368d6d8abSJakob Stoklund Olesen   for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
454af8ee2cdSDavid Greene     DagInit *DAG = dynamic_cast<DagInit*>(*i);
45568d6d8abSJakob Stoklund Olesen     if (!DAG) throw "SubRegClasses must contain DAGs";
456af8ee2cdSDavid Greene     DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
45768d6d8abSJakob Stoklund Olesen     Record *RCRec;
45868d6d8abSJakob Stoklund Olesen     if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass"))
45968d6d8abSJakob Stoklund Olesen       throw "Operator '" + DAG->getOperator()->getAsString() +
46068d6d8abSJakob Stoklund Olesen         "' in SubRegClasses is not a RegisterClass";
46168d6d8abSJakob Stoklund Olesen     // Iterate over args, all SubRegIndex instances.
46268d6d8abSJakob Stoklund Olesen     for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end();
46368d6d8abSJakob Stoklund Olesen          ai != ae; ++ai) {
464af8ee2cdSDavid Greene       DefInit *Idx = dynamic_cast<DefInit*>(*ai);
46568d6d8abSJakob Stoklund Olesen       Record *IdxRec;
46668d6d8abSJakob Stoklund Olesen       if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex"))
46768d6d8abSJakob Stoklund Olesen         throw "Argument '" + (*ai)->getAsString() +
46868d6d8abSJakob Stoklund Olesen           "' in SubRegClasses is not a SubRegIndex";
46968d6d8abSJakob Stoklund Olesen       if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second)
47068d6d8abSJakob Stoklund Olesen         throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice";
47168d6d8abSJakob Stoklund Olesen     }
47268d6d8abSJakob Stoklund Olesen   }
47368d6d8abSJakob Stoklund Olesen 
47468d6d8abSJakob Stoklund Olesen   // Allow targets to override the size in bits of the RegisterClass.
47568d6d8abSJakob Stoklund Olesen   unsigned Size = R->getValueAsInt("Size");
47668d6d8abSJakob Stoklund Olesen 
47768d6d8abSJakob Stoklund Olesen   Namespace = R->getValueAsString("Namespace");
47868d6d8abSJakob Stoklund Olesen   SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
47968d6d8abSJakob Stoklund Olesen   SpillAlignment = R->getValueAsInt("Alignment");
48068d6d8abSJakob Stoklund Olesen   CopyCost = R->getValueAsInt("CopyCost");
48168d6d8abSJakob Stoklund Olesen   Allocatable = R->getValueAsBit("isAllocatable");
482dd8fbf57SJakob Stoklund Olesen   AltOrderSelect = R->getValueAsString("AltOrderSelect");
48368d6d8abSJakob Stoklund Olesen }
48468d6d8abSJakob Stoklund Olesen 
48503efe84dSJakob Stoklund Olesen // Create an inferred register class that was missing from the .td files.
48603efe84dSJakob Stoklund Olesen // Most properties will be inherited from the closest super-class after the
48703efe84dSJakob Stoklund Olesen // class structure has been computed.
48803efe84dSJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(StringRef Name, Key Props)
48903efe84dSJakob Stoklund Olesen   : Members(*Props.Members),
49003efe84dSJakob Stoklund Olesen     TheDef(0),
49103efe84dSJakob Stoklund Olesen     Name(Name),
49203efe84dSJakob Stoklund Olesen     EnumValue(-1),
49303efe84dSJakob Stoklund Olesen     SpillSize(Props.SpillSize),
49403efe84dSJakob Stoklund Olesen     SpillAlignment(Props.SpillAlignment),
49503efe84dSJakob Stoklund Olesen     CopyCost(0),
49603efe84dSJakob Stoklund Olesen     Allocatable(true) {
49703efe84dSJakob Stoklund Olesen }
49803efe84dSJakob Stoklund Olesen 
49903efe84dSJakob Stoklund Olesen // Compute inherited propertied for a synthesized register class.
50003efe84dSJakob Stoklund Olesen void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
50103efe84dSJakob Stoklund Olesen   assert(!getDef() && "Only synthesized classes can inherit properties");
50203efe84dSJakob Stoklund Olesen   assert(!SuperClasses.empty() && "Synthesized class without super class");
50303efe84dSJakob Stoklund Olesen 
50403efe84dSJakob Stoklund Olesen   // The last super-class is the smallest one.
50503efe84dSJakob Stoklund Olesen   CodeGenRegisterClass &Super = *SuperClasses.back();
50603efe84dSJakob Stoklund Olesen 
50703efe84dSJakob Stoklund Olesen   // Most properties are copied directly.
50803efe84dSJakob Stoklund Olesen   // Exceptions are members, size, and alignment
50903efe84dSJakob Stoklund Olesen   Namespace = Super.Namespace;
51003efe84dSJakob Stoklund Olesen   VTs = Super.VTs;
51103efe84dSJakob Stoklund Olesen   CopyCost = Super.CopyCost;
51203efe84dSJakob Stoklund Olesen   Allocatable = Super.Allocatable;
51303efe84dSJakob Stoklund Olesen   AltOrderSelect = Super.AltOrderSelect;
51403efe84dSJakob Stoklund Olesen 
51503efe84dSJakob Stoklund Olesen   // Copy all allocation orders, filter out foreign registers from the larger
51603efe84dSJakob Stoklund Olesen   // super-class.
51703efe84dSJakob Stoklund Olesen   Orders.resize(Super.Orders.size());
51803efe84dSJakob Stoklund Olesen   for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i)
51903efe84dSJakob Stoklund Olesen     for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j)
52003efe84dSJakob Stoklund Olesen       if (contains(RegBank.getReg(Super.Orders[i][j])))
52103efe84dSJakob Stoklund Olesen         Orders[i].push_back(Super.Orders[i][j]);
52203efe84dSJakob Stoklund Olesen }
52303efe84dSJakob Stoklund Olesen 
524d7bc5c26SJakob Stoklund Olesen bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
525d7bc5c26SJakob Stoklund Olesen   return Members.count(Reg);
526d7bc5c26SJakob Stoklund Olesen }
527d7bc5c26SJakob Stoklund Olesen 
52803efe84dSJakob Stoklund Olesen namespace llvm {
52903efe84dSJakob Stoklund Olesen   raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) {
53003efe84dSJakob Stoklund Olesen     OS << "{ S=" << K.SpillSize << ", A=" << K.SpillAlignment;
53103efe84dSJakob Stoklund Olesen     for (CodeGenRegister::Set::const_iterator I = K.Members->begin(),
53203efe84dSJakob Stoklund Olesen          E = K.Members->end(); I != E; ++I)
53303efe84dSJakob Stoklund Olesen       OS << ", " << (*I)->getName();
53403efe84dSJakob Stoklund Olesen     return OS << " }";
53503efe84dSJakob Stoklund Olesen   }
53603efe84dSJakob Stoklund Olesen }
53703efe84dSJakob Stoklund Olesen 
53803efe84dSJakob Stoklund Olesen // This is a simple lexicographical order that can be used to search for sets.
53903efe84dSJakob Stoklund Olesen // It is not the same as the topological order provided by TopoOrderRC.
54003efe84dSJakob Stoklund Olesen bool CodeGenRegisterClass::Key::
54103efe84dSJakob Stoklund Olesen operator<(const CodeGenRegisterClass::Key &B) const {
54203efe84dSJakob Stoklund Olesen   assert(Members && B.Members);
54303efe84dSJakob Stoklund Olesen   if (*Members != *B.Members)
54403efe84dSJakob Stoklund Olesen     return *Members < *B.Members;
54503efe84dSJakob Stoklund Olesen   if (SpillSize != B.SpillSize)
54603efe84dSJakob Stoklund Olesen     return SpillSize < B.SpillSize;
54703efe84dSJakob Stoklund Olesen   return SpillAlignment < B.SpillAlignment;
54803efe84dSJakob Stoklund Olesen }
54903efe84dSJakob Stoklund Olesen 
550d7bc5c26SJakob Stoklund Olesen // Returns true if RC is a strict subclass.
551d7bc5c26SJakob Stoklund Olesen // RC is a sub-class of this class if it is a valid replacement for any
552d7bc5c26SJakob Stoklund Olesen // instruction operand where a register of this classis required. It must
553d7bc5c26SJakob Stoklund Olesen // satisfy these conditions:
554d7bc5c26SJakob Stoklund Olesen //
555d7bc5c26SJakob Stoklund Olesen // 1. All RC registers are also in this.
556d7bc5c26SJakob Stoklund Olesen // 2. The RC spill size must not be smaller than our spill size.
557d7bc5c26SJakob Stoklund Olesen // 3. RC spill alignment must be compatible with ours.
558d7bc5c26SJakob Stoklund Olesen //
5596417395dSJakob Stoklund Olesen static bool testSubClass(const CodeGenRegisterClass *A,
5606417395dSJakob Stoklund Olesen                          const CodeGenRegisterClass *B) {
5616417395dSJakob Stoklund Olesen   return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 &&
5626417395dSJakob Stoklund Olesen     A->SpillSize <= B->SpillSize &&
5636417395dSJakob Stoklund Olesen     std::includes(A->getMembers().begin(), A->getMembers().end(),
5646417395dSJakob Stoklund Olesen                   B->getMembers().begin(), B->getMembers().end(),
565afef4222SJakob Stoklund Olesen                   CodeGenRegister::Less());
566d7bc5c26SJakob Stoklund Olesen }
567d7bc5c26SJakob Stoklund Olesen 
568c0fc173dSJakob Stoklund Olesen /// Sorting predicate for register classes.  This provides a topological
569c0fc173dSJakob Stoklund Olesen /// ordering that arranges all register classes before their sub-classes.
570c0fc173dSJakob Stoklund Olesen ///
571c0fc173dSJakob Stoklund Olesen /// Register classes with the same registers, spill size, and alignment form a
572c0fc173dSJakob Stoklund Olesen /// clique.  They will be ordered alphabetically.
573c0fc173dSJakob Stoklund Olesen ///
574c0fc173dSJakob Stoklund Olesen static int TopoOrderRC(const void *PA, const void *PB) {
575c0fc173dSJakob Stoklund Olesen   const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA;
576c0fc173dSJakob Stoklund Olesen   const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB;
577c0fc173dSJakob Stoklund Olesen   if (A == B)
578c0fc173dSJakob Stoklund Olesen     return 0;
579c0fc173dSJakob Stoklund Olesen 
58003efe84dSJakob Stoklund Olesen   // Order by descending set size.  Note that the classes' allocation order may
58103efe84dSJakob Stoklund Olesen   // not have been computed yet.  The Members set is always vaild.
58203efe84dSJakob Stoklund Olesen   if (A->getMembers().size() > B->getMembers().size())
583c0fc173dSJakob Stoklund Olesen     return -1;
58403efe84dSJakob Stoklund Olesen   if (A->getMembers().size() < B->getMembers().size())
585c0fc173dSJakob Stoklund Olesen     return 1;
586c0fc173dSJakob Stoklund Olesen 
587c0fc173dSJakob Stoklund Olesen   // Order by ascending spill size.
588c0fc173dSJakob Stoklund Olesen   if (A->SpillSize < B->SpillSize)
589c0fc173dSJakob Stoklund Olesen     return -1;
590c0fc173dSJakob Stoklund Olesen   if (A->SpillSize > B->SpillSize)
591c0fc173dSJakob Stoklund Olesen     return 1;
592c0fc173dSJakob Stoklund Olesen 
593c0fc173dSJakob Stoklund Olesen   // Order by ascending spill alignment.
594c0fc173dSJakob Stoklund Olesen   if (A->SpillAlignment < B->SpillAlignment)
595c0fc173dSJakob Stoklund Olesen     return -1;
596c0fc173dSJakob Stoklund Olesen   if (A->SpillAlignment > B->SpillAlignment)
597c0fc173dSJakob Stoklund Olesen     return 1;
598c0fc173dSJakob Stoklund Olesen 
599c0fc173dSJakob Stoklund Olesen   // Finally order by name as a tie breaker.
600fff0dfd8SJakob Stoklund Olesen   return StringRef(A->getName()).compare(B->getName());
601c0fc173dSJakob Stoklund Olesen }
602c0fc173dSJakob Stoklund Olesen 
603bd92dc60SJakob Stoklund Olesen std::string CodeGenRegisterClass::getQualifiedName() const {
604bd92dc60SJakob Stoklund Olesen   if (Namespace.empty())
605bd92dc60SJakob Stoklund Olesen     return getName();
606bd92dc60SJakob Stoklund Olesen   else
607bd92dc60SJakob Stoklund Olesen     return Namespace + "::" + getName();
60868d6d8abSJakob Stoklund Olesen }
60968d6d8abSJakob Stoklund Olesen 
6102c024b2dSJakob Stoklund Olesen // Compute sub-classes of all register classes.
6112c024b2dSJakob Stoklund Olesen // Assume the classes are ordered topologically.
61203efe84dSJakob Stoklund Olesen void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
61303efe84dSJakob Stoklund Olesen   ArrayRef<CodeGenRegisterClass*> RegClasses = RegBank.getRegClasses();
61403efe84dSJakob Stoklund Olesen 
6152c024b2dSJakob Stoklund Olesen   // Visit backwards so sub-classes are seen first.
6162c024b2dSJakob Stoklund Olesen   for (unsigned rci = RegClasses.size(); rci; --rci) {
6172c024b2dSJakob Stoklund Olesen     CodeGenRegisterClass &RC = *RegClasses[rci - 1];
6182c024b2dSJakob Stoklund Olesen     RC.SubClasses.resize(RegClasses.size());
6192c024b2dSJakob Stoklund Olesen     RC.SubClasses.set(RC.EnumValue);
6202c024b2dSJakob Stoklund Olesen 
6212c024b2dSJakob Stoklund Olesen     // Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
6222c024b2dSJakob Stoklund Olesen     for (unsigned s = rci; s != RegClasses.size(); ++s) {
6232c024b2dSJakob Stoklund Olesen       if (RC.SubClasses.test(s))
6242c024b2dSJakob Stoklund Olesen         continue;
6252c024b2dSJakob Stoklund Olesen       CodeGenRegisterClass *SubRC = RegClasses[s];
6266417395dSJakob Stoklund Olesen       if (!testSubClass(&RC, SubRC))
6272c024b2dSJakob Stoklund Olesen         continue;
6282c024b2dSJakob Stoklund Olesen       // SubRC is a sub-class. Grap all its sub-classes so we won't have to
6292c024b2dSJakob Stoklund Olesen       // check them again.
6302c024b2dSJakob Stoklund Olesen       RC.SubClasses |= SubRC->SubClasses;
6312c024b2dSJakob Stoklund Olesen     }
6322c024b2dSJakob Stoklund Olesen 
6332c024b2dSJakob Stoklund Olesen     // Sweep up missed clique members.  They will be immediately preceeding RC.
6346417395dSJakob Stoklund Olesen     for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s)
6352c024b2dSJakob Stoklund Olesen       RC.SubClasses.set(s - 1);
6362c024b2dSJakob Stoklund Olesen   }
637b15fad9dSJakob Stoklund Olesen 
638b15fad9dSJakob Stoklund Olesen   // Compute the SuperClasses lists from the SubClasses vectors.
639b15fad9dSJakob Stoklund Olesen   for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
640b15fad9dSJakob Stoklund Olesen     const BitVector &SC = RegClasses[rci]->getSubClasses();
641b15fad9dSJakob Stoklund Olesen     for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) {
642b15fad9dSJakob Stoklund Olesen       if (unsigned(s) == rci)
643b15fad9dSJakob Stoklund Olesen         continue;
644b15fad9dSJakob Stoklund Olesen       RegClasses[s]->SuperClasses.push_back(RegClasses[rci]);
645b15fad9dSJakob Stoklund Olesen     }
646b15fad9dSJakob Stoklund Olesen   }
64703efe84dSJakob Stoklund Olesen 
64803efe84dSJakob Stoklund Olesen   // With the class hierarchy in place, let synthesized register classes inherit
64903efe84dSJakob Stoklund Olesen   // properties from their closest super-class. The iteration order here can
65003efe84dSJakob Stoklund Olesen   // propagate properties down multiple levels.
65103efe84dSJakob Stoklund Olesen   for (unsigned rci = 0; rci != RegClasses.size(); ++rci)
65203efe84dSJakob Stoklund Olesen     if (!RegClasses[rci]->getDef())
65303efe84dSJakob Stoklund Olesen       RegClasses[rci]->inheritProperties(RegBank);
6542c024b2dSJakob Stoklund Olesen }
6552c024b2dSJakob Stoklund Olesen 
656c7b437aeSJakob Stoklund Olesen void
657f1bb1519SJakob Stoklund Olesen CodeGenRegisterClass::getSuperRegClasses(CodeGenSubRegIndex *SubIdx,
658f1bb1519SJakob Stoklund Olesen                                          BitVector &Out) const {
659f1bb1519SJakob Stoklund Olesen   DenseMap<CodeGenSubRegIndex*,
660f1bb1519SJakob Stoklund Olesen            SmallPtrSet<CodeGenRegisterClass*, 8> >::const_iterator
661c7b437aeSJakob Stoklund Olesen     FindI = SuperRegClasses.find(SubIdx);
662c7b437aeSJakob Stoklund Olesen   if (FindI == SuperRegClasses.end())
663c7b437aeSJakob Stoklund Olesen     return;
664c7b437aeSJakob Stoklund Olesen   for (SmallPtrSet<CodeGenRegisterClass*, 8>::const_iterator I =
665c7b437aeSJakob Stoklund Olesen        FindI->second.begin(), E = FindI->second.end(); I != E; ++I)
666c7b437aeSJakob Stoklund Olesen     Out.set((*I)->EnumValue);
667c7b437aeSJakob Stoklund Olesen }
668c7b437aeSJakob Stoklund Olesen 
669c7b437aeSJakob Stoklund Olesen 
67076a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
67176a5a71eSJakob Stoklund Olesen //                               CodeGenRegBank
67276a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
67376a5a71eSJakob Stoklund Olesen 
67476a5a71eSJakob Stoklund Olesen CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
6753bd1b65eSJakob Stoklund Olesen   // Configure register Sets to understand register classes and tuples.
6765ee87726SJakob Stoklund Olesen   Sets.addFieldExpander("RegisterClass", "MemberList");
677c3abb0f6SJakob Stoklund Olesen   Sets.addFieldExpander("CalleeSavedRegs", "SaveList");
6783bd1b65eSJakob Stoklund Olesen   Sets.addExpander("RegisterTuples", new TupleExpander());
6795ee87726SJakob Stoklund Olesen 
68084bd44ebSJakob Stoklund Olesen   // Read in the user-defined (named) sub-register indices.
68184bd44ebSJakob Stoklund Olesen   // More indices will be synthesized later.
682f1bb1519SJakob Stoklund Olesen   std::vector<Record*> SRIs = Records.getAllDerivedDefinitions("SubRegIndex");
683f1bb1519SJakob Stoklund Olesen   std::sort(SRIs.begin(), SRIs.end(), LessRecord());
684f1bb1519SJakob Stoklund Olesen   NumNamedIndices = SRIs.size();
685f1bb1519SJakob Stoklund Olesen   for (unsigned i = 0, e = SRIs.size(); i != e; ++i)
686f1bb1519SJakob Stoklund Olesen     getSubRegIdx(SRIs[i]);
68721231609SJakob Stoklund Olesen   // Build composite maps from ComposedOf fields.
68821231609SJakob Stoklund Olesen   for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
68921231609SJakob Stoklund Olesen     SubRegIndices[i]->updateComponents(*this);
69084bd44ebSJakob Stoklund Olesen 
69184bd44ebSJakob Stoklund Olesen   // Read in the register definitions.
69284bd44ebSJakob Stoklund Olesen   std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
69384bd44ebSJakob Stoklund Olesen   std::sort(Regs.begin(), Regs.end(), LessRecord());
69484bd44ebSJakob Stoklund Olesen   Registers.reserve(Regs.size());
69584bd44ebSJakob Stoklund Olesen   // Assign the enumeration values.
69684bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Regs.size(); i != e; ++i)
6978e188be0SJakob Stoklund Olesen     getReg(Regs[i]);
69822ea424dSJakob Stoklund Olesen 
6993bd1b65eSJakob Stoklund Olesen   // Expand tuples and number the new registers.
7003bd1b65eSJakob Stoklund Olesen   std::vector<Record*> Tups =
7013bd1b65eSJakob Stoklund Olesen     Records.getAllDerivedDefinitions("RegisterTuples");
7023bd1b65eSJakob Stoklund Olesen   for (unsigned i = 0, e = Tups.size(); i != e; ++i) {
7033bd1b65eSJakob Stoklund Olesen     const std::vector<Record*> *TupRegs = Sets.expand(Tups[i]);
7043bd1b65eSJakob Stoklund Olesen     for (unsigned j = 0, je = TupRegs->size(); j != je; ++j)
7053bd1b65eSJakob Stoklund Olesen       getReg((*TupRegs)[j]);
7063bd1b65eSJakob Stoklund Olesen   }
7073bd1b65eSJakob Stoklund Olesen 
70803efe84dSJakob Stoklund Olesen   // Precompute all sub-register maps now all the registers are known.
70903efe84dSJakob Stoklund Olesen   // This will create Composite entries for all inferred sub-register indices.
7101a004ca0SAndrew Trick   NumRegUnits = 0;
71103efe84dSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i)
71203efe84dSJakob Stoklund Olesen     Registers[i]->getSubRegs(*this);
71303efe84dSJakob Stoklund Olesen 
71422ea424dSJakob Stoklund Olesen   // Read in register class definitions.
71522ea424dSJakob Stoklund Olesen   std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass");
71622ea424dSJakob Stoklund Olesen   if (RCs.empty())
71722ea424dSJakob Stoklund Olesen     throw std::string("No 'RegisterClass' subclasses defined!");
71822ea424dSJakob Stoklund Olesen 
71903efe84dSJakob Stoklund Olesen   // Allocate user-defined register classes.
72022ea424dSJakob Stoklund Olesen   RegClasses.reserve(RCs.size());
72103efe84dSJakob Stoklund Olesen   for (unsigned i = 0, e = RCs.size(); i != e; ++i)
72203efe84dSJakob Stoklund Olesen     addToMaps(new CodeGenRegisterClass(*this, RCs[i]));
72303efe84dSJakob Stoklund Olesen 
72403efe84dSJakob Stoklund Olesen   // Infer missing classes to create a full algebra.
72503efe84dSJakob Stoklund Olesen   computeInferredRegisterClasses();
72603efe84dSJakob Stoklund Olesen 
727c0fc173dSJakob Stoklund Olesen   // Order register classes topologically and assign enum values.
728c0fc173dSJakob Stoklund Olesen   array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC);
729c0fc173dSJakob Stoklund Olesen   for (unsigned i = 0, e = RegClasses.size(); i != e; ++i)
730c0fc173dSJakob Stoklund Olesen     RegClasses[i]->EnumValue = i;
73103efe84dSJakob Stoklund Olesen   CodeGenRegisterClass::computeSubClasses(*this);
73276a5a71eSJakob Stoklund Olesen }
73376a5a71eSJakob Stoklund Olesen 
734f1bb1519SJakob Stoklund Olesen CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) {
735f1bb1519SJakob Stoklund Olesen   CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def];
736f1bb1519SJakob Stoklund Olesen   if (Idx)
737f1bb1519SJakob Stoklund Olesen     return Idx;
738f1bb1519SJakob Stoklund Olesen   Idx = new CodeGenSubRegIndex(Def, SubRegIndices.size() + 1);
739f1bb1519SJakob Stoklund Olesen   SubRegIndices.push_back(Idx);
740f1bb1519SJakob Stoklund Olesen   return Idx;
741f1bb1519SJakob Stoklund Olesen }
742f1bb1519SJakob Stoklund Olesen 
74384bd44ebSJakob Stoklund Olesen CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
7448e188be0SJakob Stoklund Olesen   CodeGenRegister *&Reg = Def2Reg[Def];
7458e188be0SJakob Stoklund Olesen   if (Reg)
74684bd44ebSJakob Stoklund Olesen     return Reg;
7478e188be0SJakob Stoklund Olesen   Reg = new CodeGenRegister(Def, Registers.size() + 1);
7488e188be0SJakob Stoklund Olesen   Registers.push_back(Reg);
7498e188be0SJakob Stoklund Olesen   return Reg;
75084bd44ebSJakob Stoklund Olesen }
75184bd44ebSJakob Stoklund Olesen 
75203efe84dSJakob Stoklund Olesen void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) {
75303efe84dSJakob Stoklund Olesen   RegClasses.push_back(RC);
75403efe84dSJakob Stoklund Olesen 
75503efe84dSJakob Stoklund Olesen   if (Record *Def = RC->getDef())
75603efe84dSJakob Stoklund Olesen     Def2RC.insert(std::make_pair(Def, RC));
75703efe84dSJakob Stoklund Olesen 
75803efe84dSJakob Stoklund Olesen   // Duplicate classes are rejected by insert().
75903efe84dSJakob Stoklund Olesen   // That's OK, we only care about the properties handled by CGRC::Key.
76003efe84dSJakob Stoklund Olesen   CodeGenRegisterClass::Key K(*RC);
76103efe84dSJakob Stoklund Olesen   Key2RC.insert(std::make_pair(K, RC));
76203efe84dSJakob Stoklund Olesen }
76303efe84dSJakob Stoklund Olesen 
7647ebc6b05SJakob Stoklund Olesen // Create a synthetic sub-class if it is missing.
7657ebc6b05SJakob Stoklund Olesen CodeGenRegisterClass*
7667ebc6b05SJakob Stoklund Olesen CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
7677ebc6b05SJakob Stoklund Olesen                                     const CodeGenRegister::Set *Members,
7687ebc6b05SJakob Stoklund Olesen                                     StringRef Name) {
7697ebc6b05SJakob Stoklund Olesen   // Synthetic sub-class has the same size and alignment as RC.
7707ebc6b05SJakob Stoklund Olesen   CodeGenRegisterClass::Key K(Members, RC->SpillSize, RC->SpillAlignment);
7717ebc6b05SJakob Stoklund Olesen   RCKeyMap::const_iterator FoundI = Key2RC.find(K);
7727ebc6b05SJakob Stoklund Olesen   if (FoundI != Key2RC.end())
7737ebc6b05SJakob Stoklund Olesen     return FoundI->second;
7747ebc6b05SJakob Stoklund Olesen 
7757ebc6b05SJakob Stoklund Olesen   // Sub-class doesn't exist, create a new one.
7767ebc6b05SJakob Stoklund Olesen   CodeGenRegisterClass *NewRC = new CodeGenRegisterClass(Name, K);
7777ebc6b05SJakob Stoklund Olesen   addToMaps(NewRC);
7787ebc6b05SJakob Stoklund Olesen   return NewRC;
7797ebc6b05SJakob Stoklund Olesen }
7807ebc6b05SJakob Stoklund Olesen 
78122ea424dSJakob Stoklund Olesen CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) {
78222ea424dSJakob Stoklund Olesen   if (CodeGenRegisterClass *RC = Def2RC[Def])
78322ea424dSJakob Stoklund Olesen     return RC;
78422ea424dSJakob Stoklund Olesen 
78522ea424dSJakob Stoklund Olesen   throw TGError(Def->getLoc(), "Not a known RegisterClass!");
78622ea424dSJakob Stoklund Olesen }
78722ea424dSJakob Stoklund Olesen 
788f1bb1519SJakob Stoklund Olesen CodeGenSubRegIndex*
789f1bb1519SJakob Stoklund Olesen CodeGenRegBank::getCompositeSubRegIndex(CodeGenSubRegIndex *A,
7909a44ad70SJakob Stoklund Olesen                                         CodeGenSubRegIndex *B) {
79184bd44ebSJakob Stoklund Olesen   // Look for an existing entry.
7929a44ad70SJakob Stoklund Olesen   CodeGenSubRegIndex *Comp = A->compose(B);
7939a44ad70SJakob Stoklund Olesen   if (Comp)
79484bd44ebSJakob Stoklund Olesen     return Comp;
79584bd44ebSJakob Stoklund Olesen 
79684bd44ebSJakob Stoklund Olesen   // None exists, synthesize one.
79776a5a71eSJakob Stoklund Olesen   std::string Name = A->getName() + "_then_" + B->getName();
798f1bb1519SJakob Stoklund Olesen   Comp = getSubRegIdx(new Record(Name, SMLoc(), Records));
7999a44ad70SJakob Stoklund Olesen   A->addComposite(B, Comp);
80084bd44ebSJakob Stoklund Olesen   return Comp;
80176a5a71eSJakob Stoklund Olesen }
80276a5a71eSJakob Stoklund Olesen 
80384bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeComposites() {
80484bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
8058e188be0SJakob Stoklund Olesen     CodeGenRegister *Reg1 = Registers[i];
806d2b4713eSJakob Stoklund Olesen     const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs();
80784bd44ebSJakob Stoklund Olesen     for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(),
80884bd44ebSJakob Stoklund Olesen          e1 = SRM1.end(); i1 != e1; ++i1) {
809f1bb1519SJakob Stoklund Olesen       CodeGenSubRegIndex *Idx1 = i1->first;
81084bd44ebSJakob Stoklund Olesen       CodeGenRegister *Reg2 = i1->second;
81184bd44ebSJakob Stoklund Olesen       // Ignore identity compositions.
81284bd44ebSJakob Stoklund Olesen       if (Reg1 == Reg2)
81384bd44ebSJakob Stoklund Olesen         continue;
814d2b4713eSJakob Stoklund Olesen       const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs();
81584bd44ebSJakob Stoklund Olesen       // Try composing Idx1 with another SubRegIndex.
81684bd44ebSJakob Stoklund Olesen       for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM2.begin(),
81784bd44ebSJakob Stoklund Olesen            e2 = SRM2.end(); i2 != e2; ++i2) {
8189a44ad70SJakob Stoklund Olesen       CodeGenSubRegIndex *Idx2 = i2->first;
81984bd44ebSJakob Stoklund Olesen         CodeGenRegister *Reg3 = i2->second;
82084bd44ebSJakob Stoklund Olesen         // Ignore identity compositions.
82184bd44ebSJakob Stoklund Olesen         if (Reg2 == Reg3)
82284bd44ebSJakob Stoklund Olesen           continue;
82384bd44ebSJakob Stoklund Olesen         // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3.
82484bd44ebSJakob Stoklund Olesen         for (CodeGenRegister::SubRegMap::const_iterator i1d = SRM1.begin(),
82584bd44ebSJakob Stoklund Olesen              e1d = SRM1.end(); i1d != e1d; ++i1d) {
82684bd44ebSJakob Stoklund Olesen           if (i1d->second == Reg3) {
82784bd44ebSJakob Stoklund Olesen             // Conflicting composition? Emit a warning but allow it.
8289a44ad70SJakob Stoklund Olesen             if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, i1d->first))
829f1bb1519SJakob Stoklund Olesen               errs() << "Warning: SubRegIndex " << Idx1->getQualifiedName()
8309a44ad70SJakob Stoklund Olesen                      << " and " << Idx2->getQualifiedName()
83184bd44ebSJakob Stoklund Olesen                      << " compose ambiguously as "
8329a44ad70SJakob Stoklund Olesen                      << Prev->getQualifiedName() << " or "
833f1bb1519SJakob Stoklund Olesen                      << i1d->first->getQualifiedName() << "\n";
83484bd44ebSJakob Stoklund Olesen           }
83584bd44ebSJakob Stoklund Olesen         }
83684bd44ebSJakob Stoklund Olesen       }
83784bd44ebSJakob Stoklund Olesen     }
83884bd44ebSJakob Stoklund Olesen   }
83984bd44ebSJakob Stoklund Olesen 
84084bd44ebSJakob Stoklund Olesen   // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid
84184bd44ebSJakob Stoklund Olesen   // compositions, so remove any mappings of that form.
8429a44ad70SJakob Stoklund Olesen   for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
8439a44ad70SJakob Stoklund Olesen     SubRegIndices[i]->cleanComposites();
84484bd44ebSJakob Stoklund Olesen }
84584bd44ebSJakob Stoklund Olesen 
846d2b4713eSJakob Stoklund Olesen // Compute sets of overlapping registers.
847d2b4713eSJakob Stoklund Olesen //
848d2b4713eSJakob Stoklund Olesen // The standard set is all super-registers and all sub-registers, but the
849d2b4713eSJakob Stoklund Olesen // target description can add arbitrary overlapping registers via the 'Aliases'
850d2b4713eSJakob Stoklund Olesen // field. This complicates things, but we can compute overlapping sets using
851d2b4713eSJakob Stoklund Olesen // the following rules:
852d2b4713eSJakob Stoklund Olesen //
853d2b4713eSJakob Stoklund Olesen // 1. The relation overlap(A, B) is reflexive and symmetric but not transitive.
854d2b4713eSJakob Stoklund Olesen //
855d2b4713eSJakob Stoklund Olesen // 2. overlap(A, B) implies overlap(A, S) for all S in supers(B).
856d2b4713eSJakob Stoklund Olesen //
857d2b4713eSJakob Stoklund Olesen // Alternatively:
858d2b4713eSJakob Stoklund Olesen //
859d2b4713eSJakob Stoklund Olesen //    overlap(A, B) iff there exists:
860d2b4713eSJakob Stoklund Olesen //    A' in { A, subregs(A) } and B' in { B, subregs(B) } such that:
861d2b4713eSJakob Stoklund Olesen //    A' = B' or A' in aliases(B') or B' in aliases(A').
862d2b4713eSJakob Stoklund Olesen //
863d2b4713eSJakob Stoklund Olesen // Here subregs(A) is the full flattened sub-register set returned by
864d2b4713eSJakob Stoklund Olesen // A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the
865d2b4713eSJakob Stoklund Olesen // description of register A.
866d2b4713eSJakob Stoklund Olesen //
867d2b4713eSJakob Stoklund Olesen // This also implies that registers with a common sub-register are considered
868d2b4713eSJakob Stoklund Olesen // overlapping. This can happen when forming register pairs:
869d2b4713eSJakob Stoklund Olesen //
870d2b4713eSJakob Stoklund Olesen //    P0 = (R0, R1)
871d2b4713eSJakob Stoklund Olesen //    P1 = (R1, R2)
872d2b4713eSJakob Stoklund Olesen //    P2 = (R2, R3)
873d2b4713eSJakob Stoklund Olesen //
874d2b4713eSJakob Stoklund Olesen // In this case, we will infer an overlap between P0 and P1 because of the
875d2b4713eSJakob Stoklund Olesen // shared sub-register R1. There is no overlap between P0 and P2.
876d2b4713eSJakob Stoklund Olesen //
877d2b4713eSJakob Stoklund Olesen void CodeGenRegBank::
878d2b4713eSJakob Stoklund Olesen computeOverlaps(std::map<const CodeGenRegister*, CodeGenRegister::Set> &Map) {
879d2b4713eSJakob Stoklund Olesen   assert(Map.empty());
880d2b4713eSJakob Stoklund Olesen 
881d2b4713eSJakob Stoklund Olesen   // Collect overlaps that don't follow from rule 2.
882d2b4713eSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
8838e188be0SJakob Stoklund Olesen     CodeGenRegister *Reg = Registers[i];
884d2b4713eSJakob Stoklund Olesen     CodeGenRegister::Set &Overlaps = Map[Reg];
885d2b4713eSJakob Stoklund Olesen 
886d2b4713eSJakob Stoklund Olesen     // Reg overlaps itself.
887d2b4713eSJakob Stoklund Olesen     Overlaps.insert(Reg);
888d2b4713eSJakob Stoklund Olesen 
889d2b4713eSJakob Stoklund Olesen     // All super-registers overlap.
890d2b4713eSJakob Stoklund Olesen     const CodeGenRegister::SuperRegList &Supers = Reg->getSuperRegs();
891d2b4713eSJakob Stoklund Olesen     Overlaps.insert(Supers.begin(), Supers.end());
892d2b4713eSJakob Stoklund Olesen 
893d2b4713eSJakob Stoklund Olesen     // Form symmetrical relations from the special Aliases[] lists.
894d2b4713eSJakob Stoklund Olesen     std::vector<Record*> RegList = Reg->TheDef->getValueAsListOfDefs("Aliases");
895d2b4713eSJakob Stoklund Olesen     for (unsigned i2 = 0, e2 = RegList.size(); i2 != e2; ++i2) {
896d2b4713eSJakob Stoklund Olesen       CodeGenRegister *Reg2 = getReg(RegList[i2]);
897d2b4713eSJakob Stoklund Olesen       CodeGenRegister::Set &Overlaps2 = Map[Reg2];
898d2b4713eSJakob Stoklund Olesen       const CodeGenRegister::SuperRegList &Supers2 = Reg2->getSuperRegs();
899d2b4713eSJakob Stoklund Olesen       // Reg overlaps Reg2 which implies it overlaps supers(Reg2).
900d2b4713eSJakob Stoklund Olesen       Overlaps.insert(Reg2);
901d2b4713eSJakob Stoklund Olesen       Overlaps.insert(Supers2.begin(), Supers2.end());
902d2b4713eSJakob Stoklund Olesen       Overlaps2.insert(Reg);
903d2b4713eSJakob Stoklund Olesen       Overlaps2.insert(Supers.begin(), Supers.end());
904d2b4713eSJakob Stoklund Olesen     }
905d2b4713eSJakob Stoklund Olesen   }
906d2b4713eSJakob Stoklund Olesen 
907d2b4713eSJakob Stoklund Olesen   // Apply rule 2. and inherit all sub-register overlaps.
908d2b4713eSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
9098e188be0SJakob Stoklund Olesen     CodeGenRegister *Reg = Registers[i];
910d2b4713eSJakob Stoklund Olesen     CodeGenRegister::Set &Overlaps = Map[Reg];
911d2b4713eSJakob Stoklund Olesen     const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs();
912d2b4713eSJakob Stoklund Olesen     for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM.begin(),
913d2b4713eSJakob Stoklund Olesen          e2 = SRM.end(); i2 != e2; ++i2) {
914d2b4713eSJakob Stoklund Olesen       CodeGenRegister::Set &Overlaps2 = Map[i2->second];
915d2b4713eSJakob Stoklund Olesen       Overlaps.insert(Overlaps2.begin(), Overlaps2.end());
916d2b4713eSJakob Stoklund Olesen     }
917d2b4713eSJakob Stoklund Olesen   }
918d2b4713eSJakob Stoklund Olesen }
919d2b4713eSJakob Stoklund Olesen 
92084bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeDerivedInfo() {
92184bd44ebSJakob Stoklund Olesen   computeComposites();
92284bd44ebSJakob Stoklund Olesen }
92384bd44ebSJakob Stoklund Olesen 
924c0f97e3dSJakob Stoklund Olesen //
925c0f97e3dSJakob Stoklund Olesen // Synthesize missing register class intersections.
926c0f97e3dSJakob Stoklund Olesen //
927c0f97e3dSJakob Stoklund Olesen // Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X)
928c0f97e3dSJakob Stoklund Olesen // returns a maximal register class for all X.
929c0f97e3dSJakob Stoklund Olesen //
930c0f97e3dSJakob Stoklund Olesen void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
931c0f97e3dSJakob Stoklund Olesen   for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) {
932c0f97e3dSJakob Stoklund Olesen     CodeGenRegisterClass *RC1 = RC;
933c0f97e3dSJakob Stoklund Olesen     CodeGenRegisterClass *RC2 = RegClasses[rci];
934c0f97e3dSJakob Stoklund Olesen     if (RC1 == RC2)
935c0f97e3dSJakob Stoklund Olesen       continue;
936c0f97e3dSJakob Stoklund Olesen 
937c0f97e3dSJakob Stoklund Olesen     // Compute the set intersection of RC1 and RC2.
938c0f97e3dSJakob Stoklund Olesen     const CodeGenRegister::Set &Memb1 = RC1->getMembers();
939c0f97e3dSJakob Stoklund Olesen     const CodeGenRegister::Set &Memb2 = RC2->getMembers();
940c0f97e3dSJakob Stoklund Olesen     CodeGenRegister::Set Intersection;
941c0f97e3dSJakob Stoklund Olesen     std::set_intersection(Memb1.begin(), Memb1.end(),
942c0f97e3dSJakob Stoklund Olesen                           Memb2.begin(), Memb2.end(),
943f94cd193SJakob Stoklund Olesen                           std::inserter(Intersection, Intersection.begin()),
944f94cd193SJakob Stoklund Olesen                           CodeGenRegister::Less());
945c0f97e3dSJakob Stoklund Olesen 
946c0f97e3dSJakob Stoklund Olesen     // Skip disjoint class pairs.
947c0f97e3dSJakob Stoklund Olesen     if (Intersection.empty())
948c0f97e3dSJakob Stoklund Olesen       continue;
949c0f97e3dSJakob Stoklund Olesen 
950c0f97e3dSJakob Stoklund Olesen     // If RC1 and RC2 have different spill sizes or alignments, use the
951c0f97e3dSJakob Stoklund Olesen     // larger size for sub-classing.  If they are equal, prefer RC1.
952c0f97e3dSJakob Stoklund Olesen     if (RC2->SpillSize > RC1->SpillSize ||
953c0f97e3dSJakob Stoklund Olesen         (RC2->SpillSize == RC1->SpillSize &&
954c0f97e3dSJakob Stoklund Olesen          RC2->SpillAlignment > RC1->SpillAlignment))
955c0f97e3dSJakob Stoklund Olesen       std::swap(RC1, RC2);
956c0f97e3dSJakob Stoklund Olesen 
957c0f97e3dSJakob Stoklund Olesen     getOrCreateSubClass(RC1, &Intersection,
958c0f97e3dSJakob Stoklund Olesen                         RC1->getName() + "_and_" + RC2->getName());
959c0f97e3dSJakob Stoklund Olesen   }
960c0f97e3dSJakob Stoklund Olesen }
961c0f97e3dSJakob Stoklund Olesen 
96203efe84dSJakob Stoklund Olesen //
9636a5f0a19SJakob Stoklund Olesen // Synthesize missing sub-classes for getSubClassWithSubReg().
9646a5f0a19SJakob Stoklund Olesen //
9656a5f0a19SJakob Stoklund Olesen // Make sure that the set of registers in RC with a given SubIdx sub-register
9666a5f0a19SJakob Stoklund Olesen // form a register class.  Update RC->SubClassWithSubReg.
9676a5f0a19SJakob Stoklund Olesen //
9686a5f0a19SJakob Stoklund Olesen void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
9696a5f0a19SJakob Stoklund Olesen   // Map SubRegIndex to set of registers in RC supporting that SubRegIndex.
970f1bb1519SJakob Stoklund Olesen   typedef std::map<CodeGenSubRegIndex*, CodeGenRegister::Set,
971f1bb1519SJakob Stoklund Olesen                    CodeGenSubRegIndex::Less> SubReg2SetMap;
97203efe84dSJakob Stoklund Olesen 
97303efe84dSJakob Stoklund Olesen   // Compute the set of registers supporting each SubRegIndex.
97403efe84dSJakob Stoklund Olesen   SubReg2SetMap SRSets;
9756a5f0a19SJakob Stoklund Olesen   for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
9766a5f0a19SJakob Stoklund Olesen        RE = RC->getMembers().end(); RI != RE; ++RI) {
977b1147c46SJakob Stoklund Olesen     const CodeGenRegister::SubRegMap &SRM = (*RI)->getSubRegs();
978b1147c46SJakob Stoklund Olesen     for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
979b1147c46SJakob Stoklund Olesen          E = SRM.end(); I != E; ++I)
98003efe84dSJakob Stoklund Olesen       SRSets[I->first].insert(*RI);
98103efe84dSJakob Stoklund Olesen   }
98203efe84dSJakob Stoklund Olesen 
98303efe84dSJakob Stoklund Olesen   // Find matching classes for all SRSets entries.  Iterate in SubRegIndex
98403efe84dSJakob Stoklund Olesen   // numerical order to visit synthetic indices last.
98503efe84dSJakob Stoklund Olesen   for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
986f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *SubIdx = SubRegIndices[sri];
9873a541b04SJakob Stoklund Olesen     SubReg2SetMap::const_iterator I = SRSets.find(SubIdx);
98803efe84dSJakob Stoklund Olesen     // Unsupported SubRegIndex. Skip it.
98903efe84dSJakob Stoklund Olesen     if (I == SRSets.end())
99003efe84dSJakob Stoklund Olesen       continue;
9913a541b04SJakob Stoklund Olesen     // In most cases, all RC registers support the SubRegIndex.
9926a5f0a19SJakob Stoklund Olesen     if (I->second.size() == RC->getMembers().size()) {
9936a5f0a19SJakob Stoklund Olesen       RC->setSubClassWithSubReg(SubIdx, RC);
99403efe84dSJakob Stoklund Olesen       continue;
9953a541b04SJakob Stoklund Olesen     }
99603efe84dSJakob Stoklund Olesen     // This is a real subset.  See if we have a matching class.
9977ebc6b05SJakob Stoklund Olesen     CodeGenRegisterClass *SubRC =
9986a5f0a19SJakob Stoklund Olesen       getOrCreateSubClass(RC, &I->second,
9996a5f0a19SJakob Stoklund Olesen                           RC->getName() + "_with_" + I->first->getName());
10006a5f0a19SJakob Stoklund Olesen     RC->setSubClassWithSubReg(SubIdx, SubRC);
10016a5f0a19SJakob Stoklund Olesen   }
100203efe84dSJakob Stoklund Olesen }
1003c0f97e3dSJakob Stoklund Olesen 
10046a5f0a19SJakob Stoklund Olesen //
1005b92f557cSJakob Stoklund Olesen // Synthesize missing sub-classes of RC for getMatchingSuperRegClass().
1006b92f557cSJakob Stoklund Olesen //
1007b92f557cSJakob Stoklund Olesen // Create sub-classes of RC such that getMatchingSuperRegClass(RC, SubIdx, X)
1008b92f557cSJakob Stoklund Olesen // has a maximal result for any SubIdx and any X >= FirstSubRegRC.
1009b92f557cSJakob Stoklund Olesen //
1010b92f557cSJakob Stoklund Olesen 
1011b92f557cSJakob Stoklund Olesen void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
1012b92f557cSJakob Stoklund Olesen                                                 unsigned FirstSubRegRC) {
1013b92f557cSJakob Stoklund Olesen   SmallVector<std::pair<const CodeGenRegister*,
1014b92f557cSJakob Stoklund Olesen                         const CodeGenRegister*>, 16> SSPairs;
1015b92f557cSJakob Stoklund Olesen 
1016b92f557cSJakob Stoklund Olesen   // Iterate in SubRegIndex numerical order to visit synthetic indices last.
1017b92f557cSJakob Stoklund Olesen   for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
1018f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *SubIdx = SubRegIndices[sri];
1019b92f557cSJakob Stoklund Olesen     // Skip indexes that aren't fully supported by RC's registers. This was
1020b92f557cSJakob Stoklund Olesen     // computed by inferSubClassWithSubReg() above which should have been
1021b92f557cSJakob Stoklund Olesen     // called first.
1022b92f557cSJakob Stoklund Olesen     if (RC->getSubClassWithSubReg(SubIdx) != RC)
1023b92f557cSJakob Stoklund Olesen       continue;
1024b92f557cSJakob Stoklund Olesen 
1025b92f557cSJakob Stoklund Olesen     // Build list of (Super, Sub) pairs for this SubIdx.
1026b92f557cSJakob Stoklund Olesen     SSPairs.clear();
1027b92f557cSJakob Stoklund Olesen     for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
1028b92f557cSJakob Stoklund Olesen          RE = RC->getMembers().end(); RI != RE; ++RI) {
1029b92f557cSJakob Stoklund Olesen       const CodeGenRegister *Super = *RI;
1030b92f557cSJakob Stoklund Olesen       const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
1031b92f557cSJakob Stoklund Olesen       assert(Sub && "Missing sub-register");
1032b92f557cSJakob Stoklund Olesen       SSPairs.push_back(std::make_pair(Super, Sub));
1033b92f557cSJakob Stoklund Olesen     }
1034b92f557cSJakob Stoklund Olesen 
1035b92f557cSJakob Stoklund Olesen     // Iterate over sub-register class candidates.  Ignore classes created by
1036b92f557cSJakob Stoklund Olesen     // this loop. They will never be useful.
1037b92f557cSJakob Stoklund Olesen     for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
1038b92f557cSJakob Stoklund Olesen          ++rci) {
1039b92f557cSJakob Stoklund Olesen       CodeGenRegisterClass *SubRC = RegClasses[rci];
1040b92f557cSJakob Stoklund Olesen       // Compute the subset of RC that maps into SubRC.
1041b92f557cSJakob Stoklund Olesen       CodeGenRegister::Set SubSet;
1042b92f557cSJakob Stoklund Olesen       for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
1043b92f557cSJakob Stoklund Olesen         if (SubRC->contains(SSPairs[i].second))
1044b92f557cSJakob Stoklund Olesen           SubSet.insert(SSPairs[i].first);
1045b92f557cSJakob Stoklund Olesen       if (SubSet.empty())
1046b92f557cSJakob Stoklund Olesen         continue;
1047b92f557cSJakob Stoklund Olesen       // RC injects completely into SubRC.
1048c7b437aeSJakob Stoklund Olesen       if (SubSet.size() == SSPairs.size()) {
1049c7b437aeSJakob Stoklund Olesen         SubRC->addSuperRegClass(SubIdx, RC);
1050b92f557cSJakob Stoklund Olesen         continue;
1051c7b437aeSJakob Stoklund Olesen       }
1052b92f557cSJakob Stoklund Olesen       // Only a subset of RC maps into SubRC. Make sure it is represented by a
1053b92f557cSJakob Stoklund Olesen       // class.
1054b92f557cSJakob Stoklund Olesen       getOrCreateSubClass(RC, &SubSet, RC->getName() +
1055b92f557cSJakob Stoklund Olesen                           "_with_" + SubIdx->getName() +
1056b92f557cSJakob Stoklund Olesen                           "_in_" + SubRC->getName());
1057b92f557cSJakob Stoklund Olesen     }
1058b92f557cSJakob Stoklund Olesen   }
1059b92f557cSJakob Stoklund Olesen }
1060b92f557cSJakob Stoklund Olesen 
1061b92f557cSJakob Stoklund Olesen 
1062b92f557cSJakob Stoklund Olesen //
10636a5f0a19SJakob Stoklund Olesen // Infer missing register classes.
10646a5f0a19SJakob Stoklund Olesen //
10656a5f0a19SJakob Stoklund Olesen void CodeGenRegBank::computeInferredRegisterClasses() {
10666a5f0a19SJakob Stoklund Olesen   // When this function is called, the register classes have not been sorted
10676a5f0a19SJakob Stoklund Olesen   // and assigned EnumValues yet.  That means getSubClasses(),
10686a5f0a19SJakob Stoklund Olesen   // getSuperClasses(), and hasSubClass() functions are defunct.
1069b92f557cSJakob Stoklund Olesen   unsigned FirstNewRC = RegClasses.size();
10706a5f0a19SJakob Stoklund Olesen 
10716a5f0a19SJakob Stoklund Olesen   // Visit all register classes, including the ones being added by the loop.
10726a5f0a19SJakob Stoklund Olesen   for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
10736a5f0a19SJakob Stoklund Olesen     CodeGenRegisterClass *RC = RegClasses[rci];
10746a5f0a19SJakob Stoklund Olesen 
10756a5f0a19SJakob Stoklund Olesen     // Synthesize answers for getSubClassWithSubReg().
10766a5f0a19SJakob Stoklund Olesen     inferSubClassWithSubReg(RC);
10776a5f0a19SJakob Stoklund Olesen 
1078c0f97e3dSJakob Stoklund Olesen     // Synthesize answers for getCommonSubClass().
10796a5f0a19SJakob Stoklund Olesen     inferCommonSubClass(RC);
1080b92f557cSJakob Stoklund Olesen 
1081b92f557cSJakob Stoklund Olesen     // Synthesize answers for getMatchingSuperRegClass().
1082b92f557cSJakob Stoklund Olesen     inferMatchingSuperRegClass(RC);
1083b92f557cSJakob Stoklund Olesen 
1084b92f557cSJakob Stoklund Olesen     // New register classes are created while this loop is running, and we need
1085b92f557cSJakob Stoklund Olesen     // to visit all of them.  I  particular, inferMatchingSuperRegClass needs
1086b92f557cSJakob Stoklund Olesen     // to match old super-register classes with sub-register classes created
1087b92f557cSJakob Stoklund Olesen     // after inferMatchingSuperRegClass was called.  At this point,
1088b92f557cSJakob Stoklund Olesen     // inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC =
1089b92f557cSJakob Stoklund Olesen     // [0..FirstNewRC).  We need to cover SubRC = [FirstNewRC..rci].
1090b92f557cSJakob Stoklund Olesen     if (rci + 1 == FirstNewRC) {
1091b92f557cSJakob Stoklund Olesen       unsigned NextNewRC = RegClasses.size();
1092b92f557cSJakob Stoklund Olesen       for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2)
1093b92f557cSJakob Stoklund Olesen         inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC);
1094b92f557cSJakob Stoklund Olesen       FirstNewRC = NextNewRC;
1095b92f557cSJakob Stoklund Olesen     }
109603efe84dSJakob Stoklund Olesen   }
109703efe84dSJakob Stoklund Olesen }
109803efe84dSJakob Stoklund Olesen 
109922ea424dSJakob Stoklund Olesen /// getRegisterClassForRegister - Find the register class that contains the
110022ea424dSJakob Stoklund Olesen /// specified physical register.  If the register is not in a register class,
110122ea424dSJakob Stoklund Olesen /// return null. If the register is in multiple classes, and the classes have a
110222ea424dSJakob Stoklund Olesen /// superset-subset relationship and the same set of types, return the
110322ea424dSJakob Stoklund Olesen /// superclass.  Otherwise return null.
110422ea424dSJakob Stoklund Olesen const CodeGenRegisterClass*
110522ea424dSJakob Stoklund Olesen CodeGenRegBank::getRegClassForRegister(Record *R) {
1106d7bc5c26SJakob Stoklund Olesen   const CodeGenRegister *Reg = getReg(R);
110719be2ab3SJakob Stoklund Olesen   ArrayRef<CodeGenRegisterClass*> RCs = getRegClasses();
110822ea424dSJakob Stoklund Olesen   const CodeGenRegisterClass *FoundRC = 0;
110922ea424dSJakob Stoklund Olesen   for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
111019be2ab3SJakob Stoklund Olesen     const CodeGenRegisterClass &RC = *RCs[i];
1111d7bc5c26SJakob Stoklund Olesen     if (!RC.contains(Reg))
111222ea424dSJakob Stoklund Olesen       continue;
111322ea424dSJakob Stoklund Olesen 
111422ea424dSJakob Stoklund Olesen     // If this is the first class that contains the register,
111522ea424dSJakob Stoklund Olesen     // make a note of it and go on to the next class.
111622ea424dSJakob Stoklund Olesen     if (!FoundRC) {
111722ea424dSJakob Stoklund Olesen       FoundRC = &RC;
111822ea424dSJakob Stoklund Olesen       continue;
111922ea424dSJakob Stoklund Olesen     }
112022ea424dSJakob Stoklund Olesen 
112122ea424dSJakob Stoklund Olesen     // If a register's classes have different types, return null.
112222ea424dSJakob Stoklund Olesen     if (RC.getValueTypes() != FoundRC->getValueTypes())
112322ea424dSJakob Stoklund Olesen       return 0;
112422ea424dSJakob Stoklund Olesen 
112522ea424dSJakob Stoklund Olesen     // Check to see if the previously found class that contains
112622ea424dSJakob Stoklund Olesen     // the register is a subclass of the current class. If so,
112722ea424dSJakob Stoklund Olesen     // prefer the superclass.
1128d7bc5c26SJakob Stoklund Olesen     if (RC.hasSubClass(FoundRC)) {
112922ea424dSJakob Stoklund Olesen       FoundRC = &RC;
113022ea424dSJakob Stoklund Olesen       continue;
113122ea424dSJakob Stoklund Olesen     }
113222ea424dSJakob Stoklund Olesen 
113322ea424dSJakob Stoklund Olesen     // Check to see if the previously found class that contains
113422ea424dSJakob Stoklund Olesen     // the register is a superclass of the current class. If so,
113522ea424dSJakob Stoklund Olesen     // prefer the superclass.
1136d7bc5c26SJakob Stoklund Olesen     if (FoundRC->hasSubClass(&RC))
113722ea424dSJakob Stoklund Olesen       continue;
113822ea424dSJakob Stoklund Olesen 
113922ea424dSJakob Stoklund Olesen     // Multiple classes, and neither is a superclass of the other.
114022ea424dSJakob Stoklund Olesen     // Return null.
114122ea424dSJakob Stoklund Olesen     return 0;
114222ea424dSJakob Stoklund Olesen   }
114322ea424dSJakob Stoklund Olesen   return FoundRC;
114422ea424dSJakob Stoklund Olesen }
1145c3abb0f6SJakob Stoklund Olesen 
1146c3abb0f6SJakob Stoklund Olesen BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef<Record*> Regs) {
114700296815SJakob Stoklund Olesen   SetVector<const CodeGenRegister*> Set;
1148c3abb0f6SJakob Stoklund Olesen 
1149c3abb0f6SJakob Stoklund Olesen   // First add Regs with all sub-registers.
1150c3abb0f6SJakob Stoklund Olesen   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
1151c3abb0f6SJakob Stoklund Olesen     CodeGenRegister *Reg = getReg(Regs[i]);
1152c3abb0f6SJakob Stoklund Olesen     if (Set.insert(Reg))
1153c3abb0f6SJakob Stoklund Olesen       // Reg is new, add all sub-registers.
1154c3abb0f6SJakob Stoklund Olesen       // The pre-ordering is not important here.
1155f1bb1519SJakob Stoklund Olesen       Reg->addSubRegsPreOrder(Set, *this);
1156c3abb0f6SJakob Stoklund Olesen   }
1157c3abb0f6SJakob Stoklund Olesen 
1158c3abb0f6SJakob Stoklund Olesen   // Second, find all super-registers that are completely covered by the set.
1159f43b5995SJakob Stoklund Olesen   for (unsigned i = 0; i != Set.size(); ++i) {
1160f43b5995SJakob Stoklund Olesen     const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs();
1161f43b5995SJakob Stoklund Olesen     for (unsigned j = 0, e = SR.size(); j != e; ++j) {
116200296815SJakob Stoklund Olesen       const CodeGenRegister *Super = SR[j];
1163f43b5995SJakob Stoklund Olesen       if (!Super->CoveredBySubRegs || Set.count(Super))
1164f43b5995SJakob Stoklund Olesen         continue;
1165f43b5995SJakob Stoklund Olesen       // This new super-register is covered by its sub-registers.
1166f43b5995SJakob Stoklund Olesen       bool AllSubsInSet = true;
1167f43b5995SJakob Stoklund Olesen       const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs();
1168f43b5995SJakob Stoklund Olesen       for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
1169f43b5995SJakob Stoklund Olesen              E = SRM.end(); I != E; ++I)
1170f43b5995SJakob Stoklund Olesen         if (!Set.count(I->second)) {
1171f43b5995SJakob Stoklund Olesen           AllSubsInSet = false;
1172f43b5995SJakob Stoklund Olesen           break;
1173f43b5995SJakob Stoklund Olesen         }
1174f43b5995SJakob Stoklund Olesen       // All sub-registers in Set, add Super as well.
1175f43b5995SJakob Stoklund Olesen       // We will visit Super later to recheck its super-registers.
1176f43b5995SJakob Stoklund Olesen       if (AllSubsInSet)
1177f43b5995SJakob Stoklund Olesen         Set.insert(Super);
1178f43b5995SJakob Stoklund Olesen     }
1179f43b5995SJakob Stoklund Olesen   }
1180c3abb0f6SJakob Stoklund Olesen 
1181c3abb0f6SJakob Stoklund Olesen   // Convert to BitVector.
1182c3abb0f6SJakob Stoklund Olesen   BitVector BV(Registers.size() + 1);
1183c3abb0f6SJakob Stoklund Olesen   for (unsigned i = 0, e = Set.size(); i != e; ++i)
1184c3abb0f6SJakob Stoklund Olesen     BV.set(Set[i]->EnumValue);
1185c3abb0f6SJakob Stoklund Olesen   return BV;
1186c3abb0f6SJakob Stoklund Olesen }
1187