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