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