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 
529a44ad70SJakob Stoklund Olesen void CodeGenSubRegIndex::cleanComposites() {
539a44ad70SJakob Stoklund Olesen   // Clean out redundant mappings of the form this+X -> X.
549a44ad70SJakob Stoklund Olesen   for (CompMap::iterator i = Composed.begin(), e = Composed.end(); i != e;) {
559a44ad70SJakob Stoklund Olesen     CompMap::iterator j = i;
569a44ad70SJakob Stoklund Olesen     ++i;
579a44ad70SJakob Stoklund Olesen     if (j->first == j->second)
589a44ad70SJakob Stoklund Olesen       Composed.erase(j);
599a44ad70SJakob Stoklund Olesen   }
609a44ad70SJakob Stoklund Olesen }
619a44ad70SJakob Stoklund Olesen 
62f1bb1519SJakob Stoklund Olesen //===----------------------------------------------------------------------===//
6368d6d8abSJakob Stoklund Olesen //                              CodeGenRegister
6468d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
6568d6d8abSJakob Stoklund Olesen 
6684bd44ebSJakob Stoklund Olesen CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum)
6784bd44ebSJakob Stoklund Olesen   : TheDef(R),
6884bd44ebSJakob Stoklund Olesen     EnumValue(Enum),
6984bd44ebSJakob Stoklund Olesen     CostPerUse(R->getValueAsInt("CostPerUse")),
70f43b5995SJakob Stoklund Olesen     CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
7184bd44ebSJakob Stoklund Olesen     SubRegsComplete(false)
7284bd44ebSJakob Stoklund Olesen {}
7368d6d8abSJakob Stoklund Olesen 
7468d6d8abSJakob Stoklund Olesen const std::string &CodeGenRegister::getName() const {
7568d6d8abSJakob Stoklund Olesen   return TheDef->getName();
7668d6d8abSJakob Stoklund Olesen }
7768d6d8abSJakob Stoklund Olesen 
7884bd44ebSJakob Stoklund Olesen namespace {
7984bd44ebSJakob Stoklund Olesen   struct Orphan {
8084bd44ebSJakob Stoklund Olesen     CodeGenRegister *SubReg;
81f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *First, *Second;
82f1bb1519SJakob Stoklund Olesen     Orphan(CodeGenRegister *r, CodeGenSubRegIndex *a, CodeGenSubRegIndex *b)
8384bd44ebSJakob Stoklund Olesen       : SubReg(r), First(a), Second(b) {}
8484bd44ebSJakob Stoklund Olesen   };
8584bd44ebSJakob Stoklund Olesen }
8684bd44ebSJakob Stoklund Olesen 
8784bd44ebSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &
8884bd44ebSJakob Stoklund Olesen CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
8984bd44ebSJakob Stoklund Olesen   // Only compute this map once.
9084bd44ebSJakob Stoklund Olesen   if (SubRegsComplete)
9184bd44ebSJakob Stoklund Olesen     return SubRegs;
9284bd44ebSJakob Stoklund Olesen   SubRegsComplete = true;
9384bd44ebSJakob Stoklund Olesen 
9484bd44ebSJakob Stoklund Olesen   std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
9584bd44ebSJakob Stoklund Olesen   std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
9684bd44ebSJakob Stoklund Olesen   if (SubList.size() != Indices.size())
9784bd44ebSJakob Stoklund Olesen     throw TGError(TheDef->getLoc(), "Register " + getName() +
9884bd44ebSJakob Stoklund Olesen                   " SubRegIndices doesn't match SubRegs");
9984bd44ebSJakob Stoklund Olesen 
10084bd44ebSJakob Stoklund Olesen   // First insert the direct subregs and make sure they are fully indexed.
10184bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
10284bd44ebSJakob Stoklund Olesen     CodeGenRegister *SR = RegBank.getReg(SubList[i]);
103f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
104f1bb1519SJakob Stoklund Olesen     if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
105f1bb1519SJakob Stoklund Olesen       throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
10684bd44ebSJakob Stoklund Olesen                     " appears twice in Register " + getName());
10784bd44ebSJakob Stoklund Olesen   }
10884bd44ebSJakob Stoklund Olesen 
10984bd44ebSJakob Stoklund Olesen   // Keep track of inherited subregs and how they can be reached.
11084bd44ebSJakob Stoklund Olesen   SmallVector<Orphan, 8> Orphans;
11184bd44ebSJakob Stoklund Olesen 
11284bd44ebSJakob Stoklund Olesen   // Clone inherited subregs and place duplicate entries on Orphans.
11384bd44ebSJakob Stoklund Olesen   // Here the order is important - earlier subregs take precedence.
11484bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
11584bd44ebSJakob Stoklund Olesen     CodeGenRegister *SR = RegBank.getReg(SubList[i]);
116f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
11784bd44ebSJakob Stoklund Olesen     const SubRegMap &Map = SR->getSubRegs(RegBank);
118d2b4713eSJakob Stoklund Olesen 
119d2b4713eSJakob Stoklund Olesen     // Add this as a super-register of SR now all sub-registers are in the list.
120d2b4713eSJakob Stoklund Olesen     // This creates a topological ordering, the exact order depends on the
121d2b4713eSJakob Stoklund Olesen     // order getSubRegs is called on all registers.
122d2b4713eSJakob Stoklund Olesen     SR->SuperRegs.push_back(this);
123d2b4713eSJakob Stoklund Olesen 
12484bd44ebSJakob Stoklund Olesen     for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
125d2b4713eSJakob Stoklund Olesen          ++SI) {
12684bd44ebSJakob Stoklund Olesen       if (!SubRegs.insert(*SI).second)
127f1bb1519SJakob Stoklund Olesen         Orphans.push_back(Orphan(SI->second, Idx, SI->first));
128d2b4713eSJakob Stoklund Olesen 
129d2b4713eSJakob Stoklund Olesen       // Noop sub-register indexes are possible, so avoid duplicates.
130d2b4713eSJakob Stoklund Olesen       if (SI->second != SR)
131d2b4713eSJakob Stoklund Olesen         SI->second->SuperRegs.push_back(this);
132d2b4713eSJakob Stoklund Olesen     }
13384bd44ebSJakob Stoklund Olesen   }
13484bd44ebSJakob Stoklund Olesen 
13584bd44ebSJakob Stoklund Olesen   // Process the composites.
136af8ee2cdSDavid Greene   ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
13784bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
138af8ee2cdSDavid Greene     DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
13984bd44ebSJakob Stoklund Olesen     if (!Pat)
14084bd44ebSJakob Stoklund Olesen       throw TGError(TheDef->getLoc(), "Invalid dag '" +
14184bd44ebSJakob Stoklund Olesen                     Comps->getElement(i)->getAsString() +
14284bd44ebSJakob Stoklund Olesen                     "' in CompositeIndices");
143af8ee2cdSDavid Greene     DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
14484bd44ebSJakob Stoklund Olesen     if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
14584bd44ebSJakob Stoklund Olesen       throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
14684bd44ebSJakob Stoklund Olesen                     Pat->getAsString());
147f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef());
14884bd44ebSJakob Stoklund Olesen 
14984bd44ebSJakob Stoklund Olesen     // Resolve list of subreg indices into R2.
15084bd44ebSJakob Stoklund Olesen     CodeGenRegister *R2 = this;
15184bd44ebSJakob Stoklund Olesen     for (DagInit::const_arg_iterator di = Pat->arg_begin(),
15284bd44ebSJakob Stoklund Olesen          de = Pat->arg_end(); di != de; ++di) {
153af8ee2cdSDavid Greene       DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
15484bd44ebSJakob Stoklund Olesen       if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
15584bd44ebSJakob Stoklund Olesen         throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
15684bd44ebSJakob Stoklund Olesen                       Pat->getAsString());
157f1bb1519SJakob Stoklund Olesen       CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef());
15884bd44ebSJakob Stoklund Olesen       const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
159f1bb1519SJakob Stoklund Olesen       SubRegMap::const_iterator ni = R2Subs.find(Idx);
16084bd44ebSJakob Stoklund Olesen       if (ni == R2Subs.end())
16184bd44ebSJakob Stoklund Olesen         throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() +
16284bd44ebSJakob Stoklund Olesen                       " refers to bad index in " + R2->getName());
16384bd44ebSJakob Stoklund Olesen       R2 = ni->second;
16484bd44ebSJakob Stoklund Olesen     }
16584bd44ebSJakob Stoklund Olesen 
16684bd44ebSJakob Stoklund Olesen     // Insert composite index. Allow overriding inherited indices etc.
167f1bb1519SJakob Stoklund Olesen     SubRegs[BaseIdx] = R2;
16884bd44ebSJakob Stoklund Olesen 
16984bd44ebSJakob Stoklund Olesen     // R2 is no longer an orphan.
17084bd44ebSJakob Stoklund Olesen     for (unsigned j = 0, je = Orphans.size(); j != je; ++j)
17184bd44ebSJakob Stoklund Olesen       if (Orphans[j].SubReg == R2)
17284bd44ebSJakob Stoklund Olesen           Orphans[j].SubReg = 0;
17384bd44ebSJakob Stoklund Olesen   }
17484bd44ebSJakob Stoklund Olesen 
17584bd44ebSJakob Stoklund Olesen   // Now Orphans contains the inherited subregisters without a direct index.
17684bd44ebSJakob Stoklund Olesen   // Create inferred indexes for all missing entries.
17784bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Orphans.size(); i != e; ++i) {
17884bd44ebSJakob Stoklund Olesen     Orphan &O = Orphans[i];
17984bd44ebSJakob Stoklund Olesen     if (!O.SubReg)
18084bd44ebSJakob Stoklund Olesen       continue;
1819a44ad70SJakob Stoklund Olesen     SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second)] =
18284bd44ebSJakob Stoklund Olesen       O.SubReg;
18384bd44ebSJakob Stoklund Olesen   }
18484bd44ebSJakob Stoklund Olesen   return SubRegs;
18584bd44ebSJakob Stoklund Olesen }
18684bd44ebSJakob Stoklund Olesen 
187d2b4713eSJakob Stoklund Olesen void
188f1bb1519SJakob Stoklund Olesen CodeGenRegister::addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet,
189f1bb1519SJakob Stoklund Olesen                                     CodeGenRegBank &RegBank) const {
190d2b4713eSJakob Stoklund Olesen   assert(SubRegsComplete && "Must precompute sub-registers");
191d2b4713eSJakob Stoklund Olesen   std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
192d2b4713eSJakob Stoklund Olesen   for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
193f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
194f1bb1519SJakob Stoklund Olesen     CodeGenRegister *SR = SubRegs.find(Idx)->second;
195d2b4713eSJakob Stoklund Olesen     if (OSet.insert(SR))
196f1bb1519SJakob Stoklund Olesen       SR->addSubRegsPreOrder(OSet, RegBank);
197d2b4713eSJakob Stoklund Olesen   }
198d2b4713eSJakob Stoklund Olesen }
199d2b4713eSJakob Stoklund Olesen 
20068d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
2013bd1b65eSJakob Stoklund Olesen //                               RegisterTuples
2023bd1b65eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
2033bd1b65eSJakob Stoklund Olesen 
2043bd1b65eSJakob Stoklund Olesen // A RegisterTuples def is used to generate pseudo-registers from lists of
2053bd1b65eSJakob Stoklund Olesen // sub-registers. We provide a SetTheory expander class that returns the new
2063bd1b65eSJakob Stoklund Olesen // registers.
2073bd1b65eSJakob Stoklund Olesen namespace {
2083bd1b65eSJakob Stoklund Olesen struct TupleExpander : SetTheory::Expander {
2093bd1b65eSJakob Stoklund Olesen   void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) {
2103bd1b65eSJakob Stoklund Olesen     std::vector<Record*> Indices = Def->getValueAsListOfDefs("SubRegIndices");
2113bd1b65eSJakob Stoklund Olesen     unsigned Dim = Indices.size();
212af8ee2cdSDavid Greene     ListInit *SubRegs = Def->getValueAsListInit("SubRegs");
2133bd1b65eSJakob Stoklund Olesen     if (Dim != SubRegs->getSize())
2143bd1b65eSJakob Stoklund Olesen       throw TGError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch");
2153bd1b65eSJakob Stoklund Olesen     if (Dim < 2)
2163bd1b65eSJakob Stoklund Olesen       throw TGError(Def->getLoc(), "Tuples must have at least 2 sub-registers");
2173bd1b65eSJakob Stoklund Olesen 
2183bd1b65eSJakob Stoklund Olesen     // Evaluate the sub-register lists to be zipped.
2193bd1b65eSJakob Stoklund Olesen     unsigned Length = ~0u;
2203bd1b65eSJakob Stoklund Olesen     SmallVector<SetTheory::RecSet, 4> Lists(Dim);
2213bd1b65eSJakob Stoklund Olesen     for (unsigned i = 0; i != Dim; ++i) {
2223bd1b65eSJakob Stoklund Olesen       ST.evaluate(SubRegs->getElement(i), Lists[i]);
2233bd1b65eSJakob Stoklund Olesen       Length = std::min(Length, unsigned(Lists[i].size()));
2243bd1b65eSJakob Stoklund Olesen     }
2253bd1b65eSJakob Stoklund Olesen 
2263bd1b65eSJakob Stoklund Olesen     if (Length == 0)
2273bd1b65eSJakob Stoklund Olesen       return;
2283bd1b65eSJakob Stoklund Olesen 
2293bd1b65eSJakob Stoklund Olesen     // Precompute some types.
2303bd1b65eSJakob Stoklund Olesen     Record *RegisterCl = Def->getRecords().getClass("Register");
231abcfdceaSJakob Stoklund Olesen     RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl);
232af8ee2cdSDavid Greene     StringInit *BlankName = StringInit::get("");
2333bd1b65eSJakob Stoklund Olesen 
2343bd1b65eSJakob Stoklund Olesen     // Zip them up.
2353bd1b65eSJakob Stoklund Olesen     for (unsigned n = 0; n != Length; ++n) {
2363bd1b65eSJakob Stoklund Olesen       std::string Name;
2373bd1b65eSJakob Stoklund Olesen       Record *Proto = Lists[0][n];
238af8ee2cdSDavid Greene       std::vector<Init*> Tuple;
2393bd1b65eSJakob Stoklund Olesen       unsigned CostPerUse = 0;
2403bd1b65eSJakob Stoklund Olesen       for (unsigned i = 0; i != Dim; ++i) {
2413bd1b65eSJakob Stoklund Olesen         Record *Reg = Lists[i][n];
2423bd1b65eSJakob Stoklund Olesen         if (i) Name += '_';
2433bd1b65eSJakob Stoklund Olesen         Name += Reg->getName();
244abcfdceaSJakob Stoklund Olesen         Tuple.push_back(DefInit::get(Reg));
2453bd1b65eSJakob Stoklund Olesen         CostPerUse = std::max(CostPerUse,
2463bd1b65eSJakob Stoklund Olesen                               unsigned(Reg->getValueAsInt("CostPerUse")));
2473bd1b65eSJakob Stoklund Olesen       }
2483bd1b65eSJakob Stoklund Olesen 
2493bd1b65eSJakob Stoklund Olesen       // Create a new Record representing the synthesized register. This record
2503bd1b65eSJakob Stoklund Olesen       // is only for consumption by CodeGenRegister, it is not added to the
2513bd1b65eSJakob Stoklund Olesen       // RecordKeeper.
2523bd1b65eSJakob Stoklund Olesen       Record *NewReg = new Record(Name, Def->getLoc(), Def->getRecords());
2533bd1b65eSJakob Stoklund Olesen       Elts.insert(NewReg);
2543bd1b65eSJakob Stoklund Olesen 
2553bd1b65eSJakob Stoklund Olesen       // Copy Proto super-classes.
2563bd1b65eSJakob Stoklund Olesen       for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i)
2573bd1b65eSJakob Stoklund Olesen         NewReg->addSuperClass(Proto->getSuperClasses()[i]);
2583bd1b65eSJakob Stoklund Olesen 
2593bd1b65eSJakob Stoklund Olesen       // Copy Proto fields.
2603bd1b65eSJakob Stoklund Olesen       for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
2613bd1b65eSJakob Stoklund Olesen         RecordVal RV = Proto->getValues()[i];
2623bd1b65eSJakob Stoklund Olesen 
263f43b5995SJakob Stoklund Olesen         // Skip existing fields, like NAME.
264f43b5995SJakob Stoklund Olesen         if (NewReg->getValue(RV.getNameInit()))
265071c69cdSJakob Stoklund Olesen           continue;
266071c69cdSJakob Stoklund Olesen 
267f43b5995SJakob Stoklund Olesen         StringRef Field = RV.getName();
268f43b5995SJakob Stoklund Olesen 
2693bd1b65eSJakob Stoklund Olesen         // Replace the sub-register list with Tuple.
270f43b5995SJakob Stoklund Olesen         if (Field == "SubRegs")
271e32ebf22SDavid Greene           RV.setValue(ListInit::get(Tuple, RegisterRecTy));
2723bd1b65eSJakob Stoklund Olesen 
2733bd1b65eSJakob Stoklund Olesen         // Provide a blank AsmName. MC hacks are required anyway.
274f43b5995SJakob Stoklund Olesen         if (Field == "AsmName")
2753bd1b65eSJakob Stoklund Olesen           RV.setValue(BlankName);
2763bd1b65eSJakob Stoklund Olesen 
2773bd1b65eSJakob Stoklund Olesen         // CostPerUse is aggregated from all Tuple members.
278f43b5995SJakob Stoklund Olesen         if (Field == "CostPerUse")
279e32ebf22SDavid Greene           RV.setValue(IntInit::get(CostPerUse));
2803bd1b65eSJakob Stoklund Olesen 
281f43b5995SJakob Stoklund Olesen         // Composite registers are always covered by sub-registers.
282f43b5995SJakob Stoklund Olesen         if (Field == "CoveredBySubRegs")
283f43b5995SJakob Stoklund Olesen           RV.setValue(BitInit::get(true));
284f43b5995SJakob Stoklund Olesen 
2853bd1b65eSJakob Stoklund Olesen         // Copy fields from the RegisterTuples def.
286f43b5995SJakob Stoklund Olesen         if (Field == "SubRegIndices" ||
287f43b5995SJakob Stoklund Olesen             Field == "CompositeIndices") {
288f43b5995SJakob Stoklund Olesen           NewReg->addValue(*Def->getValue(Field));
2893bd1b65eSJakob Stoklund Olesen           continue;
2903bd1b65eSJakob Stoklund Olesen         }
2913bd1b65eSJakob Stoklund Olesen 
2923bd1b65eSJakob Stoklund Olesen         // Some fields get their default uninitialized value.
293f43b5995SJakob Stoklund Olesen         if (Field == "DwarfNumbers" ||
294f43b5995SJakob Stoklund Olesen             Field == "DwarfAlias" ||
295f43b5995SJakob Stoklund Olesen             Field == "Aliases") {
296f43b5995SJakob Stoklund Olesen           if (const RecordVal *DefRV = RegisterCl->getValue(Field))
297d9149a45SJakob Stoklund Olesen             NewReg->addValue(*DefRV);
2983bd1b65eSJakob Stoklund Olesen           continue;
2993bd1b65eSJakob Stoklund Olesen         }
3003bd1b65eSJakob Stoklund Olesen 
3013bd1b65eSJakob Stoklund Olesen         // Everything else is copied from Proto.
3023bd1b65eSJakob Stoklund Olesen         NewReg->addValue(RV);
3033bd1b65eSJakob Stoklund Olesen       }
3043bd1b65eSJakob Stoklund Olesen     }
3053bd1b65eSJakob Stoklund Olesen   }
3063bd1b65eSJakob Stoklund Olesen };
3073bd1b65eSJakob Stoklund Olesen }
3083bd1b65eSJakob Stoklund Olesen 
3093bd1b65eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
31068d6d8abSJakob Stoklund Olesen //                            CodeGenRegisterClass
31168d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
31268d6d8abSJakob Stoklund Olesen 
313d7bc5c26SJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
314bd92dc60SJakob Stoklund Olesen   : TheDef(R), Name(R->getName()), EnumValue(-1) {
31568d6d8abSJakob Stoklund Olesen   // Rename anonymous register classes.
31668d6d8abSJakob Stoklund Olesen   if (R->getName().size() > 9 && R->getName()[9] == '.') {
31768d6d8abSJakob Stoklund Olesen     static unsigned AnonCounter = 0;
31868d6d8abSJakob Stoklund Olesen     R->setName("AnonRegClass_"+utostr(AnonCounter++));
31968d6d8abSJakob Stoklund Olesen   }
32068d6d8abSJakob Stoklund Olesen 
32168d6d8abSJakob Stoklund Olesen   std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
32268d6d8abSJakob Stoklund Olesen   for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
32368d6d8abSJakob Stoklund Olesen     Record *Type = TypeList[i];
32468d6d8abSJakob Stoklund Olesen     if (!Type->isSubClassOf("ValueType"))
32568d6d8abSJakob Stoklund Olesen       throw "RegTypes list member '" + Type->getName() +
32668d6d8abSJakob Stoklund Olesen         "' does not derive from the ValueType class!";
32768d6d8abSJakob Stoklund Olesen     VTs.push_back(getValueType(Type));
32868d6d8abSJakob Stoklund Olesen   }
32968d6d8abSJakob Stoklund Olesen   assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");
33068d6d8abSJakob Stoklund Olesen 
331331534e5SJakob Stoklund Olesen   // Allocation order 0 is the full set. AltOrders provides others.
332331534e5SJakob Stoklund Olesen   const SetTheory::RecVec *Elements = RegBank.getSets().expand(R);
333331534e5SJakob Stoklund Olesen   ListInit *AltOrders = R->getValueAsListInit("AltOrders");
334331534e5SJakob Stoklund Olesen   Orders.resize(1 + AltOrders->size());
335331534e5SJakob Stoklund Olesen 
33635cea3daSJakob Stoklund Olesen   // Default allocation order always contains all registers.
337331534e5SJakob Stoklund Olesen   for (unsigned i = 0, e = Elements->size(); i != e; ++i) {
338331534e5SJakob Stoklund Olesen     Orders[0].push_back((*Elements)[i]);
3395ee87726SJakob Stoklund Olesen     Members.insert(RegBank.getReg((*Elements)[i]));
340331534e5SJakob Stoklund Olesen   }
34168d6d8abSJakob Stoklund Olesen 
34235cea3daSJakob Stoklund Olesen   // Alternative allocation orders may be subsets.
34335cea3daSJakob Stoklund Olesen   SetTheory::RecSet Order;
344331534e5SJakob Stoklund Olesen   for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) {
345331534e5SJakob Stoklund Olesen     RegBank.getSets().evaluate(AltOrders->getElement(i), Order);
346331534e5SJakob Stoklund Olesen     Orders[1 + i].append(Order.begin(), Order.end());
34735cea3daSJakob Stoklund Olesen     // Verify that all altorder members are regclass members.
34835cea3daSJakob Stoklund Olesen     while (!Order.empty()) {
34935cea3daSJakob Stoklund Olesen       CodeGenRegister *Reg = RegBank.getReg(Order.back());
35035cea3daSJakob Stoklund Olesen       Order.pop_back();
35135cea3daSJakob Stoklund Olesen       if (!contains(Reg))
35235cea3daSJakob Stoklund Olesen         throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() +
35335cea3daSJakob Stoklund Olesen                       " is not a class member");
35435cea3daSJakob Stoklund Olesen     }
35535cea3daSJakob Stoklund Olesen   }
35635cea3daSJakob Stoklund Olesen 
35768d6d8abSJakob Stoklund Olesen   // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
358af8ee2cdSDavid Greene   ListInit *SRC = R->getValueAsListInit("SubRegClasses");
35968d6d8abSJakob Stoklund Olesen   for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
360af8ee2cdSDavid Greene     DagInit *DAG = dynamic_cast<DagInit*>(*i);
36168d6d8abSJakob Stoklund Olesen     if (!DAG) throw "SubRegClasses must contain DAGs";
362af8ee2cdSDavid Greene     DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
36368d6d8abSJakob Stoklund Olesen     Record *RCRec;
36468d6d8abSJakob Stoklund Olesen     if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass"))
36568d6d8abSJakob Stoklund Olesen       throw "Operator '" + DAG->getOperator()->getAsString() +
36668d6d8abSJakob Stoklund Olesen         "' in SubRegClasses is not a RegisterClass";
36768d6d8abSJakob Stoklund Olesen     // Iterate over args, all SubRegIndex instances.
36868d6d8abSJakob Stoklund Olesen     for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end();
36968d6d8abSJakob Stoklund Olesen          ai != ae; ++ai) {
370af8ee2cdSDavid Greene       DefInit *Idx = dynamic_cast<DefInit*>(*ai);
37168d6d8abSJakob Stoklund Olesen       Record *IdxRec;
37268d6d8abSJakob Stoklund Olesen       if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex"))
37368d6d8abSJakob Stoklund Olesen         throw "Argument '" + (*ai)->getAsString() +
37468d6d8abSJakob Stoklund Olesen           "' in SubRegClasses is not a SubRegIndex";
37568d6d8abSJakob Stoklund Olesen       if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second)
37668d6d8abSJakob Stoklund Olesen         throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice";
37768d6d8abSJakob Stoklund Olesen     }
37868d6d8abSJakob Stoklund Olesen   }
37968d6d8abSJakob Stoklund Olesen 
38068d6d8abSJakob Stoklund Olesen   // Allow targets to override the size in bits of the RegisterClass.
38168d6d8abSJakob Stoklund Olesen   unsigned Size = R->getValueAsInt("Size");
38268d6d8abSJakob Stoklund Olesen 
38368d6d8abSJakob Stoklund Olesen   Namespace = R->getValueAsString("Namespace");
38468d6d8abSJakob Stoklund Olesen   SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
38568d6d8abSJakob Stoklund Olesen   SpillAlignment = R->getValueAsInt("Alignment");
38668d6d8abSJakob Stoklund Olesen   CopyCost = R->getValueAsInt("CopyCost");
38768d6d8abSJakob Stoklund Olesen   Allocatable = R->getValueAsBit("isAllocatable");
388dd8fbf57SJakob Stoklund Olesen   AltOrderSelect = R->getValueAsString("AltOrderSelect");
38968d6d8abSJakob Stoklund Olesen }
39068d6d8abSJakob Stoklund Olesen 
39103efe84dSJakob Stoklund Olesen // Create an inferred register class that was missing from the .td files.
39203efe84dSJakob Stoklund Olesen // Most properties will be inherited from the closest super-class after the
39303efe84dSJakob Stoklund Olesen // class structure has been computed.
39403efe84dSJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(StringRef Name, Key Props)
39503efe84dSJakob Stoklund Olesen   : Members(*Props.Members),
39603efe84dSJakob Stoklund Olesen     TheDef(0),
39703efe84dSJakob Stoklund Olesen     Name(Name),
39803efe84dSJakob Stoklund Olesen     EnumValue(-1),
39903efe84dSJakob Stoklund Olesen     SpillSize(Props.SpillSize),
40003efe84dSJakob Stoklund Olesen     SpillAlignment(Props.SpillAlignment),
40103efe84dSJakob Stoklund Olesen     CopyCost(0),
40203efe84dSJakob Stoklund Olesen     Allocatable(true) {
40303efe84dSJakob Stoklund Olesen }
40403efe84dSJakob Stoklund Olesen 
40503efe84dSJakob Stoklund Olesen // Compute inherited propertied for a synthesized register class.
40603efe84dSJakob Stoklund Olesen void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
40703efe84dSJakob Stoklund Olesen   assert(!getDef() && "Only synthesized classes can inherit properties");
40803efe84dSJakob Stoklund Olesen   assert(!SuperClasses.empty() && "Synthesized class without super class");
40903efe84dSJakob Stoklund Olesen 
41003efe84dSJakob Stoklund Olesen   // The last super-class is the smallest one.
41103efe84dSJakob Stoklund Olesen   CodeGenRegisterClass &Super = *SuperClasses.back();
41203efe84dSJakob Stoklund Olesen 
41303efe84dSJakob Stoklund Olesen   // Most properties are copied directly.
41403efe84dSJakob Stoklund Olesen   // Exceptions are members, size, and alignment
41503efe84dSJakob Stoklund Olesen   Namespace = Super.Namespace;
41603efe84dSJakob Stoklund Olesen   VTs = Super.VTs;
41703efe84dSJakob Stoklund Olesen   CopyCost = Super.CopyCost;
41803efe84dSJakob Stoklund Olesen   Allocatable = Super.Allocatable;
41903efe84dSJakob Stoklund Olesen   AltOrderSelect = Super.AltOrderSelect;
42003efe84dSJakob Stoklund Olesen 
42103efe84dSJakob Stoklund Olesen   // Copy all allocation orders, filter out foreign registers from the larger
42203efe84dSJakob Stoklund Olesen   // super-class.
42303efe84dSJakob Stoklund Olesen   Orders.resize(Super.Orders.size());
42403efe84dSJakob Stoklund Olesen   for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i)
42503efe84dSJakob Stoklund Olesen     for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j)
42603efe84dSJakob Stoklund Olesen       if (contains(RegBank.getReg(Super.Orders[i][j])))
42703efe84dSJakob Stoklund Olesen         Orders[i].push_back(Super.Orders[i][j]);
42803efe84dSJakob Stoklund Olesen }
42903efe84dSJakob Stoklund Olesen 
430d7bc5c26SJakob Stoklund Olesen bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
431d7bc5c26SJakob Stoklund Olesen   return Members.count(Reg);
432d7bc5c26SJakob Stoklund Olesen }
433d7bc5c26SJakob Stoklund Olesen 
43403efe84dSJakob Stoklund Olesen namespace llvm {
43503efe84dSJakob Stoklund Olesen   raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) {
43603efe84dSJakob Stoklund Olesen     OS << "{ S=" << K.SpillSize << ", A=" << K.SpillAlignment;
43703efe84dSJakob Stoklund Olesen     for (CodeGenRegister::Set::const_iterator I = K.Members->begin(),
43803efe84dSJakob Stoklund Olesen          E = K.Members->end(); I != E; ++I)
43903efe84dSJakob Stoklund Olesen       OS << ", " << (*I)->getName();
44003efe84dSJakob Stoklund Olesen     return OS << " }";
44103efe84dSJakob Stoklund Olesen   }
44203efe84dSJakob Stoklund Olesen }
44303efe84dSJakob Stoklund Olesen 
44403efe84dSJakob Stoklund Olesen // This is a simple lexicographical order that can be used to search for sets.
44503efe84dSJakob Stoklund Olesen // It is not the same as the topological order provided by TopoOrderRC.
44603efe84dSJakob Stoklund Olesen bool CodeGenRegisterClass::Key::
44703efe84dSJakob Stoklund Olesen operator<(const CodeGenRegisterClass::Key &B) const {
44803efe84dSJakob Stoklund Olesen   assert(Members && B.Members);
44903efe84dSJakob Stoklund Olesen   if (*Members != *B.Members)
45003efe84dSJakob Stoklund Olesen     return *Members < *B.Members;
45103efe84dSJakob Stoklund Olesen   if (SpillSize != B.SpillSize)
45203efe84dSJakob Stoklund Olesen     return SpillSize < B.SpillSize;
45303efe84dSJakob Stoklund Olesen   return SpillAlignment < B.SpillAlignment;
45403efe84dSJakob Stoklund Olesen }
45503efe84dSJakob Stoklund Olesen 
456d7bc5c26SJakob Stoklund Olesen // Returns true if RC is a strict subclass.
457d7bc5c26SJakob Stoklund Olesen // RC is a sub-class of this class if it is a valid replacement for any
458d7bc5c26SJakob Stoklund Olesen // instruction operand where a register of this classis required. It must
459d7bc5c26SJakob Stoklund Olesen // satisfy these conditions:
460d7bc5c26SJakob Stoklund Olesen //
461d7bc5c26SJakob Stoklund Olesen // 1. All RC registers are also in this.
462d7bc5c26SJakob Stoklund Olesen // 2. The RC spill size must not be smaller than our spill size.
463d7bc5c26SJakob Stoklund Olesen // 3. RC spill alignment must be compatible with ours.
464d7bc5c26SJakob Stoklund Olesen //
4656417395dSJakob Stoklund Olesen static bool testSubClass(const CodeGenRegisterClass *A,
4666417395dSJakob Stoklund Olesen                          const CodeGenRegisterClass *B) {
4676417395dSJakob Stoklund Olesen   return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 &&
4686417395dSJakob Stoklund Olesen     A->SpillSize <= B->SpillSize &&
4696417395dSJakob Stoklund Olesen     std::includes(A->getMembers().begin(), A->getMembers().end(),
4706417395dSJakob Stoklund Olesen                   B->getMembers().begin(), B->getMembers().end(),
471afef4222SJakob Stoklund Olesen                   CodeGenRegister::Less());
472d7bc5c26SJakob Stoklund Olesen }
473d7bc5c26SJakob Stoklund Olesen 
474c0fc173dSJakob Stoklund Olesen /// Sorting predicate for register classes.  This provides a topological
475c0fc173dSJakob Stoklund Olesen /// ordering that arranges all register classes before their sub-classes.
476c0fc173dSJakob Stoklund Olesen ///
477c0fc173dSJakob Stoklund Olesen /// Register classes with the same registers, spill size, and alignment form a
478c0fc173dSJakob Stoklund Olesen /// clique.  They will be ordered alphabetically.
479c0fc173dSJakob Stoklund Olesen ///
480c0fc173dSJakob Stoklund Olesen static int TopoOrderRC(const void *PA, const void *PB) {
481c0fc173dSJakob Stoklund Olesen   const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA;
482c0fc173dSJakob Stoklund Olesen   const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB;
483c0fc173dSJakob Stoklund Olesen   if (A == B)
484c0fc173dSJakob Stoklund Olesen     return 0;
485c0fc173dSJakob Stoklund Olesen 
48603efe84dSJakob Stoklund Olesen   // Order by descending set size.  Note that the classes' allocation order may
48703efe84dSJakob Stoklund Olesen   // not have been computed yet.  The Members set is always vaild.
48803efe84dSJakob Stoklund Olesen   if (A->getMembers().size() > B->getMembers().size())
489c0fc173dSJakob Stoklund Olesen     return -1;
49003efe84dSJakob Stoklund Olesen   if (A->getMembers().size() < B->getMembers().size())
491c0fc173dSJakob Stoklund Olesen     return 1;
492c0fc173dSJakob Stoklund Olesen 
493c0fc173dSJakob Stoklund Olesen   // Order by ascending spill size.
494c0fc173dSJakob Stoklund Olesen   if (A->SpillSize < B->SpillSize)
495c0fc173dSJakob Stoklund Olesen     return -1;
496c0fc173dSJakob Stoklund Olesen   if (A->SpillSize > B->SpillSize)
497c0fc173dSJakob Stoklund Olesen     return 1;
498c0fc173dSJakob Stoklund Olesen 
499c0fc173dSJakob Stoklund Olesen   // Order by ascending spill alignment.
500c0fc173dSJakob Stoklund Olesen   if (A->SpillAlignment < B->SpillAlignment)
501c0fc173dSJakob Stoklund Olesen     return -1;
502c0fc173dSJakob Stoklund Olesen   if (A->SpillAlignment > B->SpillAlignment)
503c0fc173dSJakob Stoklund Olesen     return 1;
504c0fc173dSJakob Stoklund Olesen 
505c0fc173dSJakob Stoklund Olesen   // Finally order by name as a tie breaker.
506*fff0dfd8SJakob Stoklund Olesen   return StringRef(A->getName()).compare(B->getName());
507c0fc173dSJakob Stoklund Olesen }
508c0fc173dSJakob Stoklund Olesen 
509bd92dc60SJakob Stoklund Olesen std::string CodeGenRegisterClass::getQualifiedName() const {
510bd92dc60SJakob Stoklund Olesen   if (Namespace.empty())
511bd92dc60SJakob Stoklund Olesen     return getName();
512bd92dc60SJakob Stoklund Olesen   else
513bd92dc60SJakob Stoklund Olesen     return Namespace + "::" + getName();
51468d6d8abSJakob Stoklund Olesen }
51568d6d8abSJakob Stoklund Olesen 
5162c024b2dSJakob Stoklund Olesen // Compute sub-classes of all register classes.
5172c024b2dSJakob Stoklund Olesen // Assume the classes are ordered topologically.
51803efe84dSJakob Stoklund Olesen void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
51903efe84dSJakob Stoklund Olesen   ArrayRef<CodeGenRegisterClass*> RegClasses = RegBank.getRegClasses();
52003efe84dSJakob Stoklund Olesen 
5212c024b2dSJakob Stoklund Olesen   // Visit backwards so sub-classes are seen first.
5222c024b2dSJakob Stoklund Olesen   for (unsigned rci = RegClasses.size(); rci; --rci) {
5232c024b2dSJakob Stoklund Olesen     CodeGenRegisterClass &RC = *RegClasses[rci - 1];
5242c024b2dSJakob Stoklund Olesen     RC.SubClasses.resize(RegClasses.size());
5252c024b2dSJakob Stoklund Olesen     RC.SubClasses.set(RC.EnumValue);
5262c024b2dSJakob Stoklund Olesen 
5272c024b2dSJakob Stoklund Olesen     // Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
5282c024b2dSJakob Stoklund Olesen     for (unsigned s = rci; s != RegClasses.size(); ++s) {
5292c024b2dSJakob Stoklund Olesen       if (RC.SubClasses.test(s))
5302c024b2dSJakob Stoklund Olesen         continue;
5312c024b2dSJakob Stoklund Olesen       CodeGenRegisterClass *SubRC = RegClasses[s];
5326417395dSJakob Stoklund Olesen       if (!testSubClass(&RC, SubRC))
5332c024b2dSJakob Stoklund Olesen         continue;
5342c024b2dSJakob Stoklund Olesen       // SubRC is a sub-class. Grap all its sub-classes so we won't have to
5352c024b2dSJakob Stoklund Olesen       // check them again.
5362c024b2dSJakob Stoklund Olesen       RC.SubClasses |= SubRC->SubClasses;
5372c024b2dSJakob Stoklund Olesen     }
5382c024b2dSJakob Stoklund Olesen 
5392c024b2dSJakob Stoklund Olesen     // Sweep up missed clique members.  They will be immediately preceeding RC.
5406417395dSJakob Stoklund Olesen     for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s)
5412c024b2dSJakob Stoklund Olesen       RC.SubClasses.set(s - 1);
5422c024b2dSJakob Stoklund Olesen   }
543b15fad9dSJakob Stoklund Olesen 
544b15fad9dSJakob Stoklund Olesen   // Compute the SuperClasses lists from the SubClasses vectors.
545b15fad9dSJakob Stoklund Olesen   for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
546b15fad9dSJakob Stoklund Olesen     const BitVector &SC = RegClasses[rci]->getSubClasses();
547b15fad9dSJakob Stoklund Olesen     for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) {
548b15fad9dSJakob Stoklund Olesen       if (unsigned(s) == rci)
549b15fad9dSJakob Stoklund Olesen         continue;
550b15fad9dSJakob Stoklund Olesen       RegClasses[s]->SuperClasses.push_back(RegClasses[rci]);
551b15fad9dSJakob Stoklund Olesen     }
552b15fad9dSJakob Stoklund Olesen   }
55303efe84dSJakob Stoklund Olesen 
55403efe84dSJakob Stoklund Olesen   // With the class hierarchy in place, let synthesized register classes inherit
55503efe84dSJakob Stoklund Olesen   // properties from their closest super-class. The iteration order here can
55603efe84dSJakob Stoklund Olesen   // propagate properties down multiple levels.
55703efe84dSJakob Stoklund Olesen   for (unsigned rci = 0; rci != RegClasses.size(); ++rci)
55803efe84dSJakob Stoklund Olesen     if (!RegClasses[rci]->getDef())
55903efe84dSJakob Stoklund Olesen       RegClasses[rci]->inheritProperties(RegBank);
5602c024b2dSJakob Stoklund Olesen }
5612c024b2dSJakob Stoklund Olesen 
562c7b437aeSJakob Stoklund Olesen void
563f1bb1519SJakob Stoklund Olesen CodeGenRegisterClass::getSuperRegClasses(CodeGenSubRegIndex *SubIdx,
564f1bb1519SJakob Stoklund Olesen                                          BitVector &Out) const {
565f1bb1519SJakob Stoklund Olesen   DenseMap<CodeGenSubRegIndex*,
566f1bb1519SJakob Stoklund Olesen            SmallPtrSet<CodeGenRegisterClass*, 8> >::const_iterator
567c7b437aeSJakob Stoklund Olesen     FindI = SuperRegClasses.find(SubIdx);
568c7b437aeSJakob Stoklund Olesen   if (FindI == SuperRegClasses.end())
569c7b437aeSJakob Stoklund Olesen     return;
570c7b437aeSJakob Stoklund Olesen   for (SmallPtrSet<CodeGenRegisterClass*, 8>::const_iterator I =
571c7b437aeSJakob Stoklund Olesen        FindI->second.begin(), E = FindI->second.end(); I != E; ++I)
572c7b437aeSJakob Stoklund Olesen     Out.set((*I)->EnumValue);
573c7b437aeSJakob Stoklund Olesen }
574c7b437aeSJakob Stoklund Olesen 
575c7b437aeSJakob Stoklund Olesen 
57676a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
57776a5a71eSJakob Stoklund Olesen //                               CodeGenRegBank
57876a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===//
57976a5a71eSJakob Stoklund Olesen 
58076a5a71eSJakob Stoklund Olesen CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
5813bd1b65eSJakob Stoklund Olesen   // Configure register Sets to understand register classes and tuples.
5825ee87726SJakob Stoklund Olesen   Sets.addFieldExpander("RegisterClass", "MemberList");
583c3abb0f6SJakob Stoklund Olesen   Sets.addFieldExpander("CalleeSavedRegs", "SaveList");
5843bd1b65eSJakob Stoklund Olesen   Sets.addExpander("RegisterTuples", new TupleExpander());
5855ee87726SJakob Stoklund Olesen 
58684bd44ebSJakob Stoklund Olesen   // Read in the user-defined (named) sub-register indices.
58784bd44ebSJakob Stoklund Olesen   // More indices will be synthesized later.
588f1bb1519SJakob Stoklund Olesen   std::vector<Record*> SRIs = Records.getAllDerivedDefinitions("SubRegIndex");
589f1bb1519SJakob Stoklund Olesen   std::sort(SRIs.begin(), SRIs.end(), LessRecord());
590f1bb1519SJakob Stoklund Olesen   NumNamedIndices = SRIs.size();
591f1bb1519SJakob Stoklund Olesen   for (unsigned i = 0, e = SRIs.size(); i != e; ++i)
592f1bb1519SJakob Stoklund Olesen     getSubRegIdx(SRIs[i]);
59384bd44ebSJakob Stoklund Olesen 
59484bd44ebSJakob Stoklund Olesen   // Read in the register definitions.
59584bd44ebSJakob Stoklund Olesen   std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");
59684bd44ebSJakob Stoklund Olesen   std::sort(Regs.begin(), Regs.end(), LessRecord());
59784bd44ebSJakob Stoklund Olesen   Registers.reserve(Regs.size());
59884bd44ebSJakob Stoklund Olesen   // Assign the enumeration values.
59984bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Regs.size(); i != e; ++i)
6008e188be0SJakob Stoklund Olesen     getReg(Regs[i]);
60122ea424dSJakob Stoklund Olesen 
6023bd1b65eSJakob Stoklund Olesen   // Expand tuples and number the new registers.
6033bd1b65eSJakob Stoklund Olesen   std::vector<Record*> Tups =
6043bd1b65eSJakob Stoklund Olesen     Records.getAllDerivedDefinitions("RegisterTuples");
6053bd1b65eSJakob Stoklund Olesen   for (unsigned i = 0, e = Tups.size(); i != e; ++i) {
6063bd1b65eSJakob Stoklund Olesen     const std::vector<Record*> *TupRegs = Sets.expand(Tups[i]);
6073bd1b65eSJakob Stoklund Olesen     for (unsigned j = 0, je = TupRegs->size(); j != je; ++j)
6083bd1b65eSJakob Stoklund Olesen       getReg((*TupRegs)[j]);
6093bd1b65eSJakob Stoklund Olesen   }
6103bd1b65eSJakob Stoklund Olesen 
61103efe84dSJakob Stoklund Olesen   // Precompute all sub-register maps now all the registers are known.
61203efe84dSJakob Stoklund Olesen   // This will create Composite entries for all inferred sub-register indices.
61303efe84dSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i)
61403efe84dSJakob Stoklund Olesen     Registers[i]->getSubRegs(*this);
61503efe84dSJakob Stoklund Olesen 
61622ea424dSJakob Stoklund Olesen   // Read in register class definitions.
61722ea424dSJakob Stoklund Olesen   std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass");
61822ea424dSJakob Stoklund Olesen   if (RCs.empty())
61922ea424dSJakob Stoklund Olesen     throw std::string("No 'RegisterClass' subclasses defined!");
62022ea424dSJakob Stoklund Olesen 
62103efe84dSJakob Stoklund Olesen   // Allocate user-defined register classes.
62222ea424dSJakob Stoklund Olesen   RegClasses.reserve(RCs.size());
62303efe84dSJakob Stoklund Olesen   for (unsigned i = 0, e = RCs.size(); i != e; ++i)
62403efe84dSJakob Stoklund Olesen     addToMaps(new CodeGenRegisterClass(*this, RCs[i]));
62503efe84dSJakob Stoklund Olesen 
62603efe84dSJakob Stoklund Olesen   // Infer missing classes to create a full algebra.
62703efe84dSJakob Stoklund Olesen   computeInferredRegisterClasses();
62803efe84dSJakob Stoklund Olesen 
629c0fc173dSJakob Stoklund Olesen   // Order register classes topologically and assign enum values.
630c0fc173dSJakob Stoklund Olesen   array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC);
631c0fc173dSJakob Stoklund Olesen   for (unsigned i = 0, e = RegClasses.size(); i != e; ++i)
632c0fc173dSJakob Stoklund Olesen     RegClasses[i]->EnumValue = i;
63303efe84dSJakob Stoklund Olesen   CodeGenRegisterClass::computeSubClasses(*this);
63476a5a71eSJakob Stoklund Olesen }
63576a5a71eSJakob Stoklund Olesen 
636f1bb1519SJakob Stoklund Olesen CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) {
637f1bb1519SJakob Stoklund Olesen   CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def];
638f1bb1519SJakob Stoklund Olesen   if (Idx)
639f1bb1519SJakob Stoklund Olesen     return Idx;
640f1bb1519SJakob Stoklund Olesen   Idx = new CodeGenSubRegIndex(Def, SubRegIndices.size() + 1);
641f1bb1519SJakob Stoklund Olesen   SubRegIndices.push_back(Idx);
642f1bb1519SJakob Stoklund Olesen   return Idx;
643f1bb1519SJakob Stoklund Olesen }
644f1bb1519SJakob Stoklund Olesen 
64584bd44ebSJakob Stoklund Olesen CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
6468e188be0SJakob Stoklund Olesen   CodeGenRegister *&Reg = Def2Reg[Def];
6478e188be0SJakob Stoklund Olesen   if (Reg)
64884bd44ebSJakob Stoklund Olesen     return Reg;
6498e188be0SJakob Stoklund Olesen   Reg = new CodeGenRegister(Def, Registers.size() + 1);
6508e188be0SJakob Stoklund Olesen   Registers.push_back(Reg);
6518e188be0SJakob Stoklund Olesen   return Reg;
65284bd44ebSJakob Stoklund Olesen }
65384bd44ebSJakob Stoklund Olesen 
65403efe84dSJakob Stoklund Olesen void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) {
65503efe84dSJakob Stoklund Olesen   RegClasses.push_back(RC);
65603efe84dSJakob Stoklund Olesen 
65703efe84dSJakob Stoklund Olesen   if (Record *Def = RC->getDef())
65803efe84dSJakob Stoklund Olesen     Def2RC.insert(std::make_pair(Def, RC));
65903efe84dSJakob Stoklund Olesen 
66003efe84dSJakob Stoklund Olesen   // Duplicate classes are rejected by insert().
66103efe84dSJakob Stoklund Olesen   // That's OK, we only care about the properties handled by CGRC::Key.
66203efe84dSJakob Stoklund Olesen   CodeGenRegisterClass::Key K(*RC);
66303efe84dSJakob Stoklund Olesen   Key2RC.insert(std::make_pair(K, RC));
66403efe84dSJakob Stoklund Olesen }
66503efe84dSJakob Stoklund Olesen 
6667ebc6b05SJakob Stoklund Olesen // Create a synthetic sub-class if it is missing.
6677ebc6b05SJakob Stoklund Olesen CodeGenRegisterClass*
6687ebc6b05SJakob Stoklund Olesen CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
6697ebc6b05SJakob Stoklund Olesen                                     const CodeGenRegister::Set *Members,
6707ebc6b05SJakob Stoklund Olesen                                     StringRef Name) {
6717ebc6b05SJakob Stoklund Olesen   // Synthetic sub-class has the same size and alignment as RC.
6727ebc6b05SJakob Stoklund Olesen   CodeGenRegisterClass::Key K(Members, RC->SpillSize, RC->SpillAlignment);
6737ebc6b05SJakob Stoklund Olesen   RCKeyMap::const_iterator FoundI = Key2RC.find(K);
6747ebc6b05SJakob Stoklund Olesen   if (FoundI != Key2RC.end())
6757ebc6b05SJakob Stoklund Olesen     return FoundI->second;
6767ebc6b05SJakob Stoklund Olesen 
6777ebc6b05SJakob Stoklund Olesen   // Sub-class doesn't exist, create a new one.
6787ebc6b05SJakob Stoklund Olesen   CodeGenRegisterClass *NewRC = new CodeGenRegisterClass(Name, K);
6797ebc6b05SJakob Stoklund Olesen   addToMaps(NewRC);
6807ebc6b05SJakob Stoklund Olesen   return NewRC;
6817ebc6b05SJakob Stoklund Olesen }
6827ebc6b05SJakob Stoklund Olesen 
68322ea424dSJakob Stoklund Olesen CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) {
68422ea424dSJakob Stoklund Olesen   if (CodeGenRegisterClass *RC = Def2RC[Def])
68522ea424dSJakob Stoklund Olesen     return RC;
68622ea424dSJakob Stoklund Olesen 
68722ea424dSJakob Stoklund Olesen   throw TGError(Def->getLoc(), "Not a known RegisterClass!");
68822ea424dSJakob Stoklund Olesen }
68922ea424dSJakob Stoklund Olesen 
690f1bb1519SJakob Stoklund Olesen CodeGenSubRegIndex*
691f1bb1519SJakob Stoklund Olesen CodeGenRegBank::getCompositeSubRegIndex(CodeGenSubRegIndex *A,
6929a44ad70SJakob Stoklund Olesen                                         CodeGenSubRegIndex *B) {
69384bd44ebSJakob Stoklund Olesen   // Look for an existing entry.
6949a44ad70SJakob Stoklund Olesen   CodeGenSubRegIndex *Comp = A->compose(B);
6959a44ad70SJakob Stoklund Olesen   if (Comp)
69684bd44ebSJakob Stoklund Olesen     return Comp;
69784bd44ebSJakob Stoklund Olesen 
69884bd44ebSJakob Stoklund Olesen   // None exists, synthesize one.
69976a5a71eSJakob Stoklund Olesen   std::string Name = A->getName() + "_then_" + B->getName();
700f1bb1519SJakob Stoklund Olesen   Comp = getSubRegIdx(new Record(Name, SMLoc(), Records));
7019a44ad70SJakob Stoklund Olesen   A->addComposite(B, Comp);
70284bd44ebSJakob Stoklund Olesen   return Comp;
70376a5a71eSJakob Stoklund Olesen }
70476a5a71eSJakob Stoklund Olesen 
70584bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeComposites() {
70684bd44ebSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
7078e188be0SJakob Stoklund Olesen     CodeGenRegister *Reg1 = Registers[i];
708d2b4713eSJakob Stoklund Olesen     const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs();
70984bd44ebSJakob Stoklund Olesen     for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(),
71084bd44ebSJakob Stoklund Olesen          e1 = SRM1.end(); i1 != e1; ++i1) {
711f1bb1519SJakob Stoklund Olesen       CodeGenSubRegIndex *Idx1 = i1->first;
71284bd44ebSJakob Stoklund Olesen       CodeGenRegister *Reg2 = i1->second;
71384bd44ebSJakob Stoklund Olesen       // Ignore identity compositions.
71484bd44ebSJakob Stoklund Olesen       if (Reg1 == Reg2)
71584bd44ebSJakob Stoklund Olesen         continue;
716d2b4713eSJakob Stoklund Olesen       const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs();
71784bd44ebSJakob Stoklund Olesen       // Try composing Idx1 with another SubRegIndex.
71884bd44ebSJakob Stoklund Olesen       for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM2.begin(),
71984bd44ebSJakob Stoklund Olesen            e2 = SRM2.end(); i2 != e2; ++i2) {
7209a44ad70SJakob Stoklund Olesen       CodeGenSubRegIndex *Idx2 = i2->first;
72184bd44ebSJakob Stoklund Olesen         CodeGenRegister *Reg3 = i2->second;
72284bd44ebSJakob Stoklund Olesen         // Ignore identity compositions.
72384bd44ebSJakob Stoklund Olesen         if (Reg2 == Reg3)
72484bd44ebSJakob Stoklund Olesen           continue;
72584bd44ebSJakob Stoklund Olesen         // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3.
72684bd44ebSJakob Stoklund Olesen         for (CodeGenRegister::SubRegMap::const_iterator i1d = SRM1.begin(),
72784bd44ebSJakob Stoklund Olesen              e1d = SRM1.end(); i1d != e1d; ++i1d) {
72884bd44ebSJakob Stoklund Olesen           if (i1d->second == Reg3) {
72984bd44ebSJakob Stoklund Olesen             // Conflicting composition? Emit a warning but allow it.
7309a44ad70SJakob Stoklund Olesen             if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, i1d->first))
731f1bb1519SJakob Stoklund Olesen               errs() << "Warning: SubRegIndex " << Idx1->getQualifiedName()
7329a44ad70SJakob Stoklund Olesen                      << " and " << Idx2->getQualifiedName()
73384bd44ebSJakob Stoklund Olesen                      << " compose ambiguously as "
7349a44ad70SJakob Stoklund Olesen                      << Prev->getQualifiedName() << " or "
735f1bb1519SJakob Stoklund Olesen                      << i1d->first->getQualifiedName() << "\n";
73684bd44ebSJakob Stoklund Olesen           }
73784bd44ebSJakob Stoklund Olesen         }
73884bd44ebSJakob Stoklund Olesen       }
73984bd44ebSJakob Stoklund Olesen     }
74084bd44ebSJakob Stoklund Olesen   }
74184bd44ebSJakob Stoklund Olesen 
74284bd44ebSJakob Stoklund Olesen   // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid
74384bd44ebSJakob Stoklund Olesen   // compositions, so remove any mappings of that form.
7449a44ad70SJakob Stoklund Olesen   for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
7459a44ad70SJakob Stoklund Olesen     SubRegIndices[i]->cleanComposites();
74684bd44ebSJakob Stoklund Olesen }
74784bd44ebSJakob Stoklund Olesen 
748d2b4713eSJakob Stoklund Olesen // Compute sets of overlapping registers.
749d2b4713eSJakob Stoklund Olesen //
750d2b4713eSJakob Stoklund Olesen // The standard set is all super-registers and all sub-registers, but the
751d2b4713eSJakob Stoklund Olesen // target description can add arbitrary overlapping registers via the 'Aliases'
752d2b4713eSJakob Stoklund Olesen // field. This complicates things, but we can compute overlapping sets using
753d2b4713eSJakob Stoklund Olesen // the following rules:
754d2b4713eSJakob Stoklund Olesen //
755d2b4713eSJakob Stoklund Olesen // 1. The relation overlap(A, B) is reflexive and symmetric but not transitive.
756d2b4713eSJakob Stoklund Olesen //
757d2b4713eSJakob Stoklund Olesen // 2. overlap(A, B) implies overlap(A, S) for all S in supers(B).
758d2b4713eSJakob Stoklund Olesen //
759d2b4713eSJakob Stoklund Olesen // Alternatively:
760d2b4713eSJakob Stoklund Olesen //
761d2b4713eSJakob Stoklund Olesen //    overlap(A, B) iff there exists:
762d2b4713eSJakob Stoklund Olesen //    A' in { A, subregs(A) } and B' in { B, subregs(B) } such that:
763d2b4713eSJakob Stoklund Olesen //    A' = B' or A' in aliases(B') or B' in aliases(A').
764d2b4713eSJakob Stoklund Olesen //
765d2b4713eSJakob Stoklund Olesen // Here subregs(A) is the full flattened sub-register set returned by
766d2b4713eSJakob Stoklund Olesen // A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the
767d2b4713eSJakob Stoklund Olesen // description of register A.
768d2b4713eSJakob Stoklund Olesen //
769d2b4713eSJakob Stoklund Olesen // This also implies that registers with a common sub-register are considered
770d2b4713eSJakob Stoklund Olesen // overlapping. This can happen when forming register pairs:
771d2b4713eSJakob Stoklund Olesen //
772d2b4713eSJakob Stoklund Olesen //    P0 = (R0, R1)
773d2b4713eSJakob Stoklund Olesen //    P1 = (R1, R2)
774d2b4713eSJakob Stoklund Olesen //    P2 = (R2, R3)
775d2b4713eSJakob Stoklund Olesen //
776d2b4713eSJakob Stoklund Olesen // In this case, we will infer an overlap between P0 and P1 because of the
777d2b4713eSJakob Stoklund Olesen // shared sub-register R1. There is no overlap between P0 and P2.
778d2b4713eSJakob Stoklund Olesen //
779d2b4713eSJakob Stoklund Olesen void CodeGenRegBank::
780d2b4713eSJakob Stoklund Olesen computeOverlaps(std::map<const CodeGenRegister*, CodeGenRegister::Set> &Map) {
781d2b4713eSJakob Stoklund Olesen   assert(Map.empty());
782d2b4713eSJakob Stoklund Olesen 
783d2b4713eSJakob Stoklund Olesen   // Collect overlaps that don't follow from rule 2.
784d2b4713eSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
7858e188be0SJakob Stoklund Olesen     CodeGenRegister *Reg = Registers[i];
786d2b4713eSJakob Stoklund Olesen     CodeGenRegister::Set &Overlaps = Map[Reg];
787d2b4713eSJakob Stoklund Olesen 
788d2b4713eSJakob Stoklund Olesen     // Reg overlaps itself.
789d2b4713eSJakob Stoklund Olesen     Overlaps.insert(Reg);
790d2b4713eSJakob Stoklund Olesen 
791d2b4713eSJakob Stoklund Olesen     // All super-registers overlap.
792d2b4713eSJakob Stoklund Olesen     const CodeGenRegister::SuperRegList &Supers = Reg->getSuperRegs();
793d2b4713eSJakob Stoklund Olesen     Overlaps.insert(Supers.begin(), Supers.end());
794d2b4713eSJakob Stoklund Olesen 
795d2b4713eSJakob Stoklund Olesen     // Form symmetrical relations from the special Aliases[] lists.
796d2b4713eSJakob Stoklund Olesen     std::vector<Record*> RegList = Reg->TheDef->getValueAsListOfDefs("Aliases");
797d2b4713eSJakob Stoklund Olesen     for (unsigned i2 = 0, e2 = RegList.size(); i2 != e2; ++i2) {
798d2b4713eSJakob Stoklund Olesen       CodeGenRegister *Reg2 = getReg(RegList[i2]);
799d2b4713eSJakob Stoklund Olesen       CodeGenRegister::Set &Overlaps2 = Map[Reg2];
800d2b4713eSJakob Stoklund Olesen       const CodeGenRegister::SuperRegList &Supers2 = Reg2->getSuperRegs();
801d2b4713eSJakob Stoklund Olesen       // Reg overlaps Reg2 which implies it overlaps supers(Reg2).
802d2b4713eSJakob Stoklund Olesen       Overlaps.insert(Reg2);
803d2b4713eSJakob Stoklund Olesen       Overlaps.insert(Supers2.begin(), Supers2.end());
804d2b4713eSJakob Stoklund Olesen       Overlaps2.insert(Reg);
805d2b4713eSJakob Stoklund Olesen       Overlaps2.insert(Supers.begin(), Supers.end());
806d2b4713eSJakob Stoklund Olesen     }
807d2b4713eSJakob Stoklund Olesen   }
808d2b4713eSJakob Stoklund Olesen 
809d2b4713eSJakob Stoklund Olesen   // Apply rule 2. and inherit all sub-register overlaps.
810d2b4713eSJakob Stoklund Olesen   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
8118e188be0SJakob Stoklund Olesen     CodeGenRegister *Reg = Registers[i];
812d2b4713eSJakob Stoklund Olesen     CodeGenRegister::Set &Overlaps = Map[Reg];
813d2b4713eSJakob Stoklund Olesen     const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs();
814d2b4713eSJakob Stoklund Olesen     for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM.begin(),
815d2b4713eSJakob Stoklund Olesen          e2 = SRM.end(); i2 != e2; ++i2) {
816d2b4713eSJakob Stoklund Olesen       CodeGenRegister::Set &Overlaps2 = Map[i2->second];
817d2b4713eSJakob Stoklund Olesen       Overlaps.insert(Overlaps2.begin(), Overlaps2.end());
818d2b4713eSJakob Stoklund Olesen     }
819d2b4713eSJakob Stoklund Olesen   }
820d2b4713eSJakob Stoklund Olesen }
821d2b4713eSJakob Stoklund Olesen 
82284bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeDerivedInfo() {
82384bd44ebSJakob Stoklund Olesen   computeComposites();
82484bd44ebSJakob Stoklund Olesen }
82584bd44ebSJakob Stoklund Olesen 
826c0f97e3dSJakob Stoklund Olesen //
827c0f97e3dSJakob Stoklund Olesen // Synthesize missing register class intersections.
828c0f97e3dSJakob Stoklund Olesen //
829c0f97e3dSJakob Stoklund Olesen // Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X)
830c0f97e3dSJakob Stoklund Olesen // returns a maximal register class for all X.
831c0f97e3dSJakob Stoklund Olesen //
832c0f97e3dSJakob Stoklund Olesen void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
833c0f97e3dSJakob Stoklund Olesen   for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) {
834c0f97e3dSJakob Stoklund Olesen     CodeGenRegisterClass *RC1 = RC;
835c0f97e3dSJakob Stoklund Olesen     CodeGenRegisterClass *RC2 = RegClasses[rci];
836c0f97e3dSJakob Stoklund Olesen     if (RC1 == RC2)
837c0f97e3dSJakob Stoklund Olesen       continue;
838c0f97e3dSJakob Stoklund Olesen 
839c0f97e3dSJakob Stoklund Olesen     // Compute the set intersection of RC1 and RC2.
840c0f97e3dSJakob Stoklund Olesen     const CodeGenRegister::Set &Memb1 = RC1->getMembers();
841c0f97e3dSJakob Stoklund Olesen     const CodeGenRegister::Set &Memb2 = RC2->getMembers();
842c0f97e3dSJakob Stoklund Olesen     CodeGenRegister::Set Intersection;
843c0f97e3dSJakob Stoklund Olesen     std::set_intersection(Memb1.begin(), Memb1.end(),
844c0f97e3dSJakob Stoklund Olesen                           Memb2.begin(), Memb2.end(),
845f94cd193SJakob Stoklund Olesen                           std::inserter(Intersection, Intersection.begin()),
846f94cd193SJakob Stoklund Olesen                           CodeGenRegister::Less());
847c0f97e3dSJakob Stoklund Olesen 
848c0f97e3dSJakob Stoklund Olesen     // Skip disjoint class pairs.
849c0f97e3dSJakob Stoklund Olesen     if (Intersection.empty())
850c0f97e3dSJakob Stoklund Olesen       continue;
851c0f97e3dSJakob Stoklund Olesen 
852c0f97e3dSJakob Stoklund Olesen     // If RC1 and RC2 have different spill sizes or alignments, use the
853c0f97e3dSJakob Stoklund Olesen     // larger size for sub-classing.  If they are equal, prefer RC1.
854c0f97e3dSJakob Stoklund Olesen     if (RC2->SpillSize > RC1->SpillSize ||
855c0f97e3dSJakob Stoklund Olesen         (RC2->SpillSize == RC1->SpillSize &&
856c0f97e3dSJakob Stoklund Olesen          RC2->SpillAlignment > RC1->SpillAlignment))
857c0f97e3dSJakob Stoklund Olesen       std::swap(RC1, RC2);
858c0f97e3dSJakob Stoklund Olesen 
859c0f97e3dSJakob Stoklund Olesen     getOrCreateSubClass(RC1, &Intersection,
860c0f97e3dSJakob Stoklund Olesen                         RC1->getName() + "_and_" + RC2->getName());
861c0f97e3dSJakob Stoklund Olesen   }
862c0f97e3dSJakob Stoklund Olesen }
863c0f97e3dSJakob Stoklund Olesen 
86403efe84dSJakob Stoklund Olesen //
8656a5f0a19SJakob Stoklund Olesen // Synthesize missing sub-classes for getSubClassWithSubReg().
8666a5f0a19SJakob Stoklund Olesen //
8676a5f0a19SJakob Stoklund Olesen // Make sure that the set of registers in RC with a given SubIdx sub-register
8686a5f0a19SJakob Stoklund Olesen // form a register class.  Update RC->SubClassWithSubReg.
8696a5f0a19SJakob Stoklund Olesen //
8706a5f0a19SJakob Stoklund Olesen void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
8716a5f0a19SJakob Stoklund Olesen   // Map SubRegIndex to set of registers in RC supporting that SubRegIndex.
872f1bb1519SJakob Stoklund Olesen   typedef std::map<CodeGenSubRegIndex*, CodeGenRegister::Set,
873f1bb1519SJakob Stoklund Olesen                    CodeGenSubRegIndex::Less> SubReg2SetMap;
87403efe84dSJakob Stoklund Olesen 
87503efe84dSJakob Stoklund Olesen   // Compute the set of registers supporting each SubRegIndex.
87603efe84dSJakob Stoklund Olesen   SubReg2SetMap SRSets;
8776a5f0a19SJakob Stoklund Olesen   for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
8786a5f0a19SJakob Stoklund Olesen        RE = RC->getMembers().end(); RI != RE; ++RI) {
879b1147c46SJakob Stoklund Olesen     const CodeGenRegister::SubRegMap &SRM = (*RI)->getSubRegs();
880b1147c46SJakob Stoklund Olesen     for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
881b1147c46SJakob Stoklund Olesen          E = SRM.end(); I != E; ++I)
88203efe84dSJakob Stoklund Olesen       SRSets[I->first].insert(*RI);
88303efe84dSJakob Stoklund Olesen   }
88403efe84dSJakob Stoklund Olesen 
88503efe84dSJakob Stoklund Olesen   // Find matching classes for all SRSets entries.  Iterate in SubRegIndex
88603efe84dSJakob Stoklund Olesen   // numerical order to visit synthetic indices last.
88703efe84dSJakob Stoklund Olesen   for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
888f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *SubIdx = SubRegIndices[sri];
8893a541b04SJakob Stoklund Olesen     SubReg2SetMap::const_iterator I = SRSets.find(SubIdx);
89003efe84dSJakob Stoklund Olesen     // Unsupported SubRegIndex. Skip it.
89103efe84dSJakob Stoklund Olesen     if (I == SRSets.end())
89203efe84dSJakob Stoklund Olesen       continue;
8933a541b04SJakob Stoklund Olesen     // In most cases, all RC registers support the SubRegIndex.
8946a5f0a19SJakob Stoklund Olesen     if (I->second.size() == RC->getMembers().size()) {
8956a5f0a19SJakob Stoklund Olesen       RC->setSubClassWithSubReg(SubIdx, RC);
89603efe84dSJakob Stoklund Olesen       continue;
8973a541b04SJakob Stoklund Olesen     }
89803efe84dSJakob Stoklund Olesen     // This is a real subset.  See if we have a matching class.
8997ebc6b05SJakob Stoklund Olesen     CodeGenRegisterClass *SubRC =
9006a5f0a19SJakob Stoklund Olesen       getOrCreateSubClass(RC, &I->second,
9016a5f0a19SJakob Stoklund Olesen                           RC->getName() + "_with_" + I->first->getName());
9026a5f0a19SJakob Stoklund Olesen     RC->setSubClassWithSubReg(SubIdx, SubRC);
9036a5f0a19SJakob Stoklund Olesen   }
90403efe84dSJakob Stoklund Olesen }
905c0f97e3dSJakob Stoklund Olesen 
9066a5f0a19SJakob Stoklund Olesen //
907b92f557cSJakob Stoklund Olesen // Synthesize missing sub-classes of RC for getMatchingSuperRegClass().
908b92f557cSJakob Stoklund Olesen //
909b92f557cSJakob Stoklund Olesen // Create sub-classes of RC such that getMatchingSuperRegClass(RC, SubIdx, X)
910b92f557cSJakob Stoklund Olesen // has a maximal result for any SubIdx and any X >= FirstSubRegRC.
911b92f557cSJakob Stoklund Olesen //
912b92f557cSJakob Stoklund Olesen 
913b92f557cSJakob Stoklund Olesen void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
914b92f557cSJakob Stoklund Olesen                                                 unsigned FirstSubRegRC) {
915b92f557cSJakob Stoklund Olesen   SmallVector<std::pair<const CodeGenRegister*,
916b92f557cSJakob Stoklund Olesen                         const CodeGenRegister*>, 16> SSPairs;
917b92f557cSJakob Stoklund Olesen 
918b92f557cSJakob Stoklund Olesen   // Iterate in SubRegIndex numerical order to visit synthetic indices last.
919b92f557cSJakob Stoklund Olesen   for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
920f1bb1519SJakob Stoklund Olesen     CodeGenSubRegIndex *SubIdx = SubRegIndices[sri];
921b92f557cSJakob Stoklund Olesen     // Skip indexes that aren't fully supported by RC's registers. This was
922b92f557cSJakob Stoklund Olesen     // computed by inferSubClassWithSubReg() above which should have been
923b92f557cSJakob Stoklund Olesen     // called first.
924b92f557cSJakob Stoklund Olesen     if (RC->getSubClassWithSubReg(SubIdx) != RC)
925b92f557cSJakob Stoklund Olesen       continue;
926b92f557cSJakob Stoklund Olesen 
927b92f557cSJakob Stoklund Olesen     // Build list of (Super, Sub) pairs for this SubIdx.
928b92f557cSJakob Stoklund Olesen     SSPairs.clear();
929b92f557cSJakob Stoklund Olesen     for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
930b92f557cSJakob Stoklund Olesen          RE = RC->getMembers().end(); RI != RE; ++RI) {
931b92f557cSJakob Stoklund Olesen       const CodeGenRegister *Super = *RI;
932b92f557cSJakob Stoklund Olesen       const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
933b92f557cSJakob Stoklund Olesen       assert(Sub && "Missing sub-register");
934b92f557cSJakob Stoklund Olesen       SSPairs.push_back(std::make_pair(Super, Sub));
935b92f557cSJakob Stoklund Olesen     }
936b92f557cSJakob Stoklund Olesen 
937b92f557cSJakob Stoklund Olesen     // Iterate over sub-register class candidates.  Ignore classes created by
938b92f557cSJakob Stoklund Olesen     // this loop. They will never be useful.
939b92f557cSJakob Stoklund Olesen     for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
940b92f557cSJakob Stoklund Olesen          ++rci) {
941b92f557cSJakob Stoklund Olesen       CodeGenRegisterClass *SubRC = RegClasses[rci];
942b92f557cSJakob Stoklund Olesen       // Compute the subset of RC that maps into SubRC.
943b92f557cSJakob Stoklund Olesen       CodeGenRegister::Set SubSet;
944b92f557cSJakob Stoklund Olesen       for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
945b92f557cSJakob Stoklund Olesen         if (SubRC->contains(SSPairs[i].second))
946b92f557cSJakob Stoklund Olesen           SubSet.insert(SSPairs[i].first);
947b92f557cSJakob Stoklund Olesen       if (SubSet.empty())
948b92f557cSJakob Stoklund Olesen         continue;
949b92f557cSJakob Stoklund Olesen       // RC injects completely into SubRC.
950c7b437aeSJakob Stoklund Olesen       if (SubSet.size() == SSPairs.size()) {
951c7b437aeSJakob Stoklund Olesen         SubRC->addSuperRegClass(SubIdx, RC);
952b92f557cSJakob Stoklund Olesen         continue;
953c7b437aeSJakob Stoklund Olesen       }
954b92f557cSJakob Stoklund Olesen       // Only a subset of RC maps into SubRC. Make sure it is represented by a
955b92f557cSJakob Stoklund Olesen       // class.
956b92f557cSJakob Stoklund Olesen       getOrCreateSubClass(RC, &SubSet, RC->getName() +
957b92f557cSJakob Stoklund Olesen                           "_with_" + SubIdx->getName() +
958b92f557cSJakob Stoklund Olesen                           "_in_" + SubRC->getName());
959b92f557cSJakob Stoklund Olesen     }
960b92f557cSJakob Stoklund Olesen   }
961b92f557cSJakob Stoklund Olesen }
962b92f557cSJakob Stoklund Olesen 
963b92f557cSJakob Stoklund Olesen 
964b92f557cSJakob Stoklund Olesen //
9656a5f0a19SJakob Stoklund Olesen // Infer missing register classes.
9666a5f0a19SJakob Stoklund Olesen //
9676a5f0a19SJakob Stoklund Olesen void CodeGenRegBank::computeInferredRegisterClasses() {
9686a5f0a19SJakob Stoklund Olesen   // When this function is called, the register classes have not been sorted
9696a5f0a19SJakob Stoklund Olesen   // and assigned EnumValues yet.  That means getSubClasses(),
9706a5f0a19SJakob Stoklund Olesen   // getSuperClasses(), and hasSubClass() functions are defunct.
971b92f557cSJakob Stoklund Olesen   unsigned FirstNewRC = RegClasses.size();
9726a5f0a19SJakob Stoklund Olesen 
9736a5f0a19SJakob Stoklund Olesen   // Visit all register classes, including the ones being added by the loop.
9746a5f0a19SJakob Stoklund Olesen   for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
9756a5f0a19SJakob Stoklund Olesen     CodeGenRegisterClass *RC = RegClasses[rci];
9766a5f0a19SJakob Stoklund Olesen 
9776a5f0a19SJakob Stoklund Olesen     // Synthesize answers for getSubClassWithSubReg().
9786a5f0a19SJakob Stoklund Olesen     inferSubClassWithSubReg(RC);
9796a5f0a19SJakob Stoklund Olesen 
980c0f97e3dSJakob Stoklund Olesen     // Synthesize answers for getCommonSubClass().
9816a5f0a19SJakob Stoklund Olesen     inferCommonSubClass(RC);
982b92f557cSJakob Stoklund Olesen 
983b92f557cSJakob Stoklund Olesen     // Synthesize answers for getMatchingSuperRegClass().
984b92f557cSJakob Stoklund Olesen     inferMatchingSuperRegClass(RC);
985b92f557cSJakob Stoklund Olesen 
986b92f557cSJakob Stoklund Olesen     // New register classes are created while this loop is running, and we need
987b92f557cSJakob Stoklund Olesen     // to visit all of them.  I  particular, inferMatchingSuperRegClass needs
988b92f557cSJakob Stoklund Olesen     // to match old super-register classes with sub-register classes created
989b92f557cSJakob Stoklund Olesen     // after inferMatchingSuperRegClass was called.  At this point,
990b92f557cSJakob Stoklund Olesen     // inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC =
991b92f557cSJakob Stoklund Olesen     // [0..FirstNewRC).  We need to cover SubRC = [FirstNewRC..rci].
992b92f557cSJakob Stoklund Olesen     if (rci + 1 == FirstNewRC) {
993b92f557cSJakob Stoklund Olesen       unsigned NextNewRC = RegClasses.size();
994b92f557cSJakob Stoklund Olesen       for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2)
995b92f557cSJakob Stoklund Olesen         inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC);
996b92f557cSJakob Stoklund Olesen       FirstNewRC = NextNewRC;
997b92f557cSJakob Stoklund Olesen     }
99803efe84dSJakob Stoklund Olesen   }
99903efe84dSJakob Stoklund Olesen }
100003efe84dSJakob Stoklund Olesen 
100122ea424dSJakob Stoklund Olesen /// getRegisterClassForRegister - Find the register class that contains the
100222ea424dSJakob Stoklund Olesen /// specified physical register.  If the register is not in a register class,
100322ea424dSJakob Stoklund Olesen /// return null. If the register is in multiple classes, and the classes have a
100422ea424dSJakob Stoklund Olesen /// superset-subset relationship and the same set of types, return the
100522ea424dSJakob Stoklund Olesen /// superclass.  Otherwise return null.
100622ea424dSJakob Stoklund Olesen const CodeGenRegisterClass*
100722ea424dSJakob Stoklund Olesen CodeGenRegBank::getRegClassForRegister(Record *R) {
1008d7bc5c26SJakob Stoklund Olesen   const CodeGenRegister *Reg = getReg(R);
100919be2ab3SJakob Stoklund Olesen   ArrayRef<CodeGenRegisterClass*> RCs = getRegClasses();
101022ea424dSJakob Stoklund Olesen   const CodeGenRegisterClass *FoundRC = 0;
101122ea424dSJakob Stoklund Olesen   for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
101219be2ab3SJakob Stoklund Olesen     const CodeGenRegisterClass &RC = *RCs[i];
1013d7bc5c26SJakob Stoklund Olesen     if (!RC.contains(Reg))
101422ea424dSJakob Stoklund Olesen       continue;
101522ea424dSJakob Stoklund Olesen 
101622ea424dSJakob Stoklund Olesen     // If this is the first class that contains the register,
101722ea424dSJakob Stoklund Olesen     // make a note of it and go on to the next class.
101822ea424dSJakob Stoklund Olesen     if (!FoundRC) {
101922ea424dSJakob Stoklund Olesen       FoundRC = &RC;
102022ea424dSJakob Stoklund Olesen       continue;
102122ea424dSJakob Stoklund Olesen     }
102222ea424dSJakob Stoklund Olesen 
102322ea424dSJakob Stoklund Olesen     // If a register's classes have different types, return null.
102422ea424dSJakob Stoklund Olesen     if (RC.getValueTypes() != FoundRC->getValueTypes())
102522ea424dSJakob Stoklund Olesen       return 0;
102622ea424dSJakob Stoklund Olesen 
102722ea424dSJakob Stoklund Olesen     // Check to see if the previously found class that contains
102822ea424dSJakob Stoklund Olesen     // the register is a subclass of the current class. If so,
102922ea424dSJakob Stoklund Olesen     // prefer the superclass.
1030d7bc5c26SJakob Stoklund Olesen     if (RC.hasSubClass(FoundRC)) {
103122ea424dSJakob Stoklund Olesen       FoundRC = &RC;
103222ea424dSJakob Stoklund Olesen       continue;
103322ea424dSJakob Stoklund Olesen     }
103422ea424dSJakob Stoklund Olesen 
103522ea424dSJakob Stoklund Olesen     // Check to see if the previously found class that contains
103622ea424dSJakob Stoklund Olesen     // the register is a superclass of the current class. If so,
103722ea424dSJakob Stoklund Olesen     // prefer the superclass.
1038d7bc5c26SJakob Stoklund Olesen     if (FoundRC->hasSubClass(&RC))
103922ea424dSJakob Stoklund Olesen       continue;
104022ea424dSJakob Stoklund Olesen 
104122ea424dSJakob Stoklund Olesen     // Multiple classes, and neither is a superclass of the other.
104222ea424dSJakob Stoklund Olesen     // Return null.
104322ea424dSJakob Stoklund Olesen     return 0;
104422ea424dSJakob Stoklund Olesen   }
104522ea424dSJakob Stoklund Olesen   return FoundRC;
104622ea424dSJakob Stoklund Olesen }
1047c3abb0f6SJakob Stoklund Olesen 
1048c3abb0f6SJakob Stoklund Olesen BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef<Record*> Regs) {
1049c3abb0f6SJakob Stoklund Olesen   SetVector<CodeGenRegister*> Set;
1050c3abb0f6SJakob Stoklund Olesen 
1051c3abb0f6SJakob Stoklund Olesen   // First add Regs with all sub-registers.
1052c3abb0f6SJakob Stoklund Olesen   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
1053c3abb0f6SJakob Stoklund Olesen     CodeGenRegister *Reg = getReg(Regs[i]);
1054c3abb0f6SJakob Stoklund Olesen     if (Set.insert(Reg))
1055c3abb0f6SJakob Stoklund Olesen       // Reg is new, add all sub-registers.
1056c3abb0f6SJakob Stoklund Olesen       // The pre-ordering is not important here.
1057f1bb1519SJakob Stoklund Olesen       Reg->addSubRegsPreOrder(Set, *this);
1058c3abb0f6SJakob Stoklund Olesen   }
1059c3abb0f6SJakob Stoklund Olesen 
1060c3abb0f6SJakob Stoklund Olesen   // Second, find all super-registers that are completely covered by the set.
1061f43b5995SJakob Stoklund Olesen   for (unsigned i = 0; i != Set.size(); ++i) {
1062f43b5995SJakob Stoklund Olesen     const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs();
1063f43b5995SJakob Stoklund Olesen     for (unsigned j = 0, e = SR.size(); j != e; ++j) {
1064f43b5995SJakob Stoklund Olesen       CodeGenRegister *Super = SR[j];
1065f43b5995SJakob Stoklund Olesen       if (!Super->CoveredBySubRegs || Set.count(Super))
1066f43b5995SJakob Stoklund Olesen         continue;
1067f43b5995SJakob Stoklund Olesen       // This new super-register is covered by its sub-registers.
1068f43b5995SJakob Stoklund Olesen       bool AllSubsInSet = true;
1069f43b5995SJakob Stoklund Olesen       const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs();
1070f43b5995SJakob Stoklund Olesen       for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
1071f43b5995SJakob Stoklund Olesen              E = SRM.end(); I != E; ++I)
1072f43b5995SJakob Stoklund Olesen         if (!Set.count(I->second)) {
1073f43b5995SJakob Stoklund Olesen           AllSubsInSet = false;
1074f43b5995SJakob Stoklund Olesen           break;
1075f43b5995SJakob Stoklund Olesen         }
1076f43b5995SJakob Stoklund Olesen       // All sub-registers in Set, add Super as well.
1077f43b5995SJakob Stoklund Olesen       // We will visit Super later to recheck its super-registers.
1078f43b5995SJakob Stoklund Olesen       if (AllSubsInSet)
1079f43b5995SJakob Stoklund Olesen         Set.insert(Super);
1080f43b5995SJakob Stoklund Olesen     }
1081f43b5995SJakob Stoklund Olesen   }
1082c3abb0f6SJakob Stoklund Olesen 
1083c3abb0f6SJakob Stoklund Olesen   // Convert to BitVector.
1084c3abb0f6SJakob Stoklund Olesen   BitVector BV(Registers.size() + 1);
1085c3abb0f6SJakob Stoklund Olesen   for (unsigned i = 0, e = Set.size(); i != e; ++i)
1086c3abb0f6SJakob Stoklund Olesen     BV.set(Set[i]->EnumValue);
1087c3abb0f6SJakob Stoklund Olesen   return BV;
1088c3abb0f6SJakob Stoklund Olesen }
1089