void MapTableEmitter::emitMapFuncBody(raw_ostream &OS, unsigned TableSize) { ListInit *ColFields = InstrMapDesc.getColFields(); const std::vector<ListInit*> &ValueCols = InstrMapDesc.getValueCols(); // Emit binary search algorithm to locate instructions in the // relation table. If found, return opcode value from the appropriate column // of the table. emitBinSearch(OS, TableSize); if (ValueCols.size() > 1) { for (unsigned i = 0, e = ValueCols.size(); i < e; i++) { ListInit *ColumnI = ValueCols[i]; for (unsigned j = 0, ColSize = ColumnI->size(); j < ColSize; ++j) { std::string ColName = ColFields->getElement(j)->getAsUnquotedString(); OS << " if (in" << ColName; OS << " == "; OS << ColName << "_" << ColumnI->getElement(j)->getAsUnquotedString(); if (j < ColumnI->size() - 1) OS << " && "; else OS << ")\n"; } OS << " return " << InstrMapDesc.getName(); OS << "Table[mid]["<<i+1<<"];\n"; } OS << " return -1;"; } else OS << " return " << InstrMapDesc.getName() << "Table[mid][1];\n"; OS <<"}\n\n"; }
static void emitEnums(raw_ostream &OS, RecordKeeper &Records) { std::vector<Record*> InstrMapVec; InstrMapVec = Records.getAllDerivedDefinitions("InstrMapping"); std::map<std::string, std::vector<Init*> > ColFieldValueMap; // Iterate over all InstrMapping records and create a map between column // fields and their possible values across all records. for (unsigned i = 0, e = InstrMapVec.size(); i < e; i++) { Record *CurMap = InstrMapVec[i]; ListInit *ColFields; ColFields = CurMap->getValueAsListInit("ColFields"); ListInit *List = CurMap->getValueAsListInit("ValueCols"); std::vector<ListInit*> ValueCols; unsigned ListSize = List->size(); for (unsigned j = 0; j < ListSize; j++) { ListInit *ListJ = dyn_cast<ListInit>(List->getElement(j)); if (ListJ->size() != ColFields->size()) PrintFatalError("Record `" + CurMap->getName() + "', field " "`ValueCols' entries don't match with the entries in 'ColFields' !"); ValueCols.push_back(ListJ); } for (unsigned j = 0, endCF = ColFields->size(); j < endCF; j++) { for (unsigned k = 0; k < ListSize; k++){ std::string ColName = ColFields->getElement(j)->getAsUnquotedString(); ColFieldValueMap[ColName].push_back((ValueCols[k])->getElement(j)); } } } for (std::map<std::string, std::vector<Init*> >::iterator II = ColFieldValueMap.begin(), IE = ColFieldValueMap.end(); II != IE; II++) { std::vector<Init*> FieldValues = (*II).second; // Delete duplicate entries from ColFieldValueMap for (unsigned i = 0; i < FieldValues.size() - 1; i++) { Init *CurVal = FieldValues[i]; for (unsigned j = i+1; j < FieldValues.size(); j++) { if (CurVal == FieldValues[j]) { FieldValues.erase(FieldValues.begin()+j); } } } // Emit enumerated values for the column fields. OS << "enum " << (*II).first << " {\n"; for (unsigned i = 0, endFV = FieldValues.size(); i < endFV; i++) { OS << "\t" << (*II).first << "_" << FieldValues[i]->getAsUnquotedString(); if (i != endFV - 1) OS << ",\n"; else OS << "\n};\n\n"; } } }
bool MapTableEmitter::isKeyColInstr(Record* CurInstr) { ListInit *ColFields = InstrMapDesc.getColFields(); ListInit *KeyCol = InstrMapDesc.getKeyCol(); // Check if the instruction is a KeyCol instruction. bool MatchFound = true; for (unsigned j = 0, endCF = ColFields->size(); (j < endCF) && MatchFound; j++) { RecordVal *ColFieldName = CurInstr->getValue(ColFields->getElement(j)); std::string CurInstrVal = ColFieldName->getValue()->getAsUnquotedString(); std::string KeyColValue = KeyCol->getElement(j)->getAsUnquotedString(); MatchFound = (CurInstrVal == KeyColValue); } return MatchFound; }
Record *MapTableEmitter::getInstrForColumn(Record *KeyInstr, ListInit *CurValueCol) { ListInit *RowFields = InstrMapDesc.getRowFields(); std::vector<Init*> KeyValue; // Construct KeyValue using KeyInstr's values for RowFields. for (Init *RowField : RowFields->getValues()) { Init *KeyInstrVal = KeyInstr->getValue(RowField)->getValue(); KeyValue.push_back(KeyInstrVal); } // Get all the instructions that share the same KeyValue as the KeyInstr // in RowInstrMap. We search through these instructions to find a match // for the current column, i.e., the instruction which has the same values // as CurValueCol for all the fields in ColFields. const std::vector<Record*> &RelatedInstrVec = RowInstrMap[KeyValue]; ListInit *ColFields = InstrMapDesc.getColFields(); Record *MatchInstr = nullptr; for (unsigned i = 0, e = RelatedInstrVec.size(); i < e; i++) { bool MatchFound = true; Record *CurInstr = RelatedInstrVec[i]; for (unsigned j = 0, endCF = ColFields->size(); (j < endCF) && MatchFound; j++) { Init *ColFieldJ = ColFields->getElement(j); Init *CurInstrInit = CurInstr->getValue(ColFieldJ)->getValue(); std::string CurInstrVal = CurInstrInit->getAsUnquotedString(); Init *ColFieldJVallue = CurValueCol->getElement(j); MatchFound = (CurInstrVal == ColFieldJVallue->getAsUnquotedString()); } if (MatchFound) { if (MatchInstr) { // Already had a match // Error if multiple matches are found for a column. std::string KeyValueStr; for (Init *Value : KeyValue) { if (!KeyValueStr.empty()) KeyValueStr += ", "; KeyValueStr += Value->getAsString(); } PrintFatalError("Multiple matches found for `" + KeyInstr->getName() + "', for the relation `" + InstrMapDesc.getName() + "', row fields [" + KeyValueStr + "], column `" + CurValueCol->getAsString() + "'"); } MatchInstr = CurInstr; } } return MatchInstr; }
/// ReadNodeTypes - Read in all of the node types in the current RecordKeeper, /// turning them into the more accessible NodeTypes data structure. /// void InstrSelectorEmitter::ReadNodeTypes() { std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("DagNode"); DEBUG(std::cerr << "Getting node types: "); for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { Record *Node = Nodes[i]; // Translate the return type... NodeType::ArgResultTypes RetTy = NodeType::Translate(Node->getValueAsDef("RetType")); // Translate the arguments... ListInit *Args = Node->getValueAsListInit("ArgTypes"); std::vector<NodeType::ArgResultTypes> ArgTypes; for (unsigned a = 0, e = Args->getSize(); a != e; ++a) { if (DefInit *DI = dynamic_cast<DefInit*>(Args->getElement(a))) ArgTypes.push_back(NodeType::Translate(DI->getDef())); else throw "In node " + Node->getName() + ", argument is not a Def!"; if (a == 0 && ArgTypes.back() == NodeType::Arg0) throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!"; if (a == 1 && ArgTypes.back() == NodeType::Arg1) throw "In node " + Node->getName() + ", arg 1 cannot have type 'arg1'!"; } if ((RetTy == NodeType::Arg0 && Args->getSize() == 0) || (RetTy == NodeType::Arg1 && Args->getSize() < 2)) throw "In node " + Node->getName() + ", invalid return type for node with this many operands!"; // Add the node type mapping now... NodeTypes[Node] = NodeType(RetTy, ArgTypes); DEBUG(std::cerr << Node->getName() << ", "); } DEBUG(std::cerr << "DONE!\n"); }
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map<std::vector<Record*>, unsigned> &EmittedLists, std::map<Record*, unsigned> &BarriersMap, const OperandInfoMapTy &OpInfo, raw_ostream &OS) { int MinOperands = 0; if (!Inst.OperandList.empty()) // Each logical operand can be multiple MI operands. MinOperands = Inst.OperandList.back().MIOperandNo + Inst.OperandList.back().MINumOperands; OS << " { "; OS << Num << ",\t" << MinOperands << ",\t" << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef) << ",\t\"" << Inst.TheDef->getName() << "\", 0"; // Emit all of the target indepedent flags... if (Inst.isReturn) OS << "|(1<<TID::Return)"; if (Inst.isBranch) OS << "|(1<<TID::Branch)"; if (Inst.isIndirectBranch) OS << "|(1<<TID::IndirectBranch)"; if (Inst.isBarrier) OS << "|(1<<TID::Barrier)"; if (Inst.hasDelaySlot) OS << "|(1<<TID::DelaySlot)"; if (Inst.isCall) OS << "|(1<<TID::Call)"; if (Inst.canFoldAsLoad) OS << "|(1<<TID::FoldableAsLoad)"; if (Inst.mayLoad) OS << "|(1<<TID::MayLoad)"; if (Inst.mayStore) OS << "|(1<<TID::MayStore)"; if (Inst.isPredicable) OS << "|(1<<TID::Predicable)"; if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)"; if (Inst.isCommutable) OS << "|(1<<TID::Commutable)"; if (Inst.isTerminator) OS << "|(1<<TID::Terminator)"; if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)"; if (Inst.isNotDuplicable) OS << "|(1<<TID::NotDuplicable)"; if (Inst.hasOptionalDef) OS << "|(1<<TID::HasOptionalDef)"; if (Inst.usesCustomDAGSchedInserter) OS << "|(1<<TID::UsesCustomDAGSchedInserter)"; if (Inst.isVariadic) OS << "|(1<<TID::Variadic)"; if (Inst.hasSideEffects) OS << "|(1<<TID::UnmodeledSideEffects)"; if (Inst.isAsCheapAsAMove) OS << "|(1<<TID::CheapAsAMove)"; OS << ", 0"; // Emit all of the target-specific flags... ListInit *LI = InstrInfo->getValueAsListInit("TSFlagsFields"); ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts"); if (LI->getSize() != Shift->getSize()) throw "Lengths of " + InstrInfo->getName() + ":(TargetInfoFields, TargetInfoPositions) must be equal!"; for (unsigned i = 0, e = LI->getSize(); i != e; ++i) emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)), dynamic_cast<IntInit*>(Shift->getElement(i)), OS); OS << ", "; // Emit the implicit uses and defs lists... std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses"); if (UseList.empty()) OS << "NULL, "; else OS << "ImplicitList" << EmittedLists[UseList] << ", "; std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs"); if (DefList.empty()) OS << "NULL, "; else OS << "ImplicitList" << EmittedLists[DefList] << ", "; std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef); if (BI == BarriersMap.end()) OS << "NULL, "; else OS << "Barriers" << BI->second << ", "; // Emit the operand info. std::vector<std::string> OperandInfo = GetOperandInfo(Inst); if (OperandInfo.empty()) OS << "0"; else OS << "OperandInfo" << OpInfo.find(OperandInfo)->second; OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; }
// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion. RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) { SubRegMap &SRM = SubReg[Reg]; if (!SRM.empty()) return SRM; std::vector<Record*> SubRegs = Reg->getValueAsListOfDefs("SubRegs"); std::vector<Record*> Indices = Reg->getValueAsListOfDefs("SubRegIndices"); if (SubRegs.size() != Indices.size()) throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs"; // First insert the direct subregs and make sure they are fully indexed. for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second) throw "SubRegIndex " + Indices[i]->getName() + " appears twice in Register " + Reg->getName(); inferSubRegIndices(SubRegs[i]); } // Keep track of inherited subregs and how they can be reached. // Register -> (SubRegIndex, SubRegIndex) typedef std::map<Record*, std::pair<Record*,Record*>, LessRecord> OrphanMap; OrphanMap Orphans; // Clone inherited subregs. Here the order is important - earlier subregs take // precedence. for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) { SubRegMap &M = SubReg[SubRegs[i]]; for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si) if (!SRM.insert(*si).second) Orphans[si->second] = std::make_pair(Indices[i], si->first); } // Finally process the composites. ListInit *Comps = Reg->getValueAsListInit("CompositeIndices"); for (unsigned i = 0, e = Comps->size(); i != e; ++i) { DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i)); if (!Pat) throw "Invalid dag '" + Comps->getElement(i)->getAsString() + "' in CompositeIndices"; DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator()); if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) throw "Invalid SubClassIndex in " + Pat->getAsString(); // Resolve list of subreg indices into R2. Record *R2 = Reg; for (DagInit::const_arg_iterator di = Pat->arg_begin(), de = Pat->arg_end(); di != de; ++di) { DefInit *IdxInit = dynamic_cast<DefInit*>(*di); if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) throw "Invalid SubClassIndex in " + Pat->getAsString(); SubRegMap::const_iterator ni = SubReg[R2].find(IdxInit->getDef()); if (ni == SubReg[R2].end()) throw "Composite " + Pat->getAsString() + " refers to bad index in " + R2->getName(); R2 = ni->second; } // Insert composite index. Allow overriding inherited indices etc. SRM[BaseIdxInit->getDef()] = R2; // R2 is now directly addressable, no longer an orphan. Orphans.erase(R2); } // Now, Orphans contains the inherited subregisters without a direct index. if (!Orphans.empty()) { errs() << "Error: Register " << getQualifiedName(Reg) << " inherited subregisters without an index:\n"; for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e; ++i) { errs() << " " << getQualifiedName(i->first) << " = " << i->second.first->getName() << ", " << i->second.second->getName() << "\n"; } abort(); } return SRM; }
const CodeGenRegister::SubRegMap & CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { // Only compute this map once. if (SubRegsComplete) return SubRegs; SubRegsComplete = true; std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs"); std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices"); if (SubList.size() != Indices.size()) throw TGError(TheDef->getLoc(), "Register " + getName() + " SubRegIndices doesn't match SubRegs"); // First insert the direct subregs and make sure they are fully indexed. for (unsigned i = 0, e = SubList.size(); i != e; ++i) { CodeGenRegister *SR = RegBank.getReg(SubList[i]); if (!SubRegs.insert(std::make_pair(Indices[i], SR)).second) throw TGError(TheDef->getLoc(), "SubRegIndex " + Indices[i]->getName() + " appears twice in Register " + getName()); } // Keep track of inherited subregs and how they can be reached. SmallVector<Orphan, 8> Orphans; // Clone inherited subregs and place duplicate entries on Orphans. // Here the order is important - earlier subregs take precedence. for (unsigned i = 0, e = SubList.size(); i != e; ++i) { CodeGenRegister *SR = RegBank.getReg(SubList[i]); const SubRegMap &Map = SR->getSubRegs(RegBank); // Add this as a super-register of SR now all sub-registers are in the list. // This creates a topological ordering, the exact order depends on the // order getSubRegs is called on all registers. SR->SuperRegs.push_back(this); for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE; ++SI) { if (!SubRegs.insert(*SI).second) Orphans.push_back(Orphan(SI->second, Indices[i], SI->first)); // Noop sub-register indexes are possible, so avoid duplicates. if (SI->second != SR) SI->second->SuperRegs.push_back(this); } } // Process the composites. ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices"); for (unsigned i = 0, e = Comps->size(); i != e; ++i) { DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i)); if (!Pat) throw TGError(TheDef->getLoc(), "Invalid dag '" + Comps->getElement(i)->getAsString() + "' in CompositeIndices"); DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator()); if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + Pat->getAsString()); // Resolve list of subreg indices into R2. CodeGenRegister *R2 = this; for (DagInit::const_arg_iterator di = Pat->arg_begin(), de = Pat->arg_end(); di != de; ++di) { DefInit *IdxInit = dynamic_cast<DefInit*>(*di); if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + Pat->getAsString()); const SubRegMap &R2Subs = R2->getSubRegs(RegBank); SubRegMap::const_iterator ni = R2Subs.find(IdxInit->getDef()); if (ni == R2Subs.end()) throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() + " refers to bad index in " + R2->getName()); R2 = ni->second; } // Insert composite index. Allow overriding inherited indices etc. SubRegs[BaseIdxInit->getDef()] = R2; // R2 is no longer an orphan. for (unsigned j = 0, je = Orphans.size(); j != je; ++j) if (Orphans[j].SubReg == R2) Orphans[j].SubReg = 0; } // Now Orphans contains the inherited subregisters without a direct index. // Create inferred indexes for all missing entries. for (unsigned i = 0, e = Orphans.size(); i != e; ++i) { Orphan &O = Orphans[i]; if (!O.SubReg) continue; SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second, true)] = O.SubReg; } return SubRegs; }
CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) : TheDef(R), Name(R->getName()), EnumValue(-1) { // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; R->setName("AnonRegClass_"+utostr(AnonCounter++)); } std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes"); for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { Record *Type = TypeList[i]; if (!Type->isSubClassOf("ValueType")) throw "RegTypes list member '" + Type->getName() + "' does not derive from the ValueType class!"; VTs.push_back(getValueType(Type)); } assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!"); // Allocation order 0 is the full set. AltOrders provides others. const SetTheory::RecVec *Elements = RegBank.getSets().expand(R); ListInit *AltOrders = R->getValueAsListInit("AltOrders"); Orders.resize(1 + AltOrders->size()); // Default allocation order always contains all registers. for (unsigned i = 0, e = Elements->size(); i != e; ++i) { Orders[0].push_back((*Elements)[i]); Members.insert(RegBank.getReg((*Elements)[i])); } // Alternative allocation orders may be subsets. SetTheory::RecSet Order; for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) { RegBank.getSets().evaluate(AltOrders->getElement(i), Order); Orders[1 + i].append(Order.begin(), Order.end()); // Verify that all altorder members are regclass members. while (!Order.empty()) { CodeGenRegister *Reg = RegBank.getReg(Order.back()); Order.pop_back(); if (!contains(Reg)) throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() + " is not a class member"); } } // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags. ListInit *SRC = R->getValueAsListInit("SubRegClasses"); for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) { DagInit *DAG = dynamic_cast<DagInit*>(*i); if (!DAG) throw "SubRegClasses must contain DAGs"; DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator()); Record *RCRec; if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass")) throw "Operator '" + DAG->getOperator()->getAsString() + "' in SubRegClasses is not a RegisterClass"; // Iterate over args, all SubRegIndex instances. for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end(); ai != ae; ++ai) { DefInit *Idx = dynamic_cast<DefInit*>(*ai); Record *IdxRec; if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex")) throw "Argument '" + (*ai)->getAsString() + "' in SubRegClasses is not a SubRegIndex"; if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second) throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice"; } } // Allow targets to override the size in bits of the RegisterClass. unsigned Size = R->getValueAsInt("Size"); Namespace = R->getValueAsString("Namespace"); SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits(); SpillAlignment = R->getValueAsInt("Alignment"); CopyCost = R->getValueAsInt("CopyCost"); Allocatable = R->getValueAsBit("isAllocatable"); AltOrderSelect = R->getValueAsCode("AltOrderSelect"); }
void InstrSelectorEmitter::run(std::ostream &OS) { // Type-check all of the node types to ensure we "understand" them. ReadNodeTypes(); // Read in all of the nonterminals, instructions, and expanders... ReadNonterminals(); ReadInstructionPatterns(); ReadExpanderPatterns(); // Instantiate any unresolved nonterminals with information from the context // that they are used in. InstantiateNonterminals(); // Clear InstantiatedNTs, we don't need it anymore... InstantiatedNTs.clear(); DEBUG(std::cerr << "Patterns acquired:\n"); for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(), E = Patterns.end(); I != E; ++I) if (I->second->isResolved()) DEBUG(std::cerr << " " << *I->second << "\n"); CalculateComputableValues(); OS << "#include \"llvm/CodeGen/MachineInstrBuilder.h\"\n"; EmitSourceFileHeader("Instruction Selector for the " + Target.getName() + " target", OS); // Output the slot number enums... OS << "\nenum { // Slot numbers...\n" << " LastBuiltinSlot = ISD::NumBuiltinSlots-1, // Start numbering here\n"; for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) OS << " " << I->first << "_Slot,\n"; OS << " NumSlots\n};\n\n// Reduction value typedefs...\n"; // Output the reduction value typedefs... for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) { OS << "typedef ReducedValue<unsigned, " << I->first << "_Slot> ReducedValue_" << I->first << ";\n"; } // Output the pattern enums... OS << "\n\n" << "enum { // Patterns...\n" << " NotComputed = 0,\n" << " NoMatchPattern, \n"; for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) { OS << " // " << I->first << " patterns...\n"; for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) for (unsigned i = 0, e = J->second.size(); i != e; ++i) OS << " " << J->second[i]->getRecord()->getName() << "_Pattern,\n"; } OS << "};\n\n"; //===--------------------------------------------------------------------===// // Emit the class definition... // OS << "namespace {\n" << " class " << Target.getName() << "ISel {\n" << " SelectionDAG &DAG;\n" << " public:\n" << " " << Target.getName () << "ISel(SelectionDAG &D) : DAG(D) {}\n" << " void generateCode();\n" << " private:\n" << " unsigned makeAnotherReg(const TargetRegisterClass *RC) {\n" << " return DAG.getMachineFunction().getSSARegMap()->createVirt" "ualRegister(RC);\n" << " }\n\n" << " // DAG matching methods for classes... all of these methods" " return the cost\n" << " // of producing a value of the specified class and type, which" " also gets\n" << " // added to the DAG node.\n"; // Output all of the matching prototypes for slots... for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) OS << " unsigned Match_" << I->first << "(SelectionDAGNode *N);\n"; OS << "\n // DAG matching methods for DAG nodes...\n"; // Output all of the matching prototypes for slot/node pairs for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) OS << " unsigned Match_" << I->first << "_" << getNodeName(J->first) << "(SelectionDAGNode *N);\n"; // Output all of the dag reduction methods prototypes... OS << "\n // DAG reduction methods...\n"; for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) OS << " ReducedValue_" << I->first << " *Reduce_" << I->first << "(SelectionDAGNode *N,\n" << std::string(27+2*I->first.size(), ' ') << "MachineBasicBlock *MBB);\n"; OS << " };\n}\n\n"; // Emit the generateCode entry-point... OS << "void " << Target.getName () << "ISel::generateCode() {\n" << " SelectionDAGNode *Root = DAG.getRoot();\n" << " assert(Root->getValueType() == MVT::isVoid && " "\"Root of DAG produces value??\");\n\n" << " std::cerr << \"\\n\";\n" << " unsigned Cost = Match_Void_void(Root);\n" << " if (Cost >= ~0U >> 1) {\n" << " std::cerr << \"Match failed!\\n\";\n" << " Root->dump();\n" << " abort();\n" << " }\n\n" << " std::cerr << \"Total DAG Cost: \" << Cost << \"\\n\\n\";\n\n" << " Reduce_Void_void(Root, 0);\n" << "}\n\n" << "//===" << std::string(70, '-') << "===//\n" << "// Matching methods...\n" << "//\n\n"; //===--------------------------------------------------------------------===// // Emit all of the matcher methods... // for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) { const std::string &SlotName = I->first; OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName << "(SelectionDAGNode *N) {\n" << " assert(N->getValueType() == MVT::" << getEnumName((*I->second.begin()).second[0]->getTree()->getType()) << ");\n" << " // If we already have a cost available for " << SlotName << " use it!\n" << " if (N->getPatternFor(" << SlotName << "_Slot))\n" << " return N->getCostFor(" << SlotName << "_Slot);\n\n" << " unsigned Cost;\n" << " switch (N->getNodeType()) {\n" << " default: Cost = ~0U >> 1; // Match failed\n" << " N->setPatternCostFor(" << SlotName << "_Slot, NoMatchPattern, Cost, NumSlots);\n" << " break;\n"; for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) if (!J->first->isSubClassOf("Nonterminal")) OS << " case ISD::" << getNodeName(J->first) << ":\tCost = Match_" << SlotName << "_" << getNodeName(J->first) << "(N); break;\n"; OS << " }\n"; // End of the switch statement // Emit any patterns which have a nonterminal leaf as the RHS. These may // match multiple root nodes, so they cannot be handled with the switch... for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) if (J->first->isSubClassOf("Nonterminal")) { OS << " unsigned " << J->first->getName() << "_Cost = Match_" << getNodeName(J->first) << "(N);\n" << " if (" << getNodeName(J->first) << "_Cost < Cost) Cost = " << getNodeName(J->first) << "_Cost;\n"; } OS << " return Cost;\n}\n\n"; for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(), E = I->second.end(); J != E; ++J) { Record *Operator = J->first; bool isNonterm = Operator->isSubClassOf("Nonterminal"); if (!isNonterm) { OS << "unsigned " << Target.getName() << "ISel::Match_"; if (!isNonterm) OS << SlotName << "_"; OS << getNodeName(Operator) << "(SelectionDAGNode *N) {\n" << " unsigned Pattern = NoMatchPattern;\n" << " unsigned MinCost = ~0U >> 1;\n"; std::vector<std::pair<Pattern*, TreePatternNode*> > Patterns; for (unsigned i = 0, e = J->second.size(); i != e; ++i) Patterns.push_back(std::make_pair(J->second[i], J->second[i]->getTree())); EmitMatchCosters(OS, Patterns, "N", 2); OS << "\n N->setPatternCostFor(" << SlotName << "_Slot, Pattern, MinCost, NumSlots);\n" << " return MinCost;\n" << "}\n"; } } } //===--------------------------------------------------------------------===// // Emit all of the reducer methods... // OS << "\n\n//===" << std::string(70, '-') << "===//\n" << "// Reducer methods...\n" << "//\n"; for (PatternOrganizer::iterator I = ComputableValues.begin(), E = ComputableValues.end(); I != E; ++I) { const std::string &SlotName = I->first; OS << "ReducedValue_" << SlotName << " *" << Target.getName() << "ISel::Reduce_" << SlotName << "(SelectionDAGNode *N, MachineBasicBlock *MBB) {\n" << " ReducedValue_" << SlotName << " *Val = N->hasValue<ReducedValue_" << SlotName << ">(" << SlotName << "_Slot);\n" << " if (Val) return Val;\n" << " if (N->getBB()) MBB = N->getBB();\n\n" << " switch (N->getPatternFor(" << SlotName << "_Slot)) {\n"; // Loop over all of the patterns that can produce a value for this slot... PatternOrganizer::NodesForSlot &NodesForSlot = I->second; for (PatternOrganizer::NodesForSlot::iterator J = NodesForSlot.begin(), E = NodesForSlot.end(); J != E; ++J) for (unsigned i = 0, e = J->second.size(); i != e; ++i) { Pattern *P = J->second[i]; OS << " case " << P->getRecord()->getName() << "_Pattern: {\n" << " // " << *P << "\n"; // Loop over the operands, reducing them... std::vector<std::pair<TreePatternNode*, std::string> > Operands; ReduceAllOperands(P->getTree(), "N", Operands, OS); // Now that we have reduced all of our operands, and have the values // that reduction produces, perform the reduction action for this // pattern. std::string Result; // If the pattern produces a register result, generate a new register // now. if (Record *R = P->getResult()) { assert(R->isSubClassOf("RegisterClass") && "Only handle register class results so far!"); OS << " unsigned NewReg = makeAnotherReg(" << Target.getName() << "::" << R->getName() << "RegisterClass);\n"; Result = "NewReg"; DEBUG(OS << " std::cerr << \"%reg\" << NewReg << \" =\t\";\n"); } else { DEBUG(OS << " std::cerr << \"\t\t\";\n"); Result = "0"; } // Print out the pattern that matched... DEBUG(OS << " std::cerr << \" " << P->getRecord()->getName() <<'"'); DEBUG(for (unsigned i = 0, e = Operands.size(); i != e; ++i) if (Operands[i].first->isLeaf()) { Record *RV = Operands[i].first->getValueRecord(); assert(RV->isSubClassOf("RegisterClass") && "Only handles registers here so far!"); OS << " << \" %reg\" << " << Operands[i].second << "->Val"; } else { OS << " << ' ' << " << Operands[i].second << "->Val"; }); DEBUG(OS << " << \"\\n\";\n"); // Generate the reduction code appropriate to the particular type of // pattern that this is... switch (P->getPatternType()) { case Pattern::Instruction: // Instruction patterns just emit a single MachineInstr, using BuildMI OS << " BuildMI(MBB, " << Target.getName() << "::" << P->getRecord()->getName() << ", " << Operands.size(); if (P->getResult()) OS << ", NewReg"; OS << ")"; for (unsigned i = 0, e = Operands.size(); i != e; ++i) { TreePatternNode *Op = Operands[i].first; if (Op->isLeaf()) { Record *RV = Op->getValueRecord(); assert(RV->isSubClassOf("RegisterClass") && "Only handles registers here so far!"); OS << ".addReg(" << Operands[i].second << "->Val)"; } else if (Op->getOperator()->getName() == "imm") { OS << ".addZImm(" << Operands[i].second << "->Val)"; } else if (Op->getOperator()->getName() == "basicblock") { OS << ".addMBB(" << Operands[i].second << "->Val)"; } else { assert(0 && "Unknown value type!"); } } OS << ";\n"; break; case Pattern::Expander: { // Expander patterns emit one machine instr for each instruction in // the list of instructions expanded to. ListInit *Insts = P->getRecord()->getValueAsListInit("Result"); for (unsigned IN = 0, e = Insts->getSize(); IN != e; ++IN) { DagInit *DIInst = dynamic_cast<DagInit*>(Insts->getElement(IN)); if (!DIInst) P->error("Result list must contain instructions!"); Record *InstRec = DIInst->getNodeType(); Pattern *InstPat = getPattern(InstRec); if (!InstPat || InstPat->getPatternType() != Pattern::Instruction) P->error("Instruction list must contain Instruction patterns!"); bool hasResult = InstPat->getResult() != 0; if (InstPat->getNumArgs() != DIInst->getNumArgs()-hasResult) { P->error("Incorrect number of arguments specified for inst '" + InstPat->getRecord()->getName() + "' in result list!"); } // Start emission of the instruction... OS << " BuildMI(MBB, " << Target.getName() << "::" << InstRec->getName() << ", " << DIInst->getNumArgs()-hasResult; // Emit register result if necessary.. if (hasResult) { std::string ArgNameVal = getArgName(P, DIInst->getArgName(0), Operands); PrintExpanderOperand(DIInst->getArg(0), ArgNameVal, InstPat->getResultNode(), P, false, OS << ", "); } OS << ")"; for (unsigned i = hasResult, e = DIInst->getNumArgs(); i != e; ++i){ std::string ArgNameVal = getArgName(P, DIInst->getArgName(i), Operands); PrintExpanderOperand(DIInst->getArg(i), ArgNameVal, InstPat->getArg(i-hasResult), P, true, OS); } OS << ";\n"; } break; } default: assert(0 && "Reduction of this type of pattern not implemented!"); } OS << " Val = new ReducedValue_" << SlotName << "(" << Result<<");\n" << " break;\n" << " }\n"; } OS << " default: assert(0 && \"Unknown " << SlotName << " pattern!\");\n" << " }\n\n N->addValue(Val); // Do not ever recalculate this\n" << " return Val;\n}\n\n"; }
const CodeGenRegister::SubRegMap & CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) { // Only compute this map once. if (SubRegsComplete) return SubRegs; SubRegsComplete = true; std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs"); std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices"); if (SubList.size() != IdxList.size()) throw TGError(TheDef->getLoc(), "Register " + getName() + " SubRegIndices doesn't match SubRegs"); // First insert the direct subregs and make sure they are fully indexed. SmallVector<CodeGenSubRegIndex*, 8> Indices; for (unsigned i = 0, e = SubList.size(); i != e; ++i) { CodeGenRegister *SR = RegBank.getReg(SubList[i]); CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]); Indices.push_back(Idx); if (!SubRegs.insert(std::make_pair(Idx, SR)).second) throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() + " appears twice in Register " + getName()); } // Keep track of inherited subregs and how they can be reached. SmallPtrSet<CodeGenRegister*, 8> Orphans; // Clone inherited subregs and place duplicate entries in Orphans. // Here the order is important - earlier subregs take precedence. for (unsigned i = 0, e = SubList.size(); i != e; ++i) { CodeGenRegister *SR = RegBank.getReg(SubList[i]); const SubRegMap &Map = SR->getSubRegs(RegBank); // Add this as a super-register of SR now all sub-registers are in the list. // This creates a topological ordering, the exact order depends on the // order getSubRegs is called on all registers. SR->SuperRegs.push_back(this); for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE; ++SI) { if (!SubRegs.insert(*SI).second) Orphans.insert(SI->second); // Noop sub-register indexes are possible, so avoid duplicates. if (SI->second != SR) SI->second->SuperRegs.push_back(this); } } // Expand any composed subreg indices. // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a // qsub_1 subreg, add a dsub_2 subreg. Keep growing Indices and process // expanded subreg indices recursively. for (unsigned i = 0; i != Indices.size(); ++i) { CodeGenSubRegIndex *Idx = Indices[i]; const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites(); CodeGenRegister *SR = SubRegs[Idx]; const SubRegMap &Map = SR->getSubRegs(RegBank); // Look at the possible compositions of Idx. // They may not all be supported by SR. for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(), E = Comps.end(); I != E; ++I) { SubRegMap::const_iterator SRI = Map.find(I->first); if (SRI == Map.end()) continue; // Idx + I->first doesn't exist in SR. // Add I->second as a name for the subreg SRI->second, assuming it is // orphaned, and the name isn't already used for something else. if (SubRegs.count(I->second) || !Orphans.erase(SRI->second)) continue; // We found a new name for the orphaned sub-register. SubRegs.insert(std::make_pair(I->second, SRI->second)); Indices.push_back(I->second); } } // Process the composites. ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices"); for (unsigned i = 0, e = Comps->size(); i != e; ++i) { DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i)); if (!Pat) throw TGError(TheDef->getLoc(), "Invalid dag '" + Comps->getElement(i)->getAsString() + "' in CompositeIndices"); DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator()); if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex")) throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + Pat->getAsString()); CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef()); // Resolve list of subreg indices into R2. CodeGenRegister *R2 = this; for (DagInit::const_arg_iterator di = Pat->arg_begin(), de = Pat->arg_end(); di != de; ++di) { DefInit *IdxInit = dynamic_cast<DefInit*>(*di); if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex")) throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " + Pat->getAsString()); CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef()); const SubRegMap &R2Subs = R2->getSubRegs(RegBank); SubRegMap::const_iterator ni = R2Subs.find(Idx); if (ni == R2Subs.end()) throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() + " refers to bad index in " + R2->getName()); R2 = ni->second; } // Insert composite index. Allow overriding inherited indices etc. SubRegs[BaseIdx] = R2; // R2 is no longer an orphan. Orphans.erase(R2); } // Now Orphans contains the inherited subregisters without a direct index. // Create inferred indexes for all missing entries. // Work backwards in the Indices vector in order to compose subregs bottom-up. // Consider this subreg sequence: // // qsub_1 -> dsub_0 -> ssub_0 // // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register // can be reached in two different ways: // // qsub_1 -> ssub_0 // dsub_2 -> ssub_0 // // We pick the latter composition because another register may have [dsub_0, // dsub_1, dsub_2] subregs without neccessarily having a qsub_1 subreg. The // dsub_2 -> ssub_0 composition can be shared. while (!Indices.empty() && !Orphans.empty()) { CodeGenSubRegIndex *Idx = Indices.pop_back_val(); CodeGenRegister *SR = SubRegs[Idx]; const SubRegMap &Map = SR->getSubRegs(RegBank); for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE; ++SI) if (Orphans.erase(SI->second)) SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second; } // Initialize RegUnitList. A register with no subregisters creates its own // unit. Otherwise, it inherits all its subregister's units. Because // getSubRegs is called recursively, this processes the register hierarchy in // postorder. // // TODO: We currently assume all register units correspond to a named "leaf" // register. We should also unify register units for ad-hoc register // aliases. This can be done by iteratively merging units for aliasing // registers using a worklist. assert(RegUnits.empty() && "Should only initialize RegUnits once"); if (SubRegs.empty()) { RegUnits.push_back(RegBank.newRegUnit()); } else { for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end(); I != E; ++I) { // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM. CodeGenRegister *SR = I->second; if (SR == this) { if (RegUnits.empty()) RegUnits.push_back(RegBank.newRegUnit()); continue; } // Merge the subregister's units into this register's RegUnits. mergeRegUnits(RegUnits, SR->RegUnits); } } return SubRegs; }