119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- CodeGenRegisters.cpp - Register and RegisterClass Info -------------===// 219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The LLVM Compiler Infrastructure 419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source 619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details. 719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file defines structures to encapsulate information gleaned from the 1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// target register and register class definitions. 1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "CodeGenRegisters.h" 1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "CodeGenTarget.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/TableGen/Error.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/SmallVector.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/STLExtras.h" 2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringExtras.h" 2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm; 2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// CodeGenRegister 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegister::CodeGenRegister(Record *R, unsigned Enum) 2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : TheDef(R), 3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EnumValue(Enum), 3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CostPerUse(R->getValueAsInt("CostPerUse")), 3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegsComplete(false) 3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{} 3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst std::string &CodeGenRegister::getName() const { 3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return TheDef->getName(); 3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace { 4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman struct Orphan { 4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *SubReg; 4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *First, *Second; 4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orphan(CodeGenRegister *r, Record *a, Record *b) 4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : SubReg(r), First(a), Second(b) {} 4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }; 4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst CodeGenRegister::SubRegMap & 4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { 5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Only compute this map once. 5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SubRegsComplete) 5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SubRegs; 5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegsComplete = true; 5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs"); 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); 5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SubList.size() != Indices.size()) 5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(TheDef->getLoc(), "Register " + getName() + 5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman " SubRegIndices doesn't match SubRegs"); 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // First insert the direct subregs and make sure they are fully indexed. 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = SubList.size(); i != e; ++i) { 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *SR = RegBank.getReg(SubList[i]); 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!SubRegs.insert(std::make_pair(Indices[i], SR)).second) 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(TheDef->getLoc(), "SubRegIndex " + Indices[i]->getName() + 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman " appears twice in Register " + getName()); 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Keep track of inherited subregs and how they can be reached. 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<Orphan, 8> Orphans; 7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Clone inherited subregs and place duplicate entries on Orphans. 7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Here the order is important - earlier subregs take precedence. 7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = SubList.size(); i != e; ++i) { 7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *SR = RegBank.getReg(SubList[i]); 7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const SubRegMap &Map = SR->getSubRegs(RegBank); 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add this as a super-register of SR now all sub-registers are in the list. 7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This creates a topological ordering, the exact order depends on the 8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // order getSubRegs is called on all registers. 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SR->SuperRegs.push_back(this); 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE; 8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++SI) { 8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!SubRegs.insert(*SI).second) 8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orphans.push_back(Orphan(SI->second, Indices[i], SI->first)); 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Noop sub-register indexes are possible, so avoid duplicates. 8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SI->second != SR) 9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SI->second->SuperRegs.push_back(this); 9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Process the composites. 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices"); 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Comps->size(); i != e; ++i) { 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i)); 9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!Pat) 9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(TheDef->getLoc(), "Invalid dag '" + 10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Comps->getElement(i)->getAsString() + 10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "' in CompositeIndices"); 10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator()); 10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) 10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + 10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Pat->getAsString()); 10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Resolve list of subreg indices into R2. 10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *R2 = this; 10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (DagInit::const_arg_iterator di = Pat->arg_begin(), 11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman de = Pat->arg_end(); di != de; ++di) { 11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefInit *IdxInit = dynamic_cast<DefInit*>(*di); 11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Pat->getAsString()); 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const SubRegMap &R2Subs = R2->getSubRegs(RegBank); 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegMap::const_iterator ni = R2Subs.find(IdxInit->getDef()); 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ni == R2Subs.end()) 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() + 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman " refers to bad index in " + R2->getName()); 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman R2 = ni->second; 12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Insert composite index. Allow overriding inherited indices etc. 12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegs[BaseIdxInit->getDef()] = R2; 12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // R2 is no longer an orphan. 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned j = 0, je = Orphans.size(); j != je; ++j) 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Orphans[j].SubReg == R2) 12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orphans[j].SubReg = 0; 13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Now Orphans contains the inherited subregisters without a direct index. 13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Create inferred indexes for all missing entries. 13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Orphans.size(); i != e; ++i) { 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orphan &O = Orphans[i]; 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!O.SubReg) 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second, true)] = 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman O.SubReg; 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SubRegs; 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegister::addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const { 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(SubRegsComplete && "Must precompute sub-registers"); 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Indices.size(); i != e; ++i) { 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *SR = SubRegs.find(Indices[i])->second; 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (OSet.insert(SR)) 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SR->addSubRegsPreOrder(OSet); 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// RegisterTuples 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// A RegisterTuples def is used to generate pseudo-registers from lists of 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// sub-registers. We provide a SetTheory expander class that returns the new 16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// registers. 16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace { 16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstruct TupleExpander : SetTheory::Expander { 16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void expand(SetTheory &ST, Record *Def, SetTheory::RecSet &Elts) { 16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> Indices = Def->getValueAsListOfDefs("SubRegIndices"); 16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Dim = Indices.size(); 16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ListInit *SubRegs = Def->getValueAsListInit("SubRegs"); 16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Dim != SubRegs->getSize()) 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(Def->getLoc(), "SubRegIndices and SubRegs size mismatch"); 17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Dim < 2) 17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(Def->getLoc(), "Tuples must have at least 2 sub-registers"); 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Evaluate the sub-register lists to be zipped. 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Length = ~0u; 17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SetTheory::RecSet, 4> Lists(Dim); 17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != Dim; ++i) { 17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST.evaluate(SubRegs->getElement(i), Lists[i]); 17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Length = std::min(Length, unsigned(Lists[i].size())); 17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Length == 0) 18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return; 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Precompute some types. 18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *RegisterCl = Def->getRecords().getClass("Register"); 18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RecTy *RegisterRecTy = RecordRecTy::get(RegisterCl); 18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StringInit *BlankName = StringInit::get(""); 18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Zip them up. 19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned n = 0; n != Length; ++n) { 19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::string Name; 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *Proto = Lists[0][n]; 19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Init*> Tuple; 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned CostPerUse = 0; 19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != Dim; ++i) { 19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *Reg = Lists[i][n]; 19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (i) Name += '_'; 19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Name += Reg->getName(); 19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tuple.push_back(DefInit::get(Reg)); 20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CostPerUse = std::max(CostPerUse, 20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned(Reg->getValueAsInt("CostPerUse"))); 20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Create a new Record representing the synthesized register. This record 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // is only for consumption by CodeGenRegister, it is not added to the 20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // RecordKeeper. 20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *NewReg = new Record(Name, Def->getLoc(), Def->getRecords()); 20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Elts.insert(NewReg); 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Copy Proto super-classes. 21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i) 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewReg->addSuperClass(Proto->getSuperClasses()[i]); 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Copy Proto fields. 21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) { 21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RecordVal RV = Proto->getValues()[i]; 21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Replace the sub-register list with Tuple. 21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RV.getName() == "SubRegs") 22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RV.setValue(ListInit::get(Tuple, RegisterRecTy)); 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Provide a blank AsmName. MC hacks are required anyway. 22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RV.getName() == "AsmName") 22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RV.setValue(BlankName); 22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // CostPerUse is aggregated from all Tuple members. 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RV.getName() == "CostPerUse") 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RV.setValue(IntInit::get(CostPerUse)); 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Copy fields from the RegisterTuples def. 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RV.getName() == "SubRegIndices" || 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RV.getName() == "CompositeIndices") { 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewReg->addValue(*Def->getValue(RV.getName())); 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Some fields get their default uninitialized value. 23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RV.getName() == "DwarfNumbers" || 23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RV.getName() == "DwarfAlias" || 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RV.getName() == "Aliases") { 24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (const RecordVal *DefRV = RegisterCl->getValue(RV.getName())) 24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewReg->addValue(*DefRV); 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Everything else is copied from Proto. 24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewReg->addValue(RV); 24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}; 25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// CodeGenRegisterClass 25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) 25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : TheDef(R), Name(R->getName()), EnumValue(-1) { 26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Rename anonymous register classes. 26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (R->getName().size() > 9 && R->getName()[9] == '.') { 26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman static unsigned AnonCounter = 0; 26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman R->setName("AnonRegClass_"+utostr(AnonCounter++)); 26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes"); 26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { 26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *Type = TypeList[i]; 26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!Type->isSubClassOf("ValueType")) 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw "RegTypes list member '" + Type->getName() + 27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "' does not derive from the ValueType class!"; 27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VTs.push_back(getValueType(Type)); 27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); 27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Allocation order 0 is the full set. AltOrders provides others. 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const SetTheory::RecVec *Elements = RegBank.getSets().expand(R); 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ListInit *AltOrders = R->getValueAsListInit("AltOrders"); 27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orders.resize(1 + AltOrders->size()); 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Default allocation order always contains all registers. 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Elements->size(); i != e; ++i) { 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orders[0].push_back((*Elements)[i]); 28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Members.insert(RegBank.getReg((*Elements)[i])); 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Alternative allocation orders may be subsets. 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SetTheory::RecSet Order; 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) { 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegBank.getSets().evaluate(AltOrders->getElement(i), Order); 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orders[1 + i].append(Order.begin(), Order.end()); 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Verify that all altorder members are regclass members. 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (!Order.empty()) { 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg = RegBank.getReg(Order.back()); 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Order.pop_back(); 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!contains(Reg)) 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() + 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman " is not a class member"); 29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags. 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ListInit *SRC = R->getValueAsListInit("SubRegClasses"); 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) { 30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DagInit *DAG = dynamic_cast<DagInit*>(*i); 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!DAG) throw "SubRegClasses must contain DAGs"; 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator()); 30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *RCRec; 30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass")) 31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw "Operator '" + DAG->getOperator()->getAsString() + 31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "' in SubRegClasses is not a RegisterClass"; 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Iterate over args, all SubRegIndex instances. 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end(); 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ai != ae; ++ai) { 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DefInit *Idx = dynamic_cast<DefInit*>(*ai); 31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *IdxRec; 31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex")) 31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw "Argument '" + (*ai)->getAsString() + 31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "' in SubRegClasses is not a SubRegIndex"; 32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second) 32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice"; 32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Allow targets to override the size in bits of the RegisterClass. 32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Size = R->getValueAsInt("Size"); 32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Namespace = R->getValueAsString("Namespace"); 32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits(); 33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SpillAlignment = R->getValueAsInt("Alignment"); 33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CopyCost = R->getValueAsInt("CopyCost"); 33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Allocatable = R->getValueAsBit("isAllocatable"); 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AltOrderSelect = R->getValueAsCode("AltOrderSelect"); 33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Create an inferred register class that was missing from the .td files. 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Most properties will be inherited from the closest super-class after the 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// class structure has been computed. 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegisterClass::CodeGenRegisterClass(StringRef Name, Key Props) 34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : Members(*Props.Members), 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TheDef(0), 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Name(Name), 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EnumValue(-1), 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SpillSize(Props.SpillSize), 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SpillAlignment(Props.SpillAlignment), 34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CopyCost(0), 34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Allocatable(true) { 34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Compute inherited propertied for a synthesized register class. 35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) { 35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!getDef() && "Only synthesized classes can inherit properties"); 35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!SuperClasses.empty() && "Synthesized class without super class"); 35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The last super-class is the smallest one. 35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass &Super = *SuperClasses.back(); 35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Most properties are copied directly. 35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Exceptions are members, size, and alignment 36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Namespace = Super.Namespace; 36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VTs = Super.VTs; 36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CopyCost = Super.CopyCost; 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Allocatable = Super.Allocatable; 36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AltOrderSelect = Super.AltOrderSelect; 36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Copy all allocation orders, filter out foreign registers from the larger 36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // super-class. 36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orders.resize(Super.Orders.size()); 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i) 37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j) 37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (contains(RegBank.getReg(Super.Orders[i][j]))) 37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Orders[i].push_back(Super.Orders[i][j]); 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Members.count(Reg); 37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace llvm { 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman raw_ostream &operator<<(raw_ostream &OS, const CodeGenRegisterClass::Key &K) { 38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OS << "{ S=" << K.SpillSize << ", A=" << K.SpillAlignment; 38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::Set::const_iterator I = K.Members->begin(), 38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman E = K.Members->end(); I != E; ++I) 38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OS << ", " << (*I)->getName(); 38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return OS << " }"; 38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This is a simple lexicographical order that can be used to search for sets. 39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// It is not the same as the topological order provided by TopoOrderRC. 39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool CodeGenRegisterClass::Key:: 39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanoperator<(const CodeGenRegisterClass::Key &B) const { 39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Members && B.Members); 39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (*Members != *B.Members) 39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return *Members < *B.Members; 39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SpillSize != B.SpillSize) 39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SpillSize < B.SpillSize; 39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SpillAlignment < B.SpillAlignment; 39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Returns true if RC is a strict subclass. 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// RC is a sub-class of this class if it is a valid replacement for any 40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// instruction operand where a register of this classis required. It must 40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// satisfy these conditions: 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1. All RC registers are also in this. 40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 2. The RC spill size must not be smaller than our spill size. 40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 3. RC spill alignment must be compatible with ours. 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool testSubClass(const CodeGenRegisterClass *A, 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegisterClass *B) { 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return A->SpillAlignment && B->SpillAlignment % A->SpillAlignment == 0 && 41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman A->SpillSize <= B->SpillSize && 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::includes(A->getMembers().begin(), A->getMembers().end(), 41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman B->getMembers().begin(), B->getMembers().end(), 41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister::Less()); 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Sorting predicate for register classes. This provides a topological 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ordering that arranges all register classes before their sub-classes. 42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Register classes with the same registers, spill size, and alignment form a 42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// clique. They will be ordered alphabetically. 42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic int TopoOrderRC(const void *PA, const void *PB) { 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegisterClass *A = *(const CodeGenRegisterClass* const*)PA; 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegisterClass *B = *(const CodeGenRegisterClass* const*)PB; 42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A == B) 42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Order by descending set size. Note that the classes' allocation order may 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // not have been computed yet. The Members set is always vaild. 43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A->getMembers().size() > B->getMembers().size()) 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return -1; 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A->getMembers().size() < B->getMembers().size()) 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 1; 43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Order by ascending spill size. 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A->SpillSize < B->SpillSize) 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return -1; 44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A->SpillSize > B->SpillSize) 44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 1; 44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Order by ascending spill alignment. 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A->SpillAlignment < B->SpillAlignment) 44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return -1; 44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (A->SpillAlignment > B->SpillAlignment) 44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 1; 44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Finally order by name as a tie breaker. 45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return A->getName() < B->getName(); 45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstd::string CodeGenRegisterClass::getQualifiedName() const { 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Namespace.empty()) 45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return getName(); 45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Namespace + "::" + getName(); 45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Compute sub-classes of all register classes. 46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Assume the classes are ordered topologically. 46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) { 46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ArrayRef<CodeGenRegisterClass*> RegClasses = RegBank.getRegClasses(); 46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Visit backwards so sub-classes are seen first. 46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned rci = RegClasses.size(); rci; --rci) { 46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass &RC = *RegClasses[rci - 1]; 46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.SubClasses.resize(RegClasses.size()); 47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.SubClasses.set(RC.EnumValue); 47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned s = rci; s != RegClasses.size(); ++s) { 47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RC.SubClasses.test(s)) 47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass *SubRC = RegClasses[s]; 47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!testSubClass(&RC, SubRC)) 47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // SubRC is a sub-class. Grap all its sub-classes so we won't have to 48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // check them again. 48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.SubClasses |= SubRC->SubClasses; 48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Sweep up missed clique members. They will be immediately preceeding RC. 48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s) 48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.SubClasses.set(s - 1); 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute the SuperClasses lists from the SubClasses vectors. 49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { 49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const BitVector &SC = RegClasses[rci]->getSubClasses(); 49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) { 49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (unsigned(s) == rci) 49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegClasses[s]->SuperClasses.push_back(RegClasses[rci]); 49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // With the class hierarchy in place, let synthesized register classes inherit 50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // properties from their closest super-class. The iteration order here can 50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // propagate properties down multiple levels. 50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned rci = 0; rci != RegClasses.size(); ++rci) 50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!RegClasses[rci]->getDef()) 50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegClasses[rci]->inheritProperties(RegBank); 50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// CodeGenRegBank 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===// 51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { 51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Configure register Sets to understand register classes and tuples. 51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Sets.addFieldExpander("RegisterClass", "MemberList"); 51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Sets.addExpander("RegisterTuples", new TupleExpander()); 51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Read in the user-defined (named) sub-register indices. 51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // More indices will be synthesized later. 51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex"); 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord()); 52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NumNamedIndices = SubRegIndices.size(); 52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Read in the register definitions. 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); 52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::sort(Regs.begin(), Regs.end(), LessRecord()); 52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Registers.reserve(Regs.size()); 52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Assign the enumeration values. 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Regs.size(); i != e; ++i) 52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getReg(Regs[i]); 52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Expand tuples and number the new registers. 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> Tups = 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Records.getAllDerivedDefinitions("RegisterTuples"); 53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Tups.size(); i != e; ++i) { 53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const std::vector<Record*> *TupRegs = Sets.expand(Tups[i]); 53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned j = 0, je = TupRegs->size(); j != je; ++j) 53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman getReg((*TupRegs)[j]); 53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Precompute all sub-register maps now all the registers are known. 54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This will create Composite entries for all inferred sub-register indices. 54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Registers.size(); i != e; ++i) 54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Registers[i]->getSubRegs(*this); 54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Read in register class definitions. 54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass"); 54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RCs.empty()) 54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw std::string("No 'RegisterClass' subclasses defined!"); 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Allocate user-defined register classes. 55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegClasses.reserve(RCs.size()); 55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = RCs.size(); i != e; ++i) 55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman addToMaps(new CodeGenRegisterClass(*this, RCs[i])); 55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Infer missing classes to create a full algebra. 55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman computeInferredRegisterClasses(); 55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Order register classes topologically and assign enum values. 55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC); 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegClasses[i]->EnumValue = i; 56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass::computeSubClasses(*this); 56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegister *CodeGenRegBank::getReg(Record *Def) { 56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *&Reg = Def2Reg[Def]; 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg) 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Reg; 56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Reg = new CodeGenRegister(Def, Registers.size() + 1); 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Registers.push_back(Reg); 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Reg; 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) { 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegClasses.push_back(RC); 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Record *Def = RC->getDef()) 57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Def2RC.insert(std::make_pair(Def, RC)); 57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Duplicate classes are rejected by insert(). 58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // That's OK, we only care about the properties handled by CGRC::Key. 58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass::Key K(*RC); 58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Key2RC.insert(std::make_pair(K, RC)); 58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { 58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CodeGenRegisterClass *RC = Def2RC[Def]) 58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return RC; 58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman throw TGError(Def->getLoc(), "Not a known RegisterClass!"); 59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanRecord *CodeGenRegBank::getCompositeSubRegIndex(Record *A, Record *B, 59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool create) { 59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Look for an existing entry. 59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *&Comp = Composite[std::make_pair(A, B)]; 59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Comp || !create) 59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Comp; 59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // None exists, synthesize one. 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::string Name = A->getName() + "_then_" + B->getName(); 60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Comp = new Record(Name, SMLoc(), Records); 60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubRegIndices.push_back(Comp); 60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Comp; 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned CodeGenRegBank::getSubRegIndexNo(Record *idx) { 60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*>::const_iterator i = 60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::find(SubRegIndices.begin(), SubRegIndices.end(), idx); 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(i != SubRegIndices.end() && "Not a SubRegIndex"); 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return (i - SubRegIndices.begin()) + 1; 61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegBank::computeComposites() { 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg1 = Registers[i]; 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs(); 61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(), 61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e1 = SRM1.end(); i1 != e1; ++i1) { 61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *Idx1 = i1->first; 62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg2 = i1->second; 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Ignore identity compositions. 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg1 == Reg2) 62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs(); 62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Try composing Idx1 with another SubRegIndex. 62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM2.begin(), 62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e2 = SRM2.end(); i2 != e2; ++i2) { 62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<Record*, Record*> IdxPair(Idx1, i2->first); 62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg3 = i2->second; 63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Ignore identity compositions. 63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Reg2 == Reg3) 63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3. 63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::SubRegMap::const_iterator i1d = SRM1.begin(), 63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e1d = SRM1.end(); i1d != e1d; ++i1d) { 63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (i1d->second == Reg3) { 63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<CompositeMap::iterator, bool> Ins = 63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Composite.insert(std::make_pair(IdxPair, i1d->first)); 63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Conflicting composition? Emit a warning but allow it. 64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!Ins.second && Ins.first->second != i1d->first) { 64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman errs() << "Warning: SubRegIndex " << getQualifiedName(Idx1) 64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman << " and " << getQualifiedName(IdxPair.second) 64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman << " compose ambiguously as " 64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman << getQualifiedName(Ins.first->second) << " or " 64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman << getQualifiedName(i1d->first) << "\n"; 64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid 65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // compositions, so remove any mappings of that form. 65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CompositeMap::iterator i = Composite.begin(), e = Composite.end(); 65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman i != e;) { 65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CompositeMap::iterator j = i; 65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ++i; 65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (j->first.second == j->second) 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Composite.erase(j); 66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Compute sets of overlapping registers. 66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The standard set is all super-registers and all sub-registers, but the 66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// target description can add arbitrary overlapping registers via the 'Aliases' 66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// field. This complicates things, but we can compute overlapping sets using 66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// the following rules: 67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 1. The relation overlap(A, B) is reflexive and symmetric but not transitive. 67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 2. overlap(A, B) implies overlap(A, S) for all S in supers(B). 67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Alternatively: 67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// overlap(A, B) iff there exists: 67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// A' in { A, subregs(A) } and B' in { B, subregs(B) } such that: 67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// A' = B' or A' in aliases(B') or B' in aliases(A'). 68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Here subregs(A) is the full flattened sub-register set returned by 68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the 68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// description of register A. 68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This also implies that registers with a common sub-register are considered 68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// overlapping. This can happen when forming register pairs: 68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// P0 = (R0, R1) 68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// P1 = (R1, R2) 69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// P2 = (R2, R3) 69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// In this case, we will infer an overlap between P0 and P1 because of the 69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// shared sub-register R1. There is no overlap between P0 and P2. 69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegBank:: 69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumancomputeOverlaps(std::map<const CodeGenRegister*, CodeGenRegister::Set> &Map) { 69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Map.empty()); 69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Collect overlaps that don't follow from rule 2. 70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg = Registers[i]; 70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister::Set &Overlaps = Map[Reg]; 70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Reg overlaps itself. 70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps.insert(Reg); 70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // All super-registers overlap. 70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister::SuperRegList &Supers = Reg->getSuperRegs(); 70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps.insert(Supers.begin(), Supers.end()); 71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Form symmetrical relations from the special Aliases[] lists. 71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<Record*> RegList = Reg->TheDef->getValueAsListOfDefs("Aliases"); 71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i2 = 0, e2 = RegList.size(); i2 != e2; ++i2) { 71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg2 = getReg(RegList[i2]); 71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister::Set &Overlaps2 = Map[Reg2]; 71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister::SuperRegList &Supers2 = Reg2->getSuperRegs(); 71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Reg overlaps Reg2 which implies it overlaps supers(Reg2). 71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps.insert(Reg2); 71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps.insert(Supers2.begin(), Supers2.end()); 72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps2.insert(Reg); 72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps2.insert(Supers.begin(), Supers.end()); 72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Apply rule 2. and inherit all sub-register overlaps. 72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister *Reg = Registers[i]; 72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister::Set &Overlaps = Map[Reg]; 72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs(); 73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM.begin(), 73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman e2 = SRM.end(); i2 != e2; ++i2) { 73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegister::Set &Overlaps2 = Map[i2->second]; 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Overlaps.insert(Overlaps2.begin(), Overlaps2.end()); 73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegBank::computeDerivedInfo() { 73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman computeComposites(); 74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Infer missing register classes. 74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// 74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// For every register class RC, make sure that the set of registers in RC with 74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// a given SubIxx sub-register form a register class. 74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid CodeGenRegBank::computeInferredRegisterClasses() { 74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // When this function is called, the register classes have not been sorted 74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // and assigned EnumValues yet. That means getSubClasses(), 74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // getSuperClasses(), and hasSubClass() functions are defunct. 75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Map SubRegIndex to register set. 75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman typedef std::map<Record*, CodeGenRegister::Set, LessRecord> SubReg2SetMap; 75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Visit all register classes, including the ones being added by the loop. 75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { 75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass &RC = *RegClasses[rci]; 75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Compute the set of registers supporting each SubRegIndex. 75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubReg2SetMap SRSets; 76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::Set::const_iterator RI = RC.getMembers().begin(), 76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RE = RC.getMembers().end(); RI != RE; ++RI) { 76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister::SubRegMap &SRM = (*RI)->getSubRegs(); 76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(), 76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman E = SRM.end(); I != E; ++I) 76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SRSets[I->first].insert(*RI); 76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Find matching classes for all SRSets entries. Iterate in SubRegIndex 76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // numerical order to visit synthetic indices last. 77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { 77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Record *SubIdx = SubRegIndices[sri]; 77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SubReg2SetMap::const_iterator I = SRSets.find(SubIdx); 77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Unsupported SubRegIndex. Skip it. 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (I == SRSets.end()) 77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // In most cases, all RC registers support the SubRegIndex. 77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (I->second.size() == RC.getMembers().size()) { 77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.setSubClassWithSubReg(SubIdx, &RC); 77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This is a real subset. See if we have a matching class. 78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass::Key K(&I->second, RC.SpillSize, RC.SpillAlignment); 78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RCKeyMap::const_iterator FoundI = Key2RC.find(K); 78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FoundI != Key2RC.end()) { 78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.setSubClassWithSubReg(SubIdx, FoundI->second); 78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Class doesn't exist. 79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CodeGenRegisterClass *NewRC = 79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman new CodeGenRegisterClass(RC.getName() + "_with_" + 79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I->first->getName(), K); 79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman addToMaps(NewRC); 79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RC.setSubClassWithSubReg(SubIdx, NewRC); 79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// getRegisterClassForRegister - Find the register class that contains the 80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// specified physical register. If the register is not in a register class, 80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// return null. If the register is in multiple classes, and the classes have a 80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// superset-subset relationship and the same set of types, return the 80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// superclass. Otherwise return null. 80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanconst CodeGenRegisterClass* 80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCodeGenRegBank::getRegClassForRegister(Record *R) { 80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegister *Reg = getReg(R); 80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ArrayRef<CodeGenRegisterClass*> RCs = getRegClasses(); 80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegisterClass *FoundRC = 0; 81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = RCs.size(); i != e; ++i) { 81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const CodeGenRegisterClass &RC = *RCs[i]; 81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!RC.contains(Reg)) 81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If this is the first class that contains the register, 81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // make a note of it and go on to the next class. 81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!FoundRC) { 81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FoundRC = &RC; 81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If a register's classes have different types, return null. 82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RC.getValueTypes() != FoundRC->getValueTypes()) 82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check to see if the previously found class that contains 82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the register is a subclass of the current class. If so, 82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // prefer the superclass. 82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RC.hasSubClass(FoundRC)) { 83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman FoundRC = &RC; 83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Check to see if the previously found class that contains 83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the register is a superclass of the current class. If so, 83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // prefer the superclass. 83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FoundRC->hasSubClass(&RC)) 83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Multiple classes, and neither is a superclass of the other. 84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Return null. 84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return FoundRC; 84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 846