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 //===----------------------------------------------------------------------===// 2568d6d8abSJakob Stoklund Olesen // CodeGenRegister 2668d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 2768d6d8abSJakob Stoklund Olesen 2884bd44ebSJakob Stoklund Olesen CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum) 2984bd44ebSJakob Stoklund Olesen : TheDef(R), 3084bd44ebSJakob Stoklund Olesen EnumValue(Enum), 3184bd44ebSJakob Stoklund Olesen CostPerUse(R->getValueAsInt("CostPerUse")), 3284bd44ebSJakob Stoklund Olesen SubRegsComplete(false) 3384bd44ebSJakob Stoklund Olesen {} 3468d6d8abSJakob Stoklund Olesen 3568d6d8abSJakob Stoklund Olesen const std::string &CodeGenRegister::getName() const { 3668d6d8abSJakob Stoklund Olesen return TheDef->getName(); 3768d6d8abSJakob Stoklund Olesen } 3868d6d8abSJakob Stoklund Olesen 3984bd44ebSJakob Stoklund Olesen namespace { 4084bd44ebSJakob Stoklund Olesen struct Orphan { 4184bd44ebSJakob Stoklund Olesen CodeGenRegister *SubReg; 4284bd44ebSJakob Stoklund Olesen Record *First, *Second; 4384bd44ebSJakob Stoklund Olesen Orphan(CodeGenRegister *r, Record *a, Record *b) 4484bd44ebSJakob Stoklund Olesen : SubReg(r), First(a), Second(b) {} 4584bd44ebSJakob Stoklund Olesen }; 4684bd44ebSJakob Stoklund Olesen } 4784bd44ebSJakob Stoklund Olesen 4884bd44ebSJakob Stoklund Olesen const CodeGenRegister::SubRegMap & 4984bd44ebSJakob Stoklund Olesen CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { 5084bd44ebSJakob Stoklund Olesen // Only compute this map once. 5184bd44ebSJakob Stoklund Olesen if (SubRegsComplete) 5284bd44ebSJakob Stoklund Olesen return SubRegs; 5384bd44ebSJakob Stoklund Olesen SubRegsComplete = true; 5484bd44ebSJakob Stoklund Olesen 5584bd44ebSJakob Stoklund Olesen std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs"); 5684bd44ebSJakob Stoklund Olesen std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); 5784bd44ebSJakob Stoklund Olesen if (SubList.size() != Indices.size()) 5884bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Register " + getName() + 5984bd44ebSJakob Stoklund Olesen " SubRegIndices doesn't match SubRegs"); 6084bd44ebSJakob Stoklund Olesen 6184bd44ebSJakob Stoklund Olesen // First insert the direct subregs and make sure they are fully indexed. 6284bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = SubList.size(); i != e; ++i) { 6384bd44ebSJakob Stoklund Olesen CodeGenRegister *SR = RegBank.getReg(SubList[i]); 6484bd44ebSJakob Stoklund Olesen if (!SubRegs.insert(std::make_pair(Indices[i], SR)).second) 6584bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "SubRegIndex " + Indices[i]->getName() + 6684bd44ebSJakob Stoklund Olesen " appears twice in Register " + getName()); 6784bd44ebSJakob Stoklund Olesen } 6884bd44ebSJakob Stoklund Olesen 6984bd44ebSJakob Stoklund Olesen // Keep track of inherited subregs and how they can be reached. 7084bd44ebSJakob Stoklund Olesen SmallVector<Orphan, 8> Orphans; 7184bd44ebSJakob Stoklund Olesen 7284bd44ebSJakob Stoklund Olesen // Clone inherited subregs and place duplicate entries on Orphans. 7384bd44ebSJakob Stoklund Olesen // Here the order is important - earlier subregs take precedence. 7484bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = SubList.size(); i != e; ++i) { 7584bd44ebSJakob Stoklund Olesen CodeGenRegister *SR = RegBank.getReg(SubList[i]); 7684bd44ebSJakob Stoklund Olesen const SubRegMap &Map = SR->getSubRegs(RegBank); 77d2b4713eSJakob Stoklund Olesen 78d2b4713eSJakob Stoklund Olesen // Add this as a super-register of SR now all sub-registers are in the list. 79d2b4713eSJakob Stoklund Olesen // This creates a topological ordering, the exact order depends on the 80d2b4713eSJakob Stoklund Olesen // order getSubRegs is called on all registers. 81d2b4713eSJakob Stoklund Olesen SR->SuperRegs.push_back(this); 82d2b4713eSJakob Stoklund Olesen 8384bd44ebSJakob Stoklund Olesen for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE; 84d2b4713eSJakob Stoklund Olesen ++SI) { 8584bd44ebSJakob Stoklund Olesen if (!SubRegs.insert(*SI).second) 8684bd44ebSJakob Stoklund Olesen Orphans.push_back(Orphan(SI->second, Indices[i], SI->first)); 87d2b4713eSJakob Stoklund Olesen 88d2b4713eSJakob Stoklund Olesen // Noop sub-register indexes are possible, so avoid duplicates. 89d2b4713eSJakob Stoklund Olesen if (SI->second != SR) 90d2b4713eSJakob Stoklund Olesen SI->second->SuperRegs.push_back(this); 91d2b4713eSJakob Stoklund Olesen } 9284bd44ebSJakob Stoklund Olesen } 9384bd44ebSJakob Stoklund Olesen 9484bd44ebSJakob Stoklund Olesen // Process the composites. 95af8ee2cdSDavid Greene ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices"); 9684bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Comps->size(); i != e; ++i) { 97af8ee2cdSDavid Greene DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i)); 9884bd44ebSJakob Stoklund Olesen if (!Pat) 9984bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Invalid dag '" + 10084bd44ebSJakob Stoklund Olesen Comps->getElement(i)->getAsString() + 10184bd44ebSJakob Stoklund Olesen "' in CompositeIndices"); 102af8ee2cdSDavid Greene DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator()); 10384bd44ebSJakob Stoklund Olesen if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) 10484bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + 10584bd44ebSJakob Stoklund Olesen Pat->getAsString()); 10684bd44ebSJakob Stoklund Olesen 10784bd44ebSJakob Stoklund Olesen // Resolve list of subreg indices into R2. 10884bd44ebSJakob Stoklund Olesen CodeGenRegister *R2 = this; 10984bd44ebSJakob Stoklund Olesen for (DagInit::const_arg_iterator di = Pat->arg_begin(), 11084bd44ebSJakob Stoklund Olesen de = Pat->arg_end(); di != de; ++di) { 111af8ee2cdSDavid Greene DefInit *IdxInit = dynamic_cast<DefInit*>(*di); 11284bd44ebSJakob Stoklund Olesen if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) 11384bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + 11484bd44ebSJakob Stoklund Olesen Pat->getAsString()); 11584bd44ebSJakob Stoklund Olesen const SubRegMap &R2Subs = R2->getSubRegs(RegBank); 11684bd44ebSJakob Stoklund Olesen SubRegMap::const_iterator ni = R2Subs.find(IdxInit->getDef()); 11784bd44ebSJakob Stoklund Olesen if (ni == R2Subs.end()) 11884bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() + 11984bd44ebSJakob Stoklund Olesen " refers to bad index in " + R2->getName()); 12084bd44ebSJakob Stoklund Olesen R2 = ni->second; 12184bd44ebSJakob Stoklund Olesen } 12284bd44ebSJakob Stoklund Olesen 12384bd44ebSJakob Stoklund Olesen // Insert composite index. Allow overriding inherited indices etc. 12484bd44ebSJakob Stoklund Olesen SubRegs[BaseIdxInit->getDef()] = R2; 12584bd44ebSJakob Stoklund Olesen 12684bd44ebSJakob Stoklund Olesen // R2 is no longer an orphan. 12784bd44ebSJakob Stoklund Olesen for (unsigned j = 0, je = Orphans.size(); j != je; ++j) 12884bd44ebSJakob Stoklund Olesen if (Orphans[j].SubReg == R2) 12984bd44ebSJakob Stoklund Olesen Orphans[j].SubReg = 0; 13084bd44ebSJakob Stoklund Olesen } 13184bd44ebSJakob Stoklund Olesen 13284bd44ebSJakob Stoklund Olesen // Now Orphans contains the inherited subregisters without a direct index. 13384bd44ebSJakob Stoklund Olesen // Create inferred indexes for all missing entries. 13484bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Orphans.size(); i != e; ++i) { 13584bd44ebSJakob Stoklund Olesen Orphan &O = Orphans[i]; 13684bd44ebSJakob Stoklund Olesen if (!O.SubReg) 13784bd44ebSJakob Stoklund Olesen continue; 13884bd44ebSJakob Stoklund Olesen SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second, true)] = 13984bd44ebSJakob Stoklund Olesen O.SubReg; 14084bd44ebSJakob Stoklund Olesen } 14184bd44ebSJakob Stoklund Olesen return SubRegs; 14284bd44ebSJakob Stoklund Olesen } 14384bd44ebSJakob Stoklund Olesen 144d2b4713eSJakob Stoklund Olesen void 145d2b4713eSJakob Stoklund Olesen CodeGenRegister::addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const { 146d2b4713eSJakob Stoklund Olesen assert(SubRegsComplete && "Must precompute sub-registers"); 147d2b4713eSJakob Stoklund Olesen std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); 148d2b4713eSJakob Stoklund Olesen for (unsigned i = 0, e = Indices.size(); i != e; ++i) { 149d2b4713eSJakob Stoklund Olesen CodeGenRegister *SR = SubRegs.find(Indices[i])->second; 150d2b4713eSJakob Stoklund Olesen if (OSet.insert(SR)) 151d2b4713eSJakob Stoklund Olesen SR->addSubRegsPreOrder(OSet); 152d2b4713eSJakob Stoklund Olesen } 153d2b4713eSJakob Stoklund Olesen } 154d2b4713eSJakob Stoklund Olesen 15568d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 1563bd1b65eSJakob Stoklund Olesen // RegisterTuples 1573bd1b65eSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 1583bd1b65eSJakob Stoklund Olesen 1593bd1b65eSJakob Stoklund Olesen // A RegisterTuples def is used to generate pseudo-registers from lists of 1603bd1b65eSJakob Stoklund Olesen // sub-registers. We provide a SetTheory expander class that returns the new 1613bd1b65eSJakob Stoklund Olesen // registers. 1623bd1b65eSJakob Stoklund Olesen namespace { 1633bd1b65eSJakob Stoklund Olesen struct TupleExpander : SetTheory::Expander { 1643bd1b65eSJakob Stoklund Olesen void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) { 1653bd1b65eSJakob Stoklund Olesen std::vector<Record*> Indices = Def->getValueAsListOfDefs("SubRegIndices"); 1663bd1b65eSJakob Stoklund Olesen unsigned Dim = Indices.size(); 167af8ee2cdSDavid Greene ListInit *SubRegs = Def->getValueAsListInit("SubRegs"); 1683bd1b65eSJakob Stoklund Olesen if (Dim != SubRegs->getSize()) 1693bd1b65eSJakob Stoklund Olesen throw TGError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch"); 1703bd1b65eSJakob Stoklund Olesen if (Dim < 2) 1713bd1b65eSJakob Stoklund Olesen throw TGError(Def->getLoc(), "Tuples must have at least 2 sub-registers"); 1723bd1b65eSJakob Stoklund Olesen 1733bd1b65eSJakob Stoklund Olesen // Evaluate the sub-register lists to be zipped. 1743bd1b65eSJakob Stoklund Olesen unsigned Length = ~0u; 1753bd1b65eSJakob Stoklund Olesen SmallVector<SetTheory::RecSet, 4> Lists(Dim); 1763bd1b65eSJakob Stoklund Olesen for (unsigned i = 0; i != Dim; ++i) { 1773bd1b65eSJakob Stoklund Olesen ST.evaluate(SubRegs->getElement(i), Lists[i]); 1783bd1b65eSJakob Stoklund Olesen Length = std::min(Length, unsigned(Lists[i].size())); 1793bd1b65eSJakob Stoklund Olesen } 1803bd1b65eSJakob Stoklund Olesen 1813bd1b65eSJakob Stoklund Olesen if (Length == 0) 1823bd1b65eSJakob Stoklund Olesen return; 1833bd1b65eSJakob Stoklund Olesen 1843bd1b65eSJakob Stoklund Olesen // Precompute some types. 1853bd1b65eSJakob Stoklund Olesen Record *RegisterCl = Def->getRecords().getClass("Register"); 186abcfdceaSJakob Stoklund Olesen RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl); 187af8ee2cdSDavid Greene StringInit *BlankName = StringInit::get(""); 1883bd1b65eSJakob Stoklund Olesen 1893bd1b65eSJakob Stoklund Olesen // Zip them up. 1903bd1b65eSJakob Stoklund Olesen for (unsigned n = 0; n != Length; ++n) { 1913bd1b65eSJakob Stoklund Olesen std::string Name; 1923bd1b65eSJakob Stoklund Olesen Record *Proto = Lists[0][n]; 193af8ee2cdSDavid Greene std::vector<Init*> Tuple; 1943bd1b65eSJakob Stoklund Olesen unsigned CostPerUse = 0; 1953bd1b65eSJakob Stoklund Olesen for (unsigned i = 0; i != Dim; ++i) { 1963bd1b65eSJakob Stoklund Olesen Record *Reg = Lists[i][n]; 1973bd1b65eSJakob Stoklund Olesen if (i) Name += '_'; 1983bd1b65eSJakob Stoklund Olesen Name += Reg->getName(); 199abcfdceaSJakob Stoklund Olesen Tuple.push_back(DefInit::get(Reg)); 2003bd1b65eSJakob Stoklund Olesen CostPerUse = std::max(CostPerUse, 2013bd1b65eSJakob Stoklund Olesen unsigned(Reg->getValueAsInt("CostPerUse"))); 2023bd1b65eSJakob Stoklund Olesen } 2033bd1b65eSJakob Stoklund Olesen 2043bd1b65eSJakob Stoklund Olesen // Create a new Record representing the synthesized register. This record 2053bd1b65eSJakob Stoklund Olesen // is only for consumption by CodeGenRegister, it is not added to the 2063bd1b65eSJakob Stoklund Olesen // RecordKeeper. 2073bd1b65eSJakob Stoklund Olesen Record *NewReg = new Record(Name, Def->getLoc(), Def->getRecords()); 2083bd1b65eSJakob Stoklund Olesen Elts.insert(NewReg); 2093bd1b65eSJakob Stoklund Olesen 2103bd1b65eSJakob Stoklund Olesen // Copy Proto super-classes. 2113bd1b65eSJakob Stoklund Olesen for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i) 2123bd1b65eSJakob Stoklund Olesen NewReg->addSuperClass(Proto->getSuperClasses()[i]); 2133bd1b65eSJakob Stoklund Olesen 2143bd1b65eSJakob Stoklund Olesen // Copy Proto fields. 2153bd1b65eSJakob Stoklund Olesen for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) { 2163bd1b65eSJakob Stoklund Olesen RecordVal RV = Proto->getValues()[i]; 2173bd1b65eSJakob Stoklund Olesen 2183bd1b65eSJakob Stoklund Olesen // Replace the sub-register list with Tuple. 2193bd1b65eSJakob Stoklund Olesen if (RV.getName() == "SubRegs") 220e32ebf22SDavid Greene RV.setValue(ListInit::get(Tuple, RegisterRecTy)); 2213bd1b65eSJakob Stoklund Olesen 2223bd1b65eSJakob Stoklund Olesen // Provide a blank AsmName. MC hacks are required anyway. 2233bd1b65eSJakob Stoklund Olesen if (RV.getName() == "AsmName") 2243bd1b65eSJakob Stoklund Olesen RV.setValue(BlankName); 2253bd1b65eSJakob Stoklund Olesen 2263bd1b65eSJakob Stoklund Olesen // CostPerUse is aggregated from all Tuple members. 2273bd1b65eSJakob Stoklund Olesen if (RV.getName() == "CostPerUse") 228e32ebf22SDavid Greene RV.setValue(IntInit::get(CostPerUse)); 2293bd1b65eSJakob Stoklund Olesen 2303bd1b65eSJakob Stoklund Olesen // Copy fields from the RegisterTuples def. 2313bd1b65eSJakob Stoklund Olesen if (RV.getName() == "SubRegIndices" || 2323bd1b65eSJakob Stoklund Olesen RV.getName() == "CompositeIndices") { 2333bd1b65eSJakob Stoklund Olesen NewReg->addValue(*Def->getValue(RV.getName())); 2343bd1b65eSJakob Stoklund Olesen continue; 2353bd1b65eSJakob Stoklund Olesen } 2363bd1b65eSJakob Stoklund Olesen 2373bd1b65eSJakob Stoklund Olesen // Some fields get their default uninitialized value. 2383bd1b65eSJakob Stoklund Olesen if (RV.getName() == "DwarfNumbers" || 2393bd1b65eSJakob Stoklund Olesen RV.getName() == "DwarfAlias" || 2403bd1b65eSJakob Stoklund Olesen RV.getName() == "Aliases") { 241d9149a45SJakob Stoklund Olesen if (const RecordVal *DefRV = RegisterCl->getValue(RV.getName())) 242d9149a45SJakob Stoklund Olesen NewReg->addValue(*DefRV); 2433bd1b65eSJakob Stoklund Olesen continue; 2443bd1b65eSJakob Stoklund Olesen } 2453bd1b65eSJakob Stoklund Olesen 2463bd1b65eSJakob Stoklund Olesen // Everything else is copied from Proto. 2473bd1b65eSJakob Stoklund Olesen NewReg->addValue(RV); 2483bd1b65eSJakob Stoklund Olesen } 2493bd1b65eSJakob Stoklund Olesen } 2503bd1b65eSJakob Stoklund Olesen } 2513bd1b65eSJakob Stoklund Olesen }; 2523bd1b65eSJakob Stoklund Olesen } 2533bd1b65eSJakob Stoklund Olesen 2543bd1b65eSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 25568d6d8abSJakob Stoklund Olesen // CodeGenRegisterClass 25668d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 25768d6d8abSJakob Stoklund Olesen 258d7bc5c26SJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) 259bd92dc60SJakob Stoklund Olesen : TheDef(R), Name(R->getName()), EnumValue(-1) { 26068d6d8abSJakob Stoklund Olesen // Rename anonymous register classes. 26168d6d8abSJakob Stoklund Olesen if (R->getName().size() > 9 && R->getName()[9] == '.') { 26268d6d8abSJakob Stoklund Olesen static unsigned AnonCounter = 0; 26368d6d8abSJakob Stoklund Olesen R->setName("AnonRegClass_"+utostr(AnonCounter++)); 26468d6d8abSJakob Stoklund Olesen } 26568d6d8abSJakob Stoklund Olesen 26668d6d8abSJakob Stoklund Olesen std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes"); 26768d6d8abSJakob Stoklund Olesen for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { 26868d6d8abSJakob Stoklund Olesen Record *Type = TypeList[i]; 26968d6d8abSJakob Stoklund Olesen if (!Type->isSubClassOf("ValueType")) 27068d6d8abSJakob Stoklund Olesen throw "RegTypes list member '" + Type->getName() + 27168d6d8abSJakob Stoklund Olesen "' does not derive from the ValueType class!"; 27268d6d8abSJakob Stoklund Olesen VTs.push_back(getValueType(Type)); 27368d6d8abSJakob Stoklund Olesen } 27468d6d8abSJakob Stoklund Olesen assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); 27568d6d8abSJakob Stoklund Olesen 276331534e5SJakob Stoklund Olesen // Allocation order 0 is the full set. AltOrders provides others. 277331534e5SJakob Stoklund Olesen const SetTheory::RecVec *Elements = RegBank.getSets().expand(R); 278331534e5SJakob Stoklund Olesen ListInit *AltOrders = R->getValueAsListInit("AltOrders"); 279331534e5SJakob Stoklund Olesen Orders.resize(1 + AltOrders->size()); 280331534e5SJakob Stoklund Olesen 28135cea3daSJakob Stoklund Olesen // Default allocation order always contains all registers. 282331534e5SJakob Stoklund Olesen for (unsigned i = 0, e = Elements->size(); i != e; ++i) { 283331534e5SJakob Stoklund Olesen Orders[0].push_back((*Elements)[i]); 2845ee87726SJakob Stoklund Olesen Members.insert(RegBank.getReg((*Elements)[i])); 285331534e5SJakob Stoklund Olesen } 28668d6d8abSJakob Stoklund Olesen 28735cea3daSJakob Stoklund Olesen // Alternative allocation orders may be subsets. 28835cea3daSJakob Stoklund Olesen SetTheory::RecSet Order; 289331534e5SJakob Stoklund Olesen for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) { 290331534e5SJakob Stoklund Olesen RegBank.getSets().evaluate(AltOrders->getElement(i), Order); 291331534e5SJakob Stoklund Olesen Orders[1 + i].append(Order.begin(), Order.end()); 29235cea3daSJakob Stoklund Olesen // Verify that all altorder members are regclass members. 29335cea3daSJakob Stoklund Olesen while (!Order.empty()) { 29435cea3daSJakob Stoklund Olesen CodeGenRegister *Reg = RegBank.getReg(Order.back()); 29535cea3daSJakob Stoklund Olesen Order.pop_back(); 29635cea3daSJakob Stoklund Olesen if (!contains(Reg)) 29735cea3daSJakob Stoklund Olesen throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() + 29835cea3daSJakob Stoklund Olesen " is not a class member"); 29935cea3daSJakob Stoklund Olesen } 30035cea3daSJakob Stoklund Olesen } 30135cea3daSJakob Stoklund Olesen 30268d6d8abSJakob Stoklund Olesen // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags. 303af8ee2cdSDavid Greene ListInit *SRC = R->getValueAsListInit("SubRegClasses"); 30468d6d8abSJakob Stoklund Olesen for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) { 305af8ee2cdSDavid Greene DagInit *DAG = dynamic_cast<DagInit*>(*i); 30668d6d8abSJakob Stoklund Olesen if (!DAG) throw "SubRegClasses must contain DAGs"; 307af8ee2cdSDavid Greene DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator()); 30868d6d8abSJakob Stoklund Olesen Record *RCRec; 30968d6d8abSJakob Stoklund Olesen if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass")) 31068d6d8abSJakob Stoklund Olesen throw "Operator '" + DAG->getOperator()->getAsString() + 31168d6d8abSJakob Stoklund Olesen "' in SubRegClasses is not a RegisterClass"; 31268d6d8abSJakob Stoklund Olesen // Iterate over args, all SubRegIndex instances. 31368d6d8abSJakob Stoklund Olesen for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end(); 31468d6d8abSJakob Stoklund Olesen ai != ae; ++ai) { 315af8ee2cdSDavid Greene DefInit *Idx = dynamic_cast<DefInit*>(*ai); 31668d6d8abSJakob Stoklund Olesen Record *IdxRec; 31768d6d8abSJakob Stoklund Olesen if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex")) 31868d6d8abSJakob Stoklund Olesen throw "Argument '" + (*ai)->getAsString() + 31968d6d8abSJakob Stoklund Olesen "' in SubRegClasses is not a SubRegIndex"; 32068d6d8abSJakob Stoklund Olesen if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second) 32168d6d8abSJakob Stoklund Olesen throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice"; 32268d6d8abSJakob Stoklund Olesen } 32368d6d8abSJakob Stoklund Olesen } 32468d6d8abSJakob Stoklund Olesen 32568d6d8abSJakob Stoklund Olesen // Allow targets to override the size in bits of the RegisterClass. 32668d6d8abSJakob Stoklund Olesen unsigned Size = R->getValueAsInt("Size"); 32768d6d8abSJakob Stoklund Olesen 32868d6d8abSJakob Stoklund Olesen Namespace = R->getValueAsString("Namespace"); 32968d6d8abSJakob Stoklund Olesen SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits(); 33068d6d8abSJakob Stoklund Olesen SpillAlignment = R->getValueAsInt("Alignment"); 33168d6d8abSJakob Stoklund Olesen CopyCost = R->getValueAsInt("CopyCost"); 33268d6d8abSJakob Stoklund Olesen Allocatable = R->getValueAsBit("isAllocatable"); 33335cea3daSJakob Stoklund Olesen AltOrderSelect = R->getValueAsCode("AltOrderSelect"); 33468d6d8abSJakob Stoklund Olesen } 33568d6d8abSJakob Stoklund Olesen 33603efe84dSJakob Stoklund Olesen // Create an inferred register class that was missing from the .td files. 33703efe84dSJakob Stoklund Olesen // Most properties will be inherited from the closest super-class after the 33803efe84dSJakob Stoklund Olesen // class structure has been computed. 33903efe84dSJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(StringRef Name, Key Props) 34003efe84dSJakob Stoklund Olesen : Members(*Props.Members), 34103efe84dSJakob Stoklund Olesen TheDef(0), 34203efe84dSJakob Stoklund Olesen Name(Name), 34303efe84dSJakob Stoklund Olesen EnumValue(-1), 34403efe84dSJakob Stoklund Olesen SpillSize(Props.SpillSize), 34503efe84dSJakob Stoklund Olesen SpillAlignment(Props.SpillAlignment), 34603efe84dSJakob Stoklund Olesen CopyCost(0), 34703efe84dSJakob Stoklund Olesen Allocatable(true) { 34803efe84dSJakob Stoklund Olesen } 34903efe84dSJakob Stoklund Olesen 35003efe84dSJakob Stoklund Olesen // Compute inherited propertied for a synthesized register class. 35103efe84dSJakob Stoklund Olesen void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) { 35203efe84dSJakob Stoklund Olesen assert(!getDef() && "Only synthesized classes can inherit properties"); 35303efe84dSJakob Stoklund Olesen assert(!SuperClasses.empty() && "Synthesized class without super class"); 35403efe84dSJakob Stoklund Olesen 35503efe84dSJakob Stoklund Olesen // The last super-class is the smallest one. 35603efe84dSJakob Stoklund Olesen CodeGenRegisterClass &Super = *SuperClasses.back(); 35703efe84dSJakob Stoklund Olesen 35803efe84dSJakob Stoklund Olesen // Most properties are copied directly. 35903efe84dSJakob Stoklund Olesen // Exceptions are members, size, and alignment 36003efe84dSJakob Stoklund Olesen Namespace = Super.Namespace; 36103efe84dSJakob Stoklund Olesen VTs = Super.VTs; 36203efe84dSJakob Stoklund Olesen CopyCost = Super.CopyCost; 36303efe84dSJakob Stoklund Olesen Allocatable = Super.Allocatable; 36403efe84dSJakob Stoklund Olesen AltOrderSelect = Super.AltOrderSelect; 36503efe84dSJakob Stoklund Olesen 36603efe84dSJakob Stoklund Olesen // Copy all allocation orders, filter out foreign registers from the larger 36703efe84dSJakob Stoklund Olesen // super-class. 36803efe84dSJakob Stoklund Olesen Orders.resize(Super.Orders.size()); 36903efe84dSJakob Stoklund Olesen for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i) 37003efe84dSJakob Stoklund Olesen for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j) 37103efe84dSJakob Stoklund Olesen if (contains(RegBank.getReg(Super.Orders[i][j]))) 37203efe84dSJakob Stoklund Olesen Orders[i].push_back(Super.Orders[i][j]); 37303efe84dSJakob Stoklund Olesen } 37403efe84dSJakob Stoklund Olesen 375d7bc5c26SJakob Stoklund Olesen bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { 376d7bc5c26SJakob Stoklund Olesen return Members.count(Reg); 377d7bc5c26SJakob Stoklund Olesen } 378d7bc5c26SJakob Stoklund Olesen 37903efe84dSJakob Stoklund Olesen namespace llvm { 38003efe84dSJakob Stoklund Olesen raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) { 38103efe84dSJakob Stoklund Olesen OS << "{ S=" << K.SpillSize << ", A=" << K.SpillAlignment; 38203efe84dSJakob Stoklund Olesen for (CodeGenRegister::Set::const_iterator I = K.Members->begin(), 38303efe84dSJakob Stoklund Olesen E = K.Members->end(); I != E; ++I) 38403efe84dSJakob Stoklund Olesen OS << ", " << (*I)->getName(); 38503efe84dSJakob Stoklund Olesen return OS << " }"; 38603efe84dSJakob Stoklund Olesen } 38703efe84dSJakob Stoklund Olesen } 38803efe84dSJakob Stoklund Olesen 38903efe84dSJakob Stoklund Olesen // This is a simple lexicographical order that can be used to search for sets. 39003efe84dSJakob Stoklund Olesen // It is not the same as the topological order provided by TopoOrderRC. 39103efe84dSJakob Stoklund Olesen bool CodeGenRegisterClass::Key:: 39203efe84dSJakob Stoklund Olesen operator<(const CodeGenRegisterClass::Key &B) const { 39303efe84dSJakob Stoklund Olesen assert(Members && B.Members); 39403efe84dSJakob Stoklund Olesen if (*Members != *B.Members) 39503efe84dSJakob Stoklund Olesen return *Members < *B.Members; 39603efe84dSJakob Stoklund Olesen if (SpillSize != B.SpillSize) 39703efe84dSJakob Stoklund Olesen return SpillSize < B.SpillSize; 39803efe84dSJakob Stoklund Olesen return SpillAlignment < B.SpillAlignment; 39903efe84dSJakob Stoklund Olesen } 40003efe84dSJakob Stoklund Olesen 401d7bc5c26SJakob Stoklund Olesen // Returns true if RC is a strict subclass. 402d7bc5c26SJakob Stoklund Olesen // RC is a sub-class of this class if it is a valid replacement for any 403d7bc5c26SJakob Stoklund Olesen // instruction operand where a register of this classis required. It must 404d7bc5c26SJakob Stoklund Olesen // satisfy these conditions: 405d7bc5c26SJakob Stoklund Olesen // 406d7bc5c26SJakob Stoklund Olesen // 1. All RC registers are also in this. 407d7bc5c26SJakob Stoklund Olesen // 2. The RC spill size must not be smaller than our spill size. 408d7bc5c26SJakob Stoklund Olesen // 3. RC spill alignment must be compatible with ours. 409d7bc5c26SJakob Stoklund Olesen // 4106417395dSJakob Stoklund Olesen static bool testSubClass(const CodeGenRegisterClass *A, 4116417395dSJakob Stoklund Olesen const CodeGenRegisterClass *B) { 4126417395dSJakob Stoklund Olesen return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 && 4136417395dSJakob Stoklund Olesen A->SpillSize <= B->SpillSize && 4146417395dSJakob Stoklund Olesen std::includes(A->getMembers().begin(), A->getMembers().end(), 4156417395dSJakob Stoklund Olesen B->getMembers().begin(), B->getMembers().end(), 416afef4222SJakob Stoklund Olesen CodeGenRegister::Less()); 417d7bc5c26SJakob Stoklund Olesen } 418d7bc5c26SJakob Stoklund Olesen 419c0fc173dSJakob Stoklund Olesen /// Sorting predicate for register classes. This provides a topological 420c0fc173dSJakob Stoklund Olesen /// ordering that arranges all register classes before their sub-classes. 421c0fc173dSJakob Stoklund Olesen /// 422c0fc173dSJakob Stoklund Olesen /// Register classes with the same registers, spill size, and alignment form a 423c0fc173dSJakob Stoklund Olesen /// clique. They will be ordered alphabetically. 424c0fc173dSJakob Stoklund Olesen /// 425c0fc173dSJakob Stoklund Olesen static int TopoOrderRC(const void *PA, const void *PB) { 426c0fc173dSJakob Stoklund Olesen const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA; 427c0fc173dSJakob Stoklund Olesen const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB; 428c0fc173dSJakob Stoklund Olesen if (A == B) 429c0fc173dSJakob Stoklund Olesen return 0; 430c0fc173dSJakob Stoklund Olesen 43103efe84dSJakob Stoklund Olesen // Order by descending set size. Note that the classes' allocation order may 43203efe84dSJakob Stoklund Olesen // not have been computed yet. The Members set is always vaild. 43303efe84dSJakob Stoklund Olesen if (A->getMembers().size() > B->getMembers().size()) 434c0fc173dSJakob Stoklund Olesen return -1; 43503efe84dSJakob Stoklund Olesen if (A->getMembers().size() < B->getMembers().size()) 436c0fc173dSJakob Stoklund Olesen return 1; 437c0fc173dSJakob Stoklund Olesen 438c0fc173dSJakob Stoklund Olesen // Order by ascending spill size. 439c0fc173dSJakob Stoklund Olesen if (A->SpillSize < B->SpillSize) 440c0fc173dSJakob Stoklund Olesen return -1; 441c0fc173dSJakob Stoklund Olesen if (A->SpillSize > B->SpillSize) 442c0fc173dSJakob Stoklund Olesen return 1; 443c0fc173dSJakob Stoklund Olesen 444c0fc173dSJakob Stoklund Olesen // Order by ascending spill alignment. 445c0fc173dSJakob Stoklund Olesen if (A->SpillAlignment < B->SpillAlignment) 446c0fc173dSJakob Stoklund Olesen return -1; 447c0fc173dSJakob Stoklund Olesen if (A->SpillAlignment > B->SpillAlignment) 448c0fc173dSJakob Stoklund Olesen return 1; 449c0fc173dSJakob Stoklund Olesen 450c0fc173dSJakob Stoklund Olesen // Finally order by name as a tie breaker. 451c0fc173dSJakob Stoklund Olesen return A->getName() < B->getName(); 452c0fc173dSJakob Stoklund Olesen } 453c0fc173dSJakob Stoklund Olesen 454bd92dc60SJakob Stoklund Olesen std::string CodeGenRegisterClass::getQualifiedName() const { 455bd92dc60SJakob Stoklund Olesen if (Namespace.empty()) 456bd92dc60SJakob Stoklund Olesen return getName(); 457bd92dc60SJakob Stoklund Olesen else 458bd92dc60SJakob Stoklund Olesen return Namespace + "::" + getName(); 45968d6d8abSJakob Stoklund Olesen } 46068d6d8abSJakob Stoklund Olesen 4612c024b2dSJakob Stoklund Olesen // Compute sub-classes of all register classes. 4622c024b2dSJakob Stoklund Olesen // Assume the classes are ordered topologically. 46303efe84dSJakob Stoklund Olesen void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) { 46403efe84dSJakob Stoklund Olesen ArrayRef<CodeGenRegisterClass*> RegClasses = RegBank.getRegClasses(); 46503efe84dSJakob Stoklund Olesen 4662c024b2dSJakob Stoklund Olesen // Visit backwards so sub-classes are seen first. 4672c024b2dSJakob Stoklund Olesen for (unsigned rci = RegClasses.size(); rci; --rci) { 4682c024b2dSJakob Stoklund Olesen CodeGenRegisterClass &RC = *RegClasses[rci - 1]; 4692c024b2dSJakob Stoklund Olesen RC.SubClasses.resize(RegClasses.size()); 4702c024b2dSJakob Stoklund Olesen RC.SubClasses.set(RC.EnumValue); 4712c024b2dSJakob Stoklund Olesen 4722c024b2dSJakob Stoklund Olesen // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. 4732c024b2dSJakob Stoklund Olesen for (unsigned s = rci; s != RegClasses.size(); ++s) { 4742c024b2dSJakob Stoklund Olesen if (RC.SubClasses.test(s)) 4752c024b2dSJakob Stoklund Olesen continue; 4762c024b2dSJakob Stoklund Olesen CodeGenRegisterClass *SubRC = RegClasses[s]; 4776417395dSJakob Stoklund Olesen if (!testSubClass(&RC, SubRC)) 4782c024b2dSJakob Stoklund Olesen continue; 4792c024b2dSJakob Stoklund Olesen // SubRC is a sub-class. Grap all its sub-classes so we won't have to 4802c024b2dSJakob Stoklund Olesen // check them again. 4812c024b2dSJakob Stoklund Olesen RC.SubClasses |= SubRC->SubClasses; 4822c024b2dSJakob Stoklund Olesen } 4832c024b2dSJakob Stoklund Olesen 4842c024b2dSJakob Stoklund Olesen // Sweep up missed clique members. They will be immediately preceeding RC. 4856417395dSJakob Stoklund Olesen for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s) 4862c024b2dSJakob Stoklund Olesen RC.SubClasses.set(s - 1); 4872c024b2dSJakob Stoklund Olesen } 488b15fad9dSJakob Stoklund Olesen 489b15fad9dSJakob Stoklund Olesen // Compute the SuperClasses lists from the SubClasses vectors. 490b15fad9dSJakob Stoklund Olesen for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { 491b15fad9dSJakob Stoklund Olesen const BitVector &SC = RegClasses[rci]->getSubClasses(); 492b15fad9dSJakob Stoklund Olesen for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) { 493b15fad9dSJakob Stoklund Olesen if (unsigned(s) == rci) 494b15fad9dSJakob Stoklund Olesen continue; 495b15fad9dSJakob Stoklund Olesen RegClasses[s]->SuperClasses.push_back(RegClasses[rci]); 496b15fad9dSJakob Stoklund Olesen } 497b15fad9dSJakob Stoklund Olesen } 49803efe84dSJakob Stoklund Olesen 49903efe84dSJakob Stoklund Olesen // With the class hierarchy in place, let synthesized register classes inherit 50003efe84dSJakob Stoklund Olesen // properties from their closest super-class. The iteration order here can 50103efe84dSJakob Stoklund Olesen // propagate properties down multiple levels. 50203efe84dSJakob Stoklund Olesen for (unsigned rci = 0; rci != RegClasses.size(); ++rci) 50303efe84dSJakob Stoklund Olesen if (!RegClasses[rci]->getDef()) 50403efe84dSJakob Stoklund Olesen RegClasses[rci]->inheritProperties(RegBank); 5052c024b2dSJakob Stoklund Olesen } 5062c024b2dSJakob Stoklund Olesen 50776a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 50876a5a71eSJakob Stoklund Olesen // CodeGenRegBank 50976a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 51076a5a71eSJakob Stoklund Olesen 51176a5a71eSJakob Stoklund Olesen CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { 5123bd1b65eSJakob Stoklund Olesen // Configure register Sets to understand register classes and tuples. 5135ee87726SJakob Stoklund Olesen Sets.addFieldExpander("RegisterClass", "MemberList"); 5143bd1b65eSJakob Stoklund Olesen Sets.addExpander("RegisterTuples", new TupleExpander()); 5155ee87726SJakob Stoklund Olesen 51684bd44ebSJakob Stoklund Olesen // Read in the user-defined (named) sub-register indices. 51784bd44ebSJakob Stoklund Olesen // More indices will be synthesized later. 51876a5a71eSJakob Stoklund Olesen SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex"); 51976a5a71eSJakob Stoklund Olesen std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord()); 52076a5a71eSJakob Stoklund Olesen NumNamedIndices = SubRegIndices.size(); 52184bd44ebSJakob Stoklund Olesen 52284bd44ebSJakob Stoklund Olesen // Read in the register definitions. 52384bd44ebSJakob Stoklund Olesen std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); 52484bd44ebSJakob Stoklund Olesen std::sort(Regs.begin(), Regs.end(), LessRecord()); 52584bd44ebSJakob Stoklund Olesen Registers.reserve(Regs.size()); 52684bd44ebSJakob Stoklund Olesen // Assign the enumeration values. 52784bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Regs.size(); i != e; ++i) 5288e188be0SJakob Stoklund Olesen getReg(Regs[i]); 52922ea424dSJakob Stoklund Olesen 5303bd1b65eSJakob Stoklund Olesen // Expand tuples and number the new registers. 5313bd1b65eSJakob Stoklund Olesen std::vector<Record*> Tups = 5323bd1b65eSJakob Stoklund Olesen Records.getAllDerivedDefinitions("RegisterTuples"); 5333bd1b65eSJakob Stoklund Olesen for (unsigned i = 0, e = Tups.size(); i != e; ++i) { 5343bd1b65eSJakob Stoklund Olesen const std::vector<Record*> *TupRegs = Sets.expand(Tups[i]); 5353bd1b65eSJakob Stoklund Olesen for (unsigned j = 0, je = TupRegs->size(); j != je; ++j) 5363bd1b65eSJakob Stoklund Olesen getReg((*TupRegs)[j]); 5373bd1b65eSJakob Stoklund Olesen } 5383bd1b65eSJakob Stoklund Olesen 53903efe84dSJakob Stoklund Olesen // Precompute all sub-register maps now all the registers are known. 54003efe84dSJakob Stoklund Olesen // This will create Composite entries for all inferred sub-register indices. 54103efe84dSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) 54203efe84dSJakob Stoklund Olesen Registers[i]->getSubRegs(*this); 54303efe84dSJakob Stoklund Olesen 54422ea424dSJakob Stoklund Olesen // Read in register class definitions. 54522ea424dSJakob Stoklund Olesen std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass"); 54622ea424dSJakob Stoklund Olesen if (RCs.empty()) 54722ea424dSJakob Stoklund Olesen throw std::string("No 'RegisterClass' subclasses defined!"); 54822ea424dSJakob Stoklund Olesen 54903efe84dSJakob Stoklund Olesen // Allocate user-defined register classes. 55022ea424dSJakob Stoklund Olesen RegClasses.reserve(RCs.size()); 55103efe84dSJakob Stoklund Olesen for (unsigned i = 0, e = RCs.size(); i != e; ++i) 55203efe84dSJakob Stoklund Olesen addToMaps(new CodeGenRegisterClass(*this, RCs[i])); 55303efe84dSJakob Stoklund Olesen 55403efe84dSJakob Stoklund Olesen // Infer missing classes to create a full algebra. 55503efe84dSJakob Stoklund Olesen computeInferredRegisterClasses(); 55603efe84dSJakob Stoklund Olesen 557c0fc173dSJakob Stoklund Olesen // Order register classes topologically and assign enum values. 558c0fc173dSJakob Stoklund Olesen array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC); 559c0fc173dSJakob Stoklund Olesen for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) 560c0fc173dSJakob Stoklund Olesen RegClasses[i]->EnumValue = i; 56103efe84dSJakob Stoklund Olesen CodeGenRegisterClass::computeSubClasses(*this); 56276a5a71eSJakob Stoklund Olesen } 56376a5a71eSJakob Stoklund Olesen 56484bd44ebSJakob Stoklund Olesen CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { 5658e188be0SJakob Stoklund Olesen CodeGenRegister *&Reg = Def2Reg[Def]; 5668e188be0SJakob Stoklund Olesen if (Reg) 56784bd44ebSJakob Stoklund Olesen return Reg; 5688e188be0SJakob Stoklund Olesen Reg = new CodeGenRegister(Def, Registers.size() + 1); 5698e188be0SJakob Stoklund Olesen Registers.push_back(Reg); 5708e188be0SJakob Stoklund Olesen return Reg; 57184bd44ebSJakob Stoklund Olesen } 57284bd44ebSJakob Stoklund Olesen 57303efe84dSJakob Stoklund Olesen void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) { 57403efe84dSJakob Stoklund Olesen RegClasses.push_back(RC); 57503efe84dSJakob Stoklund Olesen 57603efe84dSJakob Stoklund Olesen if (Record *Def = RC->getDef()) 57703efe84dSJakob Stoklund Olesen Def2RC.insert(std::make_pair(Def, RC)); 57803efe84dSJakob Stoklund Olesen 57903efe84dSJakob Stoklund Olesen // Duplicate classes are rejected by insert(). 58003efe84dSJakob Stoklund Olesen // That's OK, we only care about the properties handled by CGRC::Key. 58103efe84dSJakob Stoklund Olesen CodeGenRegisterClass::Key K(*RC); 58203efe84dSJakob Stoklund Olesen Key2RC.insert(std::make_pair(K, RC)); 58303efe84dSJakob Stoklund Olesen } 58403efe84dSJakob Stoklund Olesen 5857ebc6b05SJakob Stoklund Olesen // Create a synthetic sub-class if it is missing. 5867ebc6b05SJakob Stoklund Olesen CodeGenRegisterClass* 5877ebc6b05SJakob Stoklund Olesen CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC, 5887ebc6b05SJakob Stoklund Olesen const CodeGenRegister::Set *Members, 5897ebc6b05SJakob Stoklund Olesen StringRef Name) { 5907ebc6b05SJakob Stoklund Olesen // Synthetic sub-class has the same size and alignment as RC. 5917ebc6b05SJakob Stoklund Olesen CodeGenRegisterClass::Key K(Members, RC->SpillSize, RC->SpillAlignment); 5927ebc6b05SJakob Stoklund Olesen RCKeyMap::const_iterator FoundI = Key2RC.find(K); 5937ebc6b05SJakob Stoklund Olesen if (FoundI != Key2RC.end()) 5947ebc6b05SJakob Stoklund Olesen return FoundI->second; 5957ebc6b05SJakob Stoklund Olesen 5967ebc6b05SJakob Stoklund Olesen // Sub-class doesn't exist, create a new one. 5977ebc6b05SJakob Stoklund Olesen CodeGenRegisterClass *NewRC = new CodeGenRegisterClass(Name, K); 5987ebc6b05SJakob Stoklund Olesen addToMaps(NewRC); 5997ebc6b05SJakob Stoklund Olesen return NewRC; 6007ebc6b05SJakob Stoklund Olesen } 6017ebc6b05SJakob Stoklund Olesen 60222ea424dSJakob Stoklund Olesen CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { 60322ea424dSJakob Stoklund Olesen if (CodeGenRegisterClass *RC = Def2RC[Def]) 60422ea424dSJakob Stoklund Olesen return RC; 60522ea424dSJakob Stoklund Olesen 60622ea424dSJakob Stoklund Olesen throw TGError(Def->getLoc(), "Not a known RegisterClass!"); 60722ea424dSJakob Stoklund Olesen } 60822ea424dSJakob Stoklund Olesen 60984bd44ebSJakob Stoklund Olesen Record *CodeGenRegBank::getCompositeSubRegIndex(Record *A, Record *B, 61084bd44ebSJakob Stoklund Olesen bool create) { 61184bd44ebSJakob Stoklund Olesen // Look for an existing entry. 61284bd44ebSJakob Stoklund Olesen Record *&Comp = Composite[std::make_pair(A, B)]; 61384bd44ebSJakob Stoklund Olesen if (Comp || !create) 61484bd44ebSJakob Stoklund Olesen return Comp; 61584bd44ebSJakob Stoklund Olesen 61684bd44ebSJakob Stoklund Olesen // None exists, synthesize one. 61776a5a71eSJakob Stoklund Olesen std::string Name = A->getName() + "_then_" + B->getName(); 61884bd44ebSJakob Stoklund Olesen Comp = new Record(Name, SMLoc(), Records); 61984bd44ebSJakob Stoklund Olesen SubRegIndices.push_back(Comp); 62084bd44ebSJakob Stoklund Olesen return Comp; 62176a5a71eSJakob Stoklund Olesen } 62276a5a71eSJakob Stoklund Olesen 62376a5a71eSJakob Stoklund Olesen unsigned CodeGenRegBank::getSubRegIndexNo(Record *idx) { 62476a5a71eSJakob Stoklund Olesen std::vector<Record*>::const_iterator i = 62576a5a71eSJakob Stoklund Olesen std::find(SubRegIndices.begin(), SubRegIndices.end(), idx); 62676a5a71eSJakob Stoklund Olesen assert(i != SubRegIndices.end() && "Not a SubRegIndex"); 62776a5a71eSJakob Stoklund Olesen return (i - SubRegIndices.begin()) + 1; 62876a5a71eSJakob Stoklund Olesen } 62976a5a71eSJakob Stoklund Olesen 63084bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeComposites() { 63184bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 6328e188be0SJakob Stoklund Olesen CodeGenRegister *Reg1 = Registers[i]; 633d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs(); 63484bd44ebSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(), 63584bd44ebSJakob Stoklund Olesen e1 = SRM1.end(); i1 != e1; ++i1) { 63684bd44ebSJakob Stoklund Olesen Record *Idx1 = i1->first; 63784bd44ebSJakob Stoklund Olesen CodeGenRegister *Reg2 = i1->second; 63884bd44ebSJakob Stoklund Olesen // Ignore identity compositions. 63984bd44ebSJakob Stoklund Olesen if (Reg1 == Reg2) 64084bd44ebSJakob Stoklund Olesen continue; 641d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs(); 64284bd44ebSJakob Stoklund Olesen // Try composing Idx1 with another SubRegIndex. 64384bd44ebSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM2.begin(), 64484bd44ebSJakob Stoklund Olesen e2 = SRM2.end(); i2 != e2; ++i2) { 64584bd44ebSJakob Stoklund Olesen std::pair<Record*, Record*> IdxPair(Idx1, i2->first); 64684bd44ebSJakob Stoklund Olesen CodeGenRegister *Reg3 = i2->second; 64784bd44ebSJakob Stoklund Olesen // Ignore identity compositions. 64884bd44ebSJakob Stoklund Olesen if (Reg2 == Reg3) 64984bd44ebSJakob Stoklund Olesen continue; 65084bd44ebSJakob Stoklund Olesen // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3. 65184bd44ebSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i1d = SRM1.begin(), 65284bd44ebSJakob Stoklund Olesen e1d = SRM1.end(); i1d != e1d; ++i1d) { 65384bd44ebSJakob Stoklund Olesen if (i1d->second == Reg3) { 65484bd44ebSJakob Stoklund Olesen std::pair<CompositeMap::iterator, bool> Ins = 65584bd44ebSJakob Stoklund Olesen Composite.insert(std::make_pair(IdxPair, i1d->first)); 65684bd44ebSJakob Stoklund Olesen // Conflicting composition? Emit a warning but allow it. 65784bd44ebSJakob Stoklund Olesen if (!Ins.second && Ins.first->second != i1d->first) { 65884bd44ebSJakob Stoklund Olesen errs() << "Warning: SubRegIndex " << getQualifiedName(Idx1) 65984bd44ebSJakob Stoklund Olesen << " and " << getQualifiedName(IdxPair.second) 66084bd44ebSJakob Stoklund Olesen << " compose ambiguously as " 66184bd44ebSJakob Stoklund Olesen << getQualifiedName(Ins.first->second) << " or " 66284bd44ebSJakob Stoklund Olesen << getQualifiedName(i1d->first) << "\n"; 66384bd44ebSJakob Stoklund Olesen } 66484bd44ebSJakob Stoklund Olesen } 66584bd44ebSJakob Stoklund Olesen } 66684bd44ebSJakob Stoklund Olesen } 66784bd44ebSJakob Stoklund Olesen } 66884bd44ebSJakob Stoklund Olesen } 66984bd44ebSJakob Stoklund Olesen 67084bd44ebSJakob Stoklund Olesen // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid 67184bd44ebSJakob Stoklund Olesen // compositions, so remove any mappings of that form. 67284bd44ebSJakob Stoklund Olesen for (CompositeMap::iterator i = Composite.begin(), e = Composite.end(); 67384bd44ebSJakob Stoklund Olesen i != e;) { 67484bd44ebSJakob Stoklund Olesen CompositeMap::iterator j = i; 67584bd44ebSJakob Stoklund Olesen ++i; 67684bd44ebSJakob Stoklund Olesen if (j->first.second == j->second) 67784bd44ebSJakob Stoklund Olesen Composite.erase(j); 67884bd44ebSJakob Stoklund Olesen } 67984bd44ebSJakob Stoklund Olesen } 68084bd44ebSJakob Stoklund Olesen 681d2b4713eSJakob Stoklund Olesen // Compute sets of overlapping registers. 682d2b4713eSJakob Stoklund Olesen // 683d2b4713eSJakob Stoklund Olesen // The standard set is all super-registers and all sub-registers, but the 684d2b4713eSJakob Stoklund Olesen // target description can add arbitrary overlapping registers via the 'Aliases' 685d2b4713eSJakob Stoklund Olesen // field. This complicates things, but we can compute overlapping sets using 686d2b4713eSJakob Stoklund Olesen // the following rules: 687d2b4713eSJakob Stoklund Olesen // 688d2b4713eSJakob Stoklund Olesen // 1. The relation overlap(A, B) is reflexive and symmetric but not transitive. 689d2b4713eSJakob Stoklund Olesen // 690d2b4713eSJakob Stoklund Olesen // 2. overlap(A, B) implies overlap(A, S) for all S in supers(B). 691d2b4713eSJakob Stoklund Olesen // 692d2b4713eSJakob Stoklund Olesen // Alternatively: 693d2b4713eSJakob Stoklund Olesen // 694d2b4713eSJakob Stoklund Olesen // overlap(A, B) iff there exists: 695d2b4713eSJakob Stoklund Olesen // A' in { A, subregs(A) } and B' in { B, subregs(B) } such that: 696d2b4713eSJakob Stoklund Olesen // A' = B' or A' in aliases(B') or B' in aliases(A'). 697d2b4713eSJakob Stoklund Olesen // 698d2b4713eSJakob Stoklund Olesen // Here subregs(A) is the full flattened sub-register set returned by 699d2b4713eSJakob Stoklund Olesen // A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the 700d2b4713eSJakob Stoklund Olesen // description of register A. 701d2b4713eSJakob Stoklund Olesen // 702d2b4713eSJakob Stoklund Olesen // This also implies that registers with a common sub-register are considered 703d2b4713eSJakob Stoklund Olesen // overlapping. This can happen when forming register pairs: 704d2b4713eSJakob Stoklund Olesen // 705d2b4713eSJakob Stoklund Olesen // P0 = (R0, R1) 706d2b4713eSJakob Stoklund Olesen // P1 = (R1, R2) 707d2b4713eSJakob Stoklund Olesen // P2 = (R2, R3) 708d2b4713eSJakob Stoklund Olesen // 709d2b4713eSJakob Stoklund Olesen // In this case, we will infer an overlap between P0 and P1 because of the 710d2b4713eSJakob Stoklund Olesen // shared sub-register R1. There is no overlap between P0 and P2. 711d2b4713eSJakob Stoklund Olesen // 712d2b4713eSJakob Stoklund Olesen void CodeGenRegBank:: 713d2b4713eSJakob Stoklund Olesen computeOverlaps(std::map<const CodeGenRegister*, CodeGenRegister::Set> &Map) { 714d2b4713eSJakob Stoklund Olesen assert(Map.empty()); 715d2b4713eSJakob Stoklund Olesen 716d2b4713eSJakob Stoklund Olesen // Collect overlaps that don't follow from rule 2. 717d2b4713eSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 7188e188be0SJakob Stoklund Olesen CodeGenRegister *Reg = Registers[i]; 719d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps = Map[Reg]; 720d2b4713eSJakob Stoklund Olesen 721d2b4713eSJakob Stoklund Olesen // Reg overlaps itself. 722d2b4713eSJakob Stoklund Olesen Overlaps.insert(Reg); 723d2b4713eSJakob Stoklund Olesen 724d2b4713eSJakob Stoklund Olesen // All super-registers overlap. 725d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SuperRegList &Supers = Reg->getSuperRegs(); 726d2b4713eSJakob Stoklund Olesen Overlaps.insert(Supers.begin(), Supers.end()); 727d2b4713eSJakob Stoklund Olesen 728d2b4713eSJakob Stoklund Olesen // Form symmetrical relations from the special Aliases[] lists. 729d2b4713eSJakob Stoklund Olesen std::vector<Record*> RegList = Reg->TheDef->getValueAsListOfDefs("Aliases"); 730d2b4713eSJakob Stoklund Olesen for (unsigned i2 = 0, e2 = RegList.size(); i2 != e2; ++i2) { 731d2b4713eSJakob Stoklund Olesen CodeGenRegister *Reg2 = getReg(RegList[i2]); 732d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps2 = Map[Reg2]; 733d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SuperRegList &Supers2 = Reg2->getSuperRegs(); 734d2b4713eSJakob Stoklund Olesen // Reg overlaps Reg2 which implies it overlaps supers(Reg2). 735d2b4713eSJakob Stoklund Olesen Overlaps.insert(Reg2); 736d2b4713eSJakob Stoklund Olesen Overlaps.insert(Supers2.begin(), Supers2.end()); 737d2b4713eSJakob Stoklund Olesen Overlaps2.insert(Reg); 738d2b4713eSJakob Stoklund Olesen Overlaps2.insert(Supers.begin(), Supers.end()); 739d2b4713eSJakob Stoklund Olesen } 740d2b4713eSJakob Stoklund Olesen } 741d2b4713eSJakob Stoklund Olesen 742d2b4713eSJakob Stoklund Olesen // Apply rule 2. and inherit all sub-register overlaps. 743d2b4713eSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 7448e188be0SJakob Stoklund Olesen CodeGenRegister *Reg = Registers[i]; 745d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps = Map[Reg]; 746d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs(); 747d2b4713eSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM.begin(), 748d2b4713eSJakob Stoklund Olesen e2 = SRM.end(); i2 != e2; ++i2) { 749d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps2 = Map[i2->second]; 750d2b4713eSJakob Stoklund Olesen Overlaps.insert(Overlaps2.begin(), Overlaps2.end()); 751d2b4713eSJakob Stoklund Olesen } 752d2b4713eSJakob Stoklund Olesen } 753d2b4713eSJakob Stoklund Olesen } 754d2b4713eSJakob Stoklund Olesen 75584bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeDerivedInfo() { 75684bd44ebSJakob Stoklund Olesen computeComposites(); 75784bd44ebSJakob Stoklund Olesen } 75884bd44ebSJakob Stoklund Olesen 759c0f97e3dSJakob Stoklund Olesen // 760c0f97e3dSJakob Stoklund Olesen // Synthesize missing register class intersections. 761c0f97e3dSJakob Stoklund Olesen // 762c0f97e3dSJakob Stoklund Olesen // Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X) 763c0f97e3dSJakob Stoklund Olesen // returns a maximal register class for all X. 764c0f97e3dSJakob Stoklund Olesen // 765c0f97e3dSJakob Stoklund Olesen void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) { 766c0f97e3dSJakob Stoklund Olesen for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) { 767c0f97e3dSJakob Stoklund Olesen CodeGenRegisterClass *RC1 = RC; 768c0f97e3dSJakob Stoklund Olesen CodeGenRegisterClass *RC2 = RegClasses[rci]; 769c0f97e3dSJakob Stoklund Olesen if (RC1 == RC2) 770c0f97e3dSJakob Stoklund Olesen continue; 771c0f97e3dSJakob Stoklund Olesen 772c0f97e3dSJakob Stoklund Olesen // Compute the set intersection of RC1 and RC2. 773c0f97e3dSJakob Stoklund Olesen const CodeGenRegister::Set &Memb1 = RC1->getMembers(); 774c0f97e3dSJakob Stoklund Olesen const CodeGenRegister::Set &Memb2 = RC2->getMembers(); 775c0f97e3dSJakob Stoklund Olesen CodeGenRegister::Set Intersection; 776c0f97e3dSJakob Stoklund Olesen std::set_intersection(Memb1.begin(), Memb1.end(), 777c0f97e3dSJakob Stoklund Olesen Memb2.begin(), Memb2.end(), 778*f94cd193SJakob Stoklund Olesen std::inserter(Intersection, Intersection.begin()), 779*f94cd193SJakob Stoklund Olesen CodeGenRegister::Less()); 780c0f97e3dSJakob Stoklund Olesen 781c0f97e3dSJakob Stoklund Olesen // Skip disjoint class pairs. 782c0f97e3dSJakob Stoklund Olesen if (Intersection.empty()) 783c0f97e3dSJakob Stoklund Olesen continue; 784c0f97e3dSJakob Stoklund Olesen 785c0f97e3dSJakob Stoklund Olesen // If RC1 and RC2 have different spill sizes or alignments, use the 786c0f97e3dSJakob Stoklund Olesen // larger size for sub-classing. If they are equal, prefer RC1. 787c0f97e3dSJakob Stoklund Olesen if (RC2->SpillSize > RC1->SpillSize || 788c0f97e3dSJakob Stoklund Olesen (RC2->SpillSize == RC1->SpillSize && 789c0f97e3dSJakob Stoklund Olesen RC2->SpillAlignment > RC1->SpillAlignment)) 790c0f97e3dSJakob Stoklund Olesen std::swap(RC1, RC2); 791c0f97e3dSJakob Stoklund Olesen 792c0f97e3dSJakob Stoklund Olesen getOrCreateSubClass(RC1, &Intersection, 793c0f97e3dSJakob Stoklund Olesen RC1->getName() + "_and_" + RC2->getName()); 794c0f97e3dSJakob Stoklund Olesen } 795c0f97e3dSJakob Stoklund Olesen } 796c0f97e3dSJakob Stoklund Olesen 79703efe84dSJakob Stoklund Olesen // Infer missing register classes. 79803efe84dSJakob Stoklund Olesen // 79903efe84dSJakob Stoklund Olesen // For every register class RC, make sure that the set of registers in RC with 80003efe84dSJakob Stoklund Olesen // a given SubIxx sub-register form a register class. 80103efe84dSJakob Stoklund Olesen void CodeGenRegBank::computeInferredRegisterClasses() { 80203efe84dSJakob Stoklund Olesen // When this function is called, the register classes have not been sorted 80303efe84dSJakob Stoklund Olesen // and assigned EnumValues yet. That means getSubClasses(), 80403efe84dSJakob Stoklund Olesen // getSuperClasses(), and hasSubClass() functions are defunct. 80503efe84dSJakob Stoklund Olesen 80603efe84dSJakob Stoklund Olesen // Map SubRegIndex to register set. 80703efe84dSJakob Stoklund Olesen typedef std::map<Record*, CodeGenRegister::Set, LessRecord> SubReg2SetMap; 80803efe84dSJakob Stoklund Olesen 80903efe84dSJakob Stoklund Olesen // Visit all register classes, including the ones being added by the loop. 81003efe84dSJakob Stoklund Olesen for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { 81103efe84dSJakob Stoklund Olesen CodeGenRegisterClass &RC = *RegClasses[rci]; 81203efe84dSJakob Stoklund Olesen 81303efe84dSJakob Stoklund Olesen // Compute the set of registers supporting each SubRegIndex. 81403efe84dSJakob Stoklund Olesen SubReg2SetMap SRSets; 815b1147c46SJakob Stoklund Olesen for (CodeGenRegister::Set::const_iterator RI = RC.getMembers().begin(), 81603efe84dSJakob Stoklund Olesen RE = RC.getMembers().end(); RI != RE; ++RI) { 817b1147c46SJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM = (*RI)->getSubRegs(); 818b1147c46SJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(), 819b1147c46SJakob Stoklund Olesen E = SRM.end(); I != E; ++I) 82003efe84dSJakob Stoklund Olesen SRSets[I->first].insert(*RI); 82103efe84dSJakob Stoklund Olesen } 82203efe84dSJakob Stoklund Olesen 82303efe84dSJakob Stoklund Olesen // Find matching classes for all SRSets entries. Iterate in SubRegIndex 82403efe84dSJakob Stoklund Olesen // numerical order to visit synthetic indices last. 82503efe84dSJakob Stoklund Olesen for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { 8263a541b04SJakob Stoklund Olesen Record *SubIdx = SubRegIndices[sri]; 8273a541b04SJakob Stoklund Olesen SubReg2SetMap::const_iterator I = SRSets.find(SubIdx); 82803efe84dSJakob Stoklund Olesen // Unsupported SubRegIndex. Skip it. 82903efe84dSJakob Stoklund Olesen if (I == SRSets.end()) 83003efe84dSJakob Stoklund Olesen continue; 8313a541b04SJakob Stoklund Olesen // In most cases, all RC registers support the SubRegIndex. 8323a541b04SJakob Stoklund Olesen if (I->second.size() == RC.getMembers().size()) { 8333a541b04SJakob Stoklund Olesen RC.setSubClassWithSubReg(SubIdx, &RC); 83403efe84dSJakob Stoklund Olesen continue; 8353a541b04SJakob Stoklund Olesen } 83603efe84dSJakob Stoklund Olesen // This is a real subset. See if we have a matching class. 8377ebc6b05SJakob Stoklund Olesen CodeGenRegisterClass *SubRC = 8387ebc6b05SJakob Stoklund Olesen getOrCreateSubClass(&RC, &I->second, 8397ebc6b05SJakob Stoklund Olesen RC.getName() + "_with_" + I->first->getName()); 8407ebc6b05SJakob Stoklund Olesen RC.setSubClassWithSubReg(SubIdx, SubRC); 84103efe84dSJakob Stoklund Olesen } 842c0f97e3dSJakob Stoklund Olesen 843c0f97e3dSJakob Stoklund Olesen // Synthesize answers for getCommonSubClass(). 844c0f97e3dSJakob Stoklund Olesen inferCommonSubClass(&RC); 84503efe84dSJakob Stoklund Olesen } 84603efe84dSJakob Stoklund Olesen } 84703efe84dSJakob Stoklund Olesen 84822ea424dSJakob Stoklund Olesen /// getRegisterClassForRegister - Find the register class that contains the 84922ea424dSJakob Stoklund Olesen /// specified physical register. If the register is not in a register class, 85022ea424dSJakob Stoklund Olesen /// return null. If the register is in multiple classes, and the classes have a 85122ea424dSJakob Stoklund Olesen /// superset-subset relationship and the same set of types, return the 85222ea424dSJakob Stoklund Olesen /// superclass. Otherwise return null. 85322ea424dSJakob Stoklund Olesen const CodeGenRegisterClass* 85422ea424dSJakob Stoklund Olesen CodeGenRegBank::getRegClassForRegister(Record *R) { 855d7bc5c26SJakob Stoklund Olesen const CodeGenRegister *Reg = getReg(R); 85619be2ab3SJakob Stoklund Olesen ArrayRef<CodeGenRegisterClass*> RCs = getRegClasses(); 85722ea424dSJakob Stoklund Olesen const CodeGenRegisterClass *FoundRC = 0; 85822ea424dSJakob Stoklund Olesen for (unsigned i = 0, e = RCs.size(); i != e; ++i) { 85919be2ab3SJakob Stoklund Olesen const CodeGenRegisterClass &RC = *RCs[i]; 860d7bc5c26SJakob Stoklund Olesen if (!RC.contains(Reg)) 86122ea424dSJakob Stoklund Olesen continue; 86222ea424dSJakob Stoklund Olesen 86322ea424dSJakob Stoklund Olesen // If this is the first class that contains the register, 86422ea424dSJakob Stoklund Olesen // make a note of it and go on to the next class. 86522ea424dSJakob Stoklund Olesen if (!FoundRC) { 86622ea424dSJakob Stoklund Olesen FoundRC = &RC; 86722ea424dSJakob Stoklund Olesen continue; 86822ea424dSJakob Stoklund Olesen } 86922ea424dSJakob Stoklund Olesen 87022ea424dSJakob Stoklund Olesen // If a register's classes have different types, return null. 87122ea424dSJakob Stoklund Olesen if (RC.getValueTypes() != FoundRC->getValueTypes()) 87222ea424dSJakob Stoklund Olesen return 0; 87322ea424dSJakob Stoklund Olesen 87422ea424dSJakob Stoklund Olesen // Check to see if the previously found class that contains 87522ea424dSJakob Stoklund Olesen // the register is a subclass of the current class. If so, 87622ea424dSJakob Stoklund Olesen // prefer the superclass. 877d7bc5c26SJakob Stoklund Olesen if (RC.hasSubClass(FoundRC)) { 87822ea424dSJakob Stoklund Olesen FoundRC = &RC; 87922ea424dSJakob Stoklund Olesen continue; 88022ea424dSJakob Stoklund Olesen } 88122ea424dSJakob Stoklund Olesen 88222ea424dSJakob Stoklund Olesen // Check to see if the previously found class that contains 88322ea424dSJakob Stoklund Olesen // the register is a superclass of the current class. If so, 88422ea424dSJakob Stoklund Olesen // prefer the superclass. 885d7bc5c26SJakob Stoklund Olesen if (FoundRC->hasSubClass(&RC)) 88622ea424dSJakob Stoklund Olesen continue; 88722ea424dSJakob Stoklund Olesen 88822ea424dSJakob Stoklund Olesen // Multiple classes, and neither is a superclass of the other. 88922ea424dSJakob Stoklund Olesen // Return null. 89022ea424dSJakob Stoklund Olesen return 0; 89122ea424dSJakob Stoklund Olesen } 89222ea424dSJakob Stoklund Olesen return FoundRC; 89322ea424dSJakob Stoklund Olesen } 894