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" 1784bd44ebSJakob Stoklund Olesen #include "llvm/ADT/SmallVector.h" 1868d6d8abSJakob Stoklund Olesen #include "llvm/ADT/StringExtras.h" 1968d6d8abSJakob Stoklund Olesen 2068d6d8abSJakob Stoklund Olesen using namespace llvm; 2168d6d8abSJakob Stoklund Olesen 2268d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 2368d6d8abSJakob Stoklund Olesen // CodeGenRegister 2468d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 2568d6d8abSJakob Stoklund Olesen 2684bd44ebSJakob Stoklund Olesen CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum) 2784bd44ebSJakob Stoklund Olesen : TheDef(R), 2884bd44ebSJakob Stoklund Olesen EnumValue(Enum), 2984bd44ebSJakob Stoklund Olesen CostPerUse(R->getValueAsInt("CostPerUse")), 3084bd44ebSJakob Stoklund Olesen SubRegsComplete(false) 3184bd44ebSJakob Stoklund Olesen {} 3268d6d8abSJakob Stoklund Olesen 3368d6d8abSJakob Stoklund Olesen const std::string &CodeGenRegister::getName() const { 3468d6d8abSJakob Stoklund Olesen return TheDef->getName(); 3568d6d8abSJakob Stoklund Olesen } 3668d6d8abSJakob Stoklund Olesen 3784bd44ebSJakob Stoklund Olesen namespace { 3884bd44ebSJakob Stoklund Olesen struct Orphan { 3984bd44ebSJakob Stoklund Olesen CodeGenRegister *SubReg; 4084bd44ebSJakob Stoklund Olesen Record *First, *Second; 4184bd44ebSJakob Stoklund Olesen Orphan(CodeGenRegister *r, Record *a, Record *b) 4284bd44ebSJakob Stoklund Olesen : SubReg(r), First(a), Second(b) {} 4384bd44ebSJakob Stoklund Olesen }; 4484bd44ebSJakob Stoklund Olesen } 4584bd44ebSJakob Stoklund Olesen 4684bd44ebSJakob Stoklund Olesen const CodeGenRegister::SubRegMap & 4784bd44ebSJakob Stoklund Olesen CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { 4884bd44ebSJakob Stoklund Olesen // Only compute this map once. 4984bd44ebSJakob Stoklund Olesen if (SubRegsComplete) 5084bd44ebSJakob Stoklund Olesen return SubRegs; 5184bd44ebSJakob Stoklund Olesen SubRegsComplete = true; 5284bd44ebSJakob Stoklund Olesen 5384bd44ebSJakob Stoklund Olesen std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs"); 5484bd44ebSJakob Stoklund Olesen std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); 5584bd44ebSJakob Stoklund Olesen if (SubList.size() != Indices.size()) 5684bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Register " + getName() + 5784bd44ebSJakob Stoklund Olesen " SubRegIndices doesn't match SubRegs"); 5884bd44ebSJakob Stoklund Olesen 5984bd44ebSJakob Stoklund Olesen // First insert the direct subregs and make sure they are fully indexed. 6084bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = SubList.size(); i != e; ++i) { 6184bd44ebSJakob Stoklund Olesen CodeGenRegister *SR = RegBank.getReg(SubList[i]); 6284bd44ebSJakob Stoklund Olesen if (!SubRegs.insert(std::make_pair(Indices[i], SR)).second) 6384bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "SubRegIndex " + Indices[i]->getName() + 6484bd44ebSJakob Stoklund Olesen " appears twice in Register " + getName()); 6584bd44ebSJakob Stoklund Olesen } 6684bd44ebSJakob Stoklund Olesen 6784bd44ebSJakob Stoklund Olesen // Keep track of inherited subregs and how they can be reached. 6884bd44ebSJakob Stoklund Olesen SmallVector<Orphan, 8> Orphans; 6984bd44ebSJakob Stoklund Olesen 7084bd44ebSJakob Stoklund Olesen // Clone inherited subregs and place duplicate entries on Orphans. 7184bd44ebSJakob Stoklund Olesen // Here the order is important - earlier subregs take precedence. 7284bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = SubList.size(); i != e; ++i) { 7384bd44ebSJakob Stoklund Olesen CodeGenRegister *SR = RegBank.getReg(SubList[i]); 7484bd44ebSJakob Stoklund Olesen const SubRegMap &Map = SR->getSubRegs(RegBank); 75d2b4713eSJakob Stoklund Olesen 76d2b4713eSJakob Stoklund Olesen // Add this as a super-register of SR now all sub-registers are in the list. 77d2b4713eSJakob Stoklund Olesen // This creates a topological ordering, the exact order depends on the 78d2b4713eSJakob Stoklund Olesen // order getSubRegs is called on all registers. 79d2b4713eSJakob Stoklund Olesen SR->SuperRegs.push_back(this); 80d2b4713eSJakob Stoklund Olesen 8184bd44ebSJakob Stoklund Olesen for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE; 82d2b4713eSJakob Stoklund Olesen ++SI) { 8384bd44ebSJakob Stoklund Olesen if (!SubRegs.insert(*SI).second) 8484bd44ebSJakob Stoklund Olesen Orphans.push_back(Orphan(SI->second, Indices[i], SI->first)); 85d2b4713eSJakob Stoklund Olesen 86d2b4713eSJakob Stoklund Olesen // Noop sub-register indexes are possible, so avoid duplicates. 87d2b4713eSJakob Stoklund Olesen if (SI->second != SR) 88d2b4713eSJakob Stoklund Olesen SI->second->SuperRegs.push_back(this); 89d2b4713eSJakob Stoklund Olesen } 9084bd44ebSJakob Stoklund Olesen } 9184bd44ebSJakob Stoklund Olesen 9284bd44ebSJakob Stoklund Olesen // Process the composites. 9384bd44ebSJakob Stoklund Olesen ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices"); 9484bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Comps->size(); i != e; ++i) { 9584bd44ebSJakob Stoklund Olesen DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i)); 9684bd44ebSJakob Stoklund Olesen if (!Pat) 9784bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Invalid dag '" + 9884bd44ebSJakob Stoklund Olesen Comps->getElement(i)->getAsString() + 9984bd44ebSJakob Stoklund Olesen "' in CompositeIndices"); 10084bd44ebSJakob Stoklund Olesen DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator()); 10184bd44ebSJakob Stoklund Olesen if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) 10284bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + 10384bd44ebSJakob Stoklund Olesen Pat->getAsString()); 10484bd44ebSJakob Stoklund Olesen 10584bd44ebSJakob Stoklund Olesen // Resolve list of subreg indices into R2. 10684bd44ebSJakob Stoklund Olesen CodeGenRegister *R2 = this; 10784bd44ebSJakob Stoklund Olesen for (DagInit::const_arg_iterator di = Pat->arg_begin(), 10884bd44ebSJakob Stoklund Olesen de = Pat->arg_end(); di != de; ++di) { 10984bd44ebSJakob Stoklund Olesen DefInit *IdxInit = dynamic_cast<DefInit*>(*di); 11084bd44ebSJakob Stoklund Olesen if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) 11184bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + 11284bd44ebSJakob Stoklund Olesen Pat->getAsString()); 11384bd44ebSJakob Stoklund Olesen const SubRegMap &R2Subs = R2->getSubRegs(RegBank); 11484bd44ebSJakob Stoklund Olesen SubRegMap::const_iterator ni = R2Subs.find(IdxInit->getDef()); 11584bd44ebSJakob Stoklund Olesen if (ni == R2Subs.end()) 11684bd44ebSJakob Stoklund Olesen throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() + 11784bd44ebSJakob Stoklund Olesen " refers to bad index in " + R2->getName()); 11884bd44ebSJakob Stoklund Olesen R2 = ni->second; 11984bd44ebSJakob Stoklund Olesen } 12084bd44ebSJakob Stoklund Olesen 12184bd44ebSJakob Stoklund Olesen // Insert composite index. Allow overriding inherited indices etc. 12284bd44ebSJakob Stoklund Olesen SubRegs[BaseIdxInit->getDef()] = R2; 12384bd44ebSJakob Stoklund Olesen 12484bd44ebSJakob Stoklund Olesen // R2 is no longer an orphan. 12584bd44ebSJakob Stoklund Olesen for (unsigned j = 0, je = Orphans.size(); j != je; ++j) 12684bd44ebSJakob Stoklund Olesen if (Orphans[j].SubReg == R2) 12784bd44ebSJakob Stoklund Olesen Orphans[j].SubReg = 0; 12884bd44ebSJakob Stoklund Olesen } 12984bd44ebSJakob Stoklund Olesen 13084bd44ebSJakob Stoklund Olesen // Now Orphans contains the inherited subregisters without a direct index. 13184bd44ebSJakob Stoklund Olesen // Create inferred indexes for all missing entries. 13284bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Orphans.size(); i != e; ++i) { 13384bd44ebSJakob Stoklund Olesen Orphan &O = Orphans[i]; 13484bd44ebSJakob Stoklund Olesen if (!O.SubReg) 13584bd44ebSJakob Stoklund Olesen continue; 13684bd44ebSJakob Stoklund Olesen SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second, true)] = 13784bd44ebSJakob Stoklund Olesen O.SubReg; 13884bd44ebSJakob Stoklund Olesen } 13984bd44ebSJakob Stoklund Olesen return SubRegs; 14084bd44ebSJakob Stoklund Olesen } 14184bd44ebSJakob Stoklund Olesen 142d2b4713eSJakob Stoklund Olesen void 143d2b4713eSJakob Stoklund Olesen CodeGenRegister::addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const { 144d2b4713eSJakob Stoklund Olesen assert(SubRegsComplete && "Must precompute sub-registers"); 145d2b4713eSJakob Stoklund Olesen std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); 146d2b4713eSJakob Stoklund Olesen for (unsigned i = 0, e = Indices.size(); i != e; ++i) { 147d2b4713eSJakob Stoklund Olesen CodeGenRegister *SR = SubRegs.find(Indices[i])->second; 148d2b4713eSJakob Stoklund Olesen if (OSet.insert(SR)) 149d2b4713eSJakob Stoklund Olesen SR->addSubRegsPreOrder(OSet); 150d2b4713eSJakob Stoklund Olesen } 151d2b4713eSJakob Stoklund Olesen } 152d2b4713eSJakob Stoklund Olesen 15368d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 15468d6d8abSJakob Stoklund Olesen // CodeGenRegisterClass 15568d6d8abSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 15668d6d8abSJakob Stoklund Olesen 157d7bc5c26SJakob Stoklund Olesen CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) 158d7bc5c26SJakob Stoklund Olesen : TheDef(R) { 15968d6d8abSJakob Stoklund Olesen // Rename anonymous register classes. 16068d6d8abSJakob Stoklund Olesen if (R->getName().size() > 9 && R->getName()[9] == '.') { 16168d6d8abSJakob Stoklund Olesen static unsigned AnonCounter = 0; 16268d6d8abSJakob Stoklund Olesen R->setName("AnonRegClass_"+utostr(AnonCounter++)); 16368d6d8abSJakob Stoklund Olesen } 16468d6d8abSJakob Stoklund Olesen 16568d6d8abSJakob Stoklund Olesen std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes"); 16668d6d8abSJakob Stoklund Olesen for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { 16768d6d8abSJakob Stoklund Olesen Record *Type = TypeList[i]; 16868d6d8abSJakob Stoklund Olesen if (!Type->isSubClassOf("ValueType")) 16968d6d8abSJakob Stoklund Olesen throw "RegTypes list member '" + Type->getName() + 17068d6d8abSJakob Stoklund Olesen "' does not derive from the ValueType class!"; 17168d6d8abSJakob Stoklund Olesen VTs.push_back(getValueType(Type)); 17268d6d8abSJakob Stoklund Olesen } 17368d6d8abSJakob Stoklund Olesen assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); 17468d6d8abSJakob Stoklund Olesen 17535cea3daSJakob Stoklund Olesen // Default allocation order always contains all registers. 1765ee87726SJakob Stoklund Olesen Elements = RegBank.getSets().expand(R); 1775ee87726SJakob Stoklund Olesen for (unsigned i = 0, e = Elements->size(); i != e; ++i) 1785ee87726SJakob Stoklund Olesen Members.insert(RegBank.getReg((*Elements)[i])); 17968d6d8abSJakob Stoklund Olesen 18035cea3daSJakob Stoklund Olesen // Alternative allocation orders may be subsets. 18135cea3daSJakob Stoklund Olesen ListInit *Alts = R->getValueAsListInit("AltOrders"); 18235cea3daSJakob Stoklund Olesen AltOrders.resize(Alts->size()); 18335cea3daSJakob Stoklund Olesen SetTheory::RecSet Order; 18435cea3daSJakob Stoklund Olesen for (unsigned i = 0, e = Alts->size(); i != e; ++i) { 18535cea3daSJakob Stoklund Olesen RegBank.getSets().evaluate(Alts->getElement(i), Order); 18635cea3daSJakob Stoklund Olesen AltOrders[i].append(Order.begin(), Order.end()); 18735cea3daSJakob Stoklund Olesen // Verify that all altorder members are regclass members. 18835cea3daSJakob Stoklund Olesen while (!Order.empty()) { 18935cea3daSJakob Stoklund Olesen CodeGenRegister *Reg = RegBank.getReg(Order.back()); 19035cea3daSJakob Stoklund Olesen Order.pop_back(); 19135cea3daSJakob Stoklund Olesen if (!contains(Reg)) 19235cea3daSJakob Stoklund Olesen throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() + 19335cea3daSJakob Stoklund Olesen " is not a class member"); 19435cea3daSJakob Stoklund Olesen } 19535cea3daSJakob Stoklund Olesen } 19635cea3daSJakob Stoklund Olesen 19768d6d8abSJakob Stoklund Olesen // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags. 19868d6d8abSJakob Stoklund Olesen ListInit *SRC = R->getValueAsListInit("SubRegClasses"); 19968d6d8abSJakob Stoklund Olesen for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) { 20068d6d8abSJakob Stoklund Olesen DagInit *DAG = dynamic_cast<DagInit*>(*i); 20168d6d8abSJakob Stoklund Olesen if (!DAG) throw "SubRegClasses must contain DAGs"; 20268d6d8abSJakob Stoklund Olesen DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator()); 20368d6d8abSJakob Stoklund Olesen Record *RCRec; 20468d6d8abSJakob Stoklund Olesen if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass")) 20568d6d8abSJakob Stoklund Olesen throw "Operator '" + DAG->getOperator()->getAsString() + 20668d6d8abSJakob Stoklund Olesen "' in SubRegClasses is not a RegisterClass"; 20768d6d8abSJakob Stoklund Olesen // Iterate over args, all SubRegIndex instances. 20868d6d8abSJakob Stoklund Olesen for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end(); 20968d6d8abSJakob Stoklund Olesen ai != ae; ++ai) { 21068d6d8abSJakob Stoklund Olesen DefInit *Idx = dynamic_cast<DefInit*>(*ai); 21168d6d8abSJakob Stoklund Olesen Record *IdxRec; 21268d6d8abSJakob Stoklund Olesen if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex")) 21368d6d8abSJakob Stoklund Olesen throw "Argument '" + (*ai)->getAsString() + 21468d6d8abSJakob Stoklund Olesen "' in SubRegClasses is not a SubRegIndex"; 21568d6d8abSJakob Stoklund Olesen if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second) 21668d6d8abSJakob Stoklund Olesen throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice"; 21768d6d8abSJakob Stoklund Olesen } 21868d6d8abSJakob Stoklund Olesen } 21968d6d8abSJakob Stoklund Olesen 22068d6d8abSJakob Stoklund Olesen // Allow targets to override the size in bits of the RegisterClass. 22168d6d8abSJakob Stoklund Olesen unsigned Size = R->getValueAsInt("Size"); 22268d6d8abSJakob Stoklund Olesen 22368d6d8abSJakob Stoklund Olesen Namespace = R->getValueAsString("Namespace"); 22468d6d8abSJakob Stoklund Olesen SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits(); 22568d6d8abSJakob Stoklund Olesen SpillAlignment = R->getValueAsInt("Alignment"); 22668d6d8abSJakob Stoklund Olesen CopyCost = R->getValueAsInt("CopyCost"); 22768d6d8abSJakob Stoklund Olesen Allocatable = R->getValueAsBit("isAllocatable"); 22835cea3daSJakob Stoklund Olesen AltOrderSelect = R->getValueAsCode("AltOrderSelect"); 22968d6d8abSJakob Stoklund Olesen } 23068d6d8abSJakob Stoklund Olesen 231d7bc5c26SJakob Stoklund Olesen bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const { 232d7bc5c26SJakob Stoklund Olesen return Members.count(Reg); 233d7bc5c26SJakob Stoklund Olesen } 234d7bc5c26SJakob Stoklund Olesen 235d7bc5c26SJakob Stoklund Olesen // Returns true if RC is a strict subclass. 236d7bc5c26SJakob Stoklund Olesen // RC is a sub-class of this class if it is a valid replacement for any 237d7bc5c26SJakob Stoklund Olesen // instruction operand where a register of this classis required. It must 238d7bc5c26SJakob Stoklund Olesen // satisfy these conditions: 239d7bc5c26SJakob Stoklund Olesen // 240d7bc5c26SJakob Stoklund Olesen // 1. All RC registers are also in this. 241d7bc5c26SJakob Stoklund Olesen // 2. The RC spill size must not be smaller than our spill size. 242d7bc5c26SJakob Stoklund Olesen // 3. RC spill alignment must be compatible with ours. 243d7bc5c26SJakob Stoklund Olesen // 244d7bc5c26SJakob Stoklund Olesen bool CodeGenRegisterClass::hasSubClass(const CodeGenRegisterClass *RC) const { 245d7bc5c26SJakob Stoklund Olesen return SpillAlignment && RC->SpillAlignment % SpillAlignment == 0 && 246d7bc5c26SJakob Stoklund Olesen SpillSize <= RC->SpillSize && 247d7bc5c26SJakob Stoklund Olesen std::includes(Members.begin(), Members.end(), 248*afef4222SJakob Stoklund Olesen RC->Members.begin(), RC->Members.end(), 249*afef4222SJakob Stoklund Olesen CodeGenRegister::Less()); 250d7bc5c26SJakob Stoklund Olesen } 251d7bc5c26SJakob Stoklund Olesen 25268d6d8abSJakob Stoklund Olesen const std::string &CodeGenRegisterClass::getName() const { 25368d6d8abSJakob Stoklund Olesen return TheDef->getName(); 25468d6d8abSJakob Stoklund Olesen } 25568d6d8abSJakob Stoklund Olesen 25676a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 25776a5a71eSJakob Stoklund Olesen // CodeGenRegBank 25876a5a71eSJakob Stoklund Olesen //===----------------------------------------------------------------------===// 25976a5a71eSJakob Stoklund Olesen 26076a5a71eSJakob Stoklund Olesen CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { 2615ee87726SJakob Stoklund Olesen // Configure register Sets to understand register classes. 2625ee87726SJakob Stoklund Olesen Sets.addFieldExpander("RegisterClass", "MemberList"); 2635ee87726SJakob Stoklund Olesen 26484bd44ebSJakob Stoklund Olesen // Read in the user-defined (named) sub-register indices. 26584bd44ebSJakob Stoklund Olesen // More indices will be synthesized later. 26676a5a71eSJakob Stoklund Olesen SubRegIndices = Records.getAllDerivedDefinitions("SubRegIndex"); 26776a5a71eSJakob Stoklund Olesen std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord()); 26876a5a71eSJakob Stoklund Olesen NumNamedIndices = SubRegIndices.size(); 26984bd44ebSJakob Stoklund Olesen 27084bd44ebSJakob Stoklund Olesen // Read in the register definitions. 27184bd44ebSJakob Stoklund Olesen std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); 27284bd44ebSJakob Stoklund Olesen std::sort(Regs.begin(), Regs.end(), LessRecord()); 27384bd44ebSJakob Stoklund Olesen Registers.reserve(Regs.size()); 27484bd44ebSJakob Stoklund Olesen // Assign the enumeration values. 27584bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Regs.size(); i != e; ++i) 2768e188be0SJakob Stoklund Olesen getReg(Regs[i]); 27722ea424dSJakob Stoklund Olesen 27822ea424dSJakob Stoklund Olesen // Read in register class definitions. 27922ea424dSJakob Stoklund Olesen std::vector<Record*> RCs = Records.getAllDerivedDefinitions("RegisterClass"); 28022ea424dSJakob Stoklund Olesen if (RCs.empty()) 28122ea424dSJakob Stoklund Olesen throw std::string("No 'RegisterClass' subclasses defined!"); 28222ea424dSJakob Stoklund Olesen 28322ea424dSJakob Stoklund Olesen RegClasses.reserve(RCs.size()); 284d7bc5c26SJakob Stoklund Olesen for (unsigned i = 0, e = RCs.size(); i != e; ++i) 285d7bc5c26SJakob Stoklund Olesen RegClasses.push_back(CodeGenRegisterClass(*this, RCs[i])); 28676a5a71eSJakob Stoklund Olesen } 28776a5a71eSJakob Stoklund Olesen 28884bd44ebSJakob Stoklund Olesen CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { 2898e188be0SJakob Stoklund Olesen CodeGenRegister *&Reg = Def2Reg[Def]; 2908e188be0SJakob Stoklund Olesen if (Reg) 29184bd44ebSJakob Stoklund Olesen return Reg; 2928e188be0SJakob Stoklund Olesen Reg = new CodeGenRegister(Def, Registers.size() + 1); 2938e188be0SJakob Stoklund Olesen Registers.push_back(Reg); 2948e188be0SJakob Stoklund Olesen return Reg; 29584bd44ebSJakob Stoklund Olesen } 29684bd44ebSJakob Stoklund Olesen 29722ea424dSJakob Stoklund Olesen CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { 29822ea424dSJakob Stoklund Olesen if (Def2RC.empty()) 29922ea424dSJakob Stoklund Olesen for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) 30022ea424dSJakob Stoklund Olesen Def2RC[RegClasses[i].TheDef] = &RegClasses[i]; 30122ea424dSJakob Stoklund Olesen 30222ea424dSJakob Stoklund Olesen if (CodeGenRegisterClass *RC = Def2RC[Def]) 30322ea424dSJakob Stoklund Olesen return RC; 30422ea424dSJakob Stoklund Olesen 30522ea424dSJakob Stoklund Olesen throw TGError(Def->getLoc(), "Not a known RegisterClass!"); 30622ea424dSJakob Stoklund Olesen } 30722ea424dSJakob Stoklund Olesen 30884bd44ebSJakob Stoklund Olesen Record *CodeGenRegBank::getCompositeSubRegIndex(Record *A, Record *B, 30984bd44ebSJakob Stoklund Olesen bool create) { 31084bd44ebSJakob Stoklund Olesen // Look for an existing entry. 31184bd44ebSJakob Stoklund Olesen Record *&Comp = Composite[std::make_pair(A, B)]; 31284bd44ebSJakob Stoklund Olesen if (Comp || !create) 31384bd44ebSJakob Stoklund Olesen return Comp; 31484bd44ebSJakob Stoklund Olesen 31584bd44ebSJakob Stoklund Olesen // None exists, synthesize one. 31676a5a71eSJakob Stoklund Olesen std::string Name = A->getName() + "_then_" + B->getName(); 31784bd44ebSJakob Stoklund Olesen Comp = new Record(Name, SMLoc(), Records); 31884bd44ebSJakob Stoklund Olesen Records.addDef(Comp); 31984bd44ebSJakob Stoklund Olesen SubRegIndices.push_back(Comp); 32084bd44ebSJakob Stoklund Olesen return Comp; 32176a5a71eSJakob Stoklund Olesen } 32276a5a71eSJakob Stoklund Olesen 32376a5a71eSJakob Stoklund Olesen unsigned CodeGenRegBank::getSubRegIndexNo(Record *idx) { 32476a5a71eSJakob Stoklund Olesen std::vector<Record*>::const_iterator i = 32576a5a71eSJakob Stoklund Olesen std::find(SubRegIndices.begin(), SubRegIndices.end(), idx); 32676a5a71eSJakob Stoklund Olesen assert(i != SubRegIndices.end() && "Not a SubRegIndex"); 32776a5a71eSJakob Stoklund Olesen return (i - SubRegIndices.begin()) + 1; 32876a5a71eSJakob Stoklund Olesen } 32976a5a71eSJakob Stoklund Olesen 33084bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeComposites() { 33184bd44ebSJakob Stoklund Olesen // Precompute all sub-register maps. This will create Composite entries for 33284bd44ebSJakob Stoklund Olesen // all inferred sub-register indices. 33384bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) 3348e188be0SJakob Stoklund Olesen Registers[i]->getSubRegs(*this); 33584bd44ebSJakob Stoklund Olesen 33684bd44ebSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 3378e188be0SJakob Stoklund Olesen CodeGenRegister *Reg1 = Registers[i]; 338d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs(); 33984bd44ebSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(), 34084bd44ebSJakob Stoklund Olesen e1 = SRM1.end(); i1 != e1; ++i1) { 34184bd44ebSJakob Stoklund Olesen Record *Idx1 = i1->first; 34284bd44ebSJakob Stoklund Olesen CodeGenRegister *Reg2 = i1->second; 34384bd44ebSJakob Stoklund Olesen // Ignore identity compositions. 34484bd44ebSJakob Stoklund Olesen if (Reg1 == Reg2) 34584bd44ebSJakob Stoklund Olesen continue; 346d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs(); 34784bd44ebSJakob Stoklund Olesen // Try composing Idx1 with another SubRegIndex. 34884bd44ebSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM2.begin(), 34984bd44ebSJakob Stoklund Olesen e2 = SRM2.end(); i2 != e2; ++i2) { 35084bd44ebSJakob Stoklund Olesen std::pair<Record*, Record*> IdxPair(Idx1, i2->first); 35184bd44ebSJakob Stoklund Olesen CodeGenRegister *Reg3 = i2->second; 35284bd44ebSJakob Stoklund Olesen // Ignore identity compositions. 35384bd44ebSJakob Stoklund Olesen if (Reg2 == Reg3) 35484bd44ebSJakob Stoklund Olesen continue; 35584bd44ebSJakob Stoklund Olesen // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3. 35684bd44ebSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i1d = SRM1.begin(), 35784bd44ebSJakob Stoklund Olesen e1d = SRM1.end(); i1d != e1d; ++i1d) { 35884bd44ebSJakob Stoklund Olesen if (i1d->second == Reg3) { 35984bd44ebSJakob Stoklund Olesen std::pair<CompositeMap::iterator, bool> Ins = 36084bd44ebSJakob Stoklund Olesen Composite.insert(std::make_pair(IdxPair, i1d->first)); 36184bd44ebSJakob Stoklund Olesen // Conflicting composition? Emit a warning but allow it. 36284bd44ebSJakob Stoklund Olesen if (!Ins.second && Ins.first->second != i1d->first) { 36384bd44ebSJakob Stoklund Olesen errs() << "Warning: SubRegIndex " << getQualifiedName(Idx1) 36484bd44ebSJakob Stoklund Olesen << " and " << getQualifiedName(IdxPair.second) 36584bd44ebSJakob Stoklund Olesen << " compose ambiguously as " 36684bd44ebSJakob Stoklund Olesen << getQualifiedName(Ins.first->second) << " or " 36784bd44ebSJakob Stoklund Olesen << getQualifiedName(i1d->first) << "\n"; 36884bd44ebSJakob Stoklund Olesen } 36984bd44ebSJakob Stoklund Olesen } 37084bd44ebSJakob Stoklund Olesen } 37184bd44ebSJakob Stoklund Olesen } 37284bd44ebSJakob Stoklund Olesen } 37384bd44ebSJakob Stoklund Olesen } 37484bd44ebSJakob Stoklund Olesen 37584bd44ebSJakob Stoklund Olesen // We don't care about the difference between (Idx1, Idx2) -> Idx2 and invalid 37684bd44ebSJakob Stoklund Olesen // compositions, so remove any mappings of that form. 37784bd44ebSJakob Stoklund Olesen for (CompositeMap::iterator i = Composite.begin(), e = Composite.end(); 37884bd44ebSJakob Stoklund Olesen i != e;) { 37984bd44ebSJakob Stoklund Olesen CompositeMap::iterator j = i; 38084bd44ebSJakob Stoklund Olesen ++i; 38184bd44ebSJakob Stoklund Olesen if (j->first.second == j->second) 38284bd44ebSJakob Stoklund Olesen Composite.erase(j); 38384bd44ebSJakob Stoklund Olesen } 38484bd44ebSJakob Stoklund Olesen } 38584bd44ebSJakob Stoklund Olesen 386d2b4713eSJakob Stoklund Olesen // Compute sets of overlapping registers. 387d2b4713eSJakob Stoklund Olesen // 388d2b4713eSJakob Stoklund Olesen // The standard set is all super-registers and all sub-registers, but the 389d2b4713eSJakob Stoklund Olesen // target description can add arbitrary overlapping registers via the 'Aliases' 390d2b4713eSJakob Stoklund Olesen // field. This complicates things, but we can compute overlapping sets using 391d2b4713eSJakob Stoklund Olesen // the following rules: 392d2b4713eSJakob Stoklund Olesen // 393d2b4713eSJakob Stoklund Olesen // 1. The relation overlap(A, B) is reflexive and symmetric but not transitive. 394d2b4713eSJakob Stoklund Olesen // 395d2b4713eSJakob Stoklund Olesen // 2. overlap(A, B) implies overlap(A, S) for all S in supers(B). 396d2b4713eSJakob Stoklund Olesen // 397d2b4713eSJakob Stoklund Olesen // Alternatively: 398d2b4713eSJakob Stoklund Olesen // 399d2b4713eSJakob Stoklund Olesen // overlap(A, B) iff there exists: 400d2b4713eSJakob Stoklund Olesen // A' in { A, subregs(A) } and B' in { B, subregs(B) } such that: 401d2b4713eSJakob Stoklund Olesen // A' = B' or A' in aliases(B') or B' in aliases(A'). 402d2b4713eSJakob Stoklund Olesen // 403d2b4713eSJakob Stoklund Olesen // Here subregs(A) is the full flattened sub-register set returned by 404d2b4713eSJakob Stoklund Olesen // A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the 405d2b4713eSJakob Stoklund Olesen // description of register A. 406d2b4713eSJakob Stoklund Olesen // 407d2b4713eSJakob Stoklund Olesen // This also implies that registers with a common sub-register are considered 408d2b4713eSJakob Stoklund Olesen // overlapping. This can happen when forming register pairs: 409d2b4713eSJakob Stoklund Olesen // 410d2b4713eSJakob Stoklund Olesen // P0 = (R0, R1) 411d2b4713eSJakob Stoklund Olesen // P1 = (R1, R2) 412d2b4713eSJakob Stoklund Olesen // P2 = (R2, R3) 413d2b4713eSJakob Stoklund Olesen // 414d2b4713eSJakob Stoklund Olesen // In this case, we will infer an overlap between P0 and P1 because of the 415d2b4713eSJakob Stoklund Olesen // shared sub-register R1. There is no overlap between P0 and P2. 416d2b4713eSJakob Stoklund Olesen // 417d2b4713eSJakob Stoklund Olesen void CodeGenRegBank:: 418d2b4713eSJakob Stoklund Olesen computeOverlaps(std::map<const CodeGenRegister*, CodeGenRegister::Set> &Map) { 419d2b4713eSJakob Stoklund Olesen assert(Map.empty()); 420d2b4713eSJakob Stoklund Olesen 421d2b4713eSJakob Stoklund Olesen // Collect overlaps that don't follow from rule 2. 422d2b4713eSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 4238e188be0SJakob Stoklund Olesen CodeGenRegister *Reg = Registers[i]; 424d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps = Map[Reg]; 425d2b4713eSJakob Stoklund Olesen 426d2b4713eSJakob Stoklund Olesen // Reg overlaps itself. 427d2b4713eSJakob Stoklund Olesen Overlaps.insert(Reg); 428d2b4713eSJakob Stoklund Olesen 429d2b4713eSJakob Stoklund Olesen // All super-registers overlap. 430d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SuperRegList &Supers = Reg->getSuperRegs(); 431d2b4713eSJakob Stoklund Olesen Overlaps.insert(Supers.begin(), Supers.end()); 432d2b4713eSJakob Stoklund Olesen 433d2b4713eSJakob Stoklund Olesen // Form symmetrical relations from the special Aliases[] lists. 434d2b4713eSJakob Stoklund Olesen std::vector<Record*> RegList = Reg->TheDef->getValueAsListOfDefs("Aliases"); 435d2b4713eSJakob Stoklund Olesen for (unsigned i2 = 0, e2 = RegList.size(); i2 != e2; ++i2) { 436d2b4713eSJakob Stoklund Olesen CodeGenRegister *Reg2 = getReg(RegList[i2]); 437d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps2 = Map[Reg2]; 438d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SuperRegList &Supers2 = Reg2->getSuperRegs(); 439d2b4713eSJakob Stoklund Olesen // Reg overlaps Reg2 which implies it overlaps supers(Reg2). 440d2b4713eSJakob Stoklund Olesen Overlaps.insert(Reg2); 441d2b4713eSJakob Stoklund Olesen Overlaps.insert(Supers2.begin(), Supers2.end()); 442d2b4713eSJakob Stoklund Olesen Overlaps2.insert(Reg); 443d2b4713eSJakob Stoklund Olesen Overlaps2.insert(Supers.begin(), Supers.end()); 444d2b4713eSJakob Stoklund Olesen } 445d2b4713eSJakob Stoklund Olesen } 446d2b4713eSJakob Stoklund Olesen 447d2b4713eSJakob Stoklund Olesen // Apply rule 2. and inherit all sub-register overlaps. 448d2b4713eSJakob Stoklund Olesen for (unsigned i = 0, e = Registers.size(); i != e; ++i) { 4498e188be0SJakob Stoklund Olesen CodeGenRegister *Reg = Registers[i]; 450d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps = Map[Reg]; 451d2b4713eSJakob Stoklund Olesen const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs(); 452d2b4713eSJakob Stoklund Olesen for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM.begin(), 453d2b4713eSJakob Stoklund Olesen e2 = SRM.end(); i2 != e2; ++i2) { 454d2b4713eSJakob Stoklund Olesen CodeGenRegister::Set &Overlaps2 = Map[i2->second]; 455d2b4713eSJakob Stoklund Olesen Overlaps.insert(Overlaps2.begin(), Overlaps2.end()); 456d2b4713eSJakob Stoklund Olesen } 457d2b4713eSJakob Stoklund Olesen } 458d2b4713eSJakob Stoklund Olesen } 459d2b4713eSJakob Stoklund Olesen 46084bd44ebSJakob Stoklund Olesen void CodeGenRegBank::computeDerivedInfo() { 46184bd44ebSJakob Stoklund Olesen computeComposites(); 46284bd44ebSJakob Stoklund Olesen } 46384bd44ebSJakob Stoklund Olesen 46422ea424dSJakob Stoklund Olesen /// getRegisterClassForRegister - Find the register class that contains the 46522ea424dSJakob Stoklund Olesen /// specified physical register. If the register is not in a register class, 46622ea424dSJakob Stoklund Olesen /// return null. If the register is in multiple classes, and the classes have a 46722ea424dSJakob Stoklund Olesen /// superset-subset relationship and the same set of types, return the 46822ea424dSJakob Stoklund Olesen /// superclass. Otherwise return null. 46922ea424dSJakob Stoklund Olesen const CodeGenRegisterClass* 47022ea424dSJakob Stoklund Olesen CodeGenRegBank::getRegClassForRegister(Record *R) { 471d7bc5c26SJakob Stoklund Olesen const CodeGenRegister *Reg = getReg(R); 47222ea424dSJakob Stoklund Olesen const std::vector<CodeGenRegisterClass> &RCs = getRegClasses(); 47322ea424dSJakob Stoklund Olesen const CodeGenRegisterClass *FoundRC = 0; 47422ea424dSJakob Stoklund Olesen for (unsigned i = 0, e = RCs.size(); i != e; ++i) { 47522ea424dSJakob Stoklund Olesen const CodeGenRegisterClass &RC = RCs[i]; 476d7bc5c26SJakob Stoklund Olesen if (!RC.contains(Reg)) 47722ea424dSJakob Stoklund Olesen continue; 47822ea424dSJakob Stoklund Olesen 47922ea424dSJakob Stoklund Olesen // If this is the first class that contains the register, 48022ea424dSJakob Stoklund Olesen // make a note of it and go on to the next class. 48122ea424dSJakob Stoklund Olesen if (!FoundRC) { 48222ea424dSJakob Stoklund Olesen FoundRC = &RC; 48322ea424dSJakob Stoklund Olesen continue; 48422ea424dSJakob Stoklund Olesen } 48522ea424dSJakob Stoklund Olesen 48622ea424dSJakob Stoklund Olesen // If a register's classes have different types, return null. 48722ea424dSJakob Stoklund Olesen if (RC.getValueTypes() != FoundRC->getValueTypes()) 48822ea424dSJakob Stoklund Olesen return 0; 48922ea424dSJakob Stoklund Olesen 49022ea424dSJakob Stoklund Olesen // Check to see if the previously found class that contains 49122ea424dSJakob Stoklund Olesen // the register is a subclass of the current class. If so, 49222ea424dSJakob Stoklund Olesen // prefer the superclass. 493d7bc5c26SJakob Stoklund Olesen if (RC.hasSubClass(FoundRC)) { 49422ea424dSJakob Stoklund Olesen FoundRC = &RC; 49522ea424dSJakob Stoklund Olesen continue; 49622ea424dSJakob Stoklund Olesen } 49722ea424dSJakob Stoklund Olesen 49822ea424dSJakob Stoklund Olesen // Check to see if the previously found class that contains 49922ea424dSJakob Stoklund Olesen // the register is a superclass of the current class. If so, 50022ea424dSJakob Stoklund Olesen // prefer the superclass. 501d7bc5c26SJakob Stoklund Olesen if (FoundRC->hasSubClass(&RC)) 50222ea424dSJakob Stoklund Olesen continue; 50322ea424dSJakob Stoklund Olesen 50422ea424dSJakob Stoklund Olesen // Multiple classes, and neither is a superclass of the other. 50522ea424dSJakob Stoklund Olesen // Return null. 50622ea424dSJakob Stoklund Olesen return 0; 50722ea424dSJakob Stoklund Olesen } 50822ea424dSJakob Stoklund Olesen return FoundRC; 50922ea424dSJakob Stoklund Olesen } 510