diff options
Diffstat (limited to 'llvm/utils/TableGen')
-rw-r--r-- | llvm/utils/TableGen/CompressInstEmitter.cpp | 116 | ||||
-rw-r--r-- | llvm/utils/TableGen/InstrInfoEmitter.cpp | 51 |
2 files changed, 91 insertions, 76 deletions
diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp index af119c3..89c175b 100644 --- a/llvm/utils/TableGen/CompressInstEmitter.cpp +++ b/llvm/utils/TableGen/CompressInstEmitter.cpp @@ -566,8 +566,6 @@ static void printPredicates(ArrayRef<const Record *> Predicates, StringRef Name, static void mergeCondAndCode(raw_ostream &CombinedStream, StringRef CondStr, StringRef CodeStr) { - // Remove first indentation and last '&&'. - CondStr = CondStr.drop_front(8).drop_back(4); CombinedStream.indent(4) << "if (" << CondStr << ") {\n"; CombinedStream << CodeStr; CombinedStream.indent(4) << " return true;\n"; @@ -704,17 +702,18 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, }); getReqFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures); + ListSeparator CondSep(" &&\n "); + // Emit checks for all required features. for (auto &Op : FeaturesSet) { StringRef Not = Op.first ? "!" : ""; - CondStream.indent(8) << Not << "STI.getFeatureBits()[" << TargetName - << "::" << Op.second << "]" - << " &&\n"; + CondStream << CondSep << Not << "STI.getFeatureBits()[" << TargetName + << "::" << Op.second << "]"; } // Emit checks for all required feature groups. for (auto &Set : AnyOfFeatureSets) { - CondStream.indent(8) << "("; + CondStream << CondSep << "("; for (auto &Op : Set) { bool IsLast = &Op == &*Set.rbegin(); StringRef Not = Op.first ? "!" : ""; @@ -723,7 +722,7 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, if (!IsLast) CondStream << " || "; } - CondStream << ") &&\n"; + CondStream << ")"; } // Start Source Inst operands validation. @@ -735,14 +734,13 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, case OpData::Operand: if (SourceOperandMap[OpNo].OpInfo.TiedOpIdx != -1) { if (Source.Operands[OpNo].Rec->isSubClassOf("RegisterClass")) - CondStream.indent(8) << "(MI.getOperand(" << OpNo - << ").isReg()) && (MI.getOperand(" - << SourceOperandMap[OpNo].OpInfo.TiedOpIdx - << ").isReg()) &&\n" - << indent(8) << "(MI.getOperand(" << OpNo - << ").getReg() == MI.getOperand(" - << SourceOperandMap[OpNo].OpInfo.TiedOpIdx - << ").getReg()) &&\n"; + CondStream << CondSep << "MI.getOperand(" << OpNo + << ").isReg() && MI.getOperand(" + << SourceOperandMap[OpNo].OpInfo.TiedOpIdx + << ").isReg()" << CondSep << "(MI.getOperand(" << OpNo + << ").getReg() == MI.getOperand(" + << SourceOperandMap[OpNo].OpInfo.TiedOpIdx + << ").getReg())"; else PrintFatalError("Unexpected tied operand types!"); } @@ -750,17 +748,17 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, // We don't need to do anything for source instruction operand checks. break; case OpData::Imm: - CondStream.indent(8) - << "(MI.getOperand(" << OpNo << ").isImm()) &&\n" - << " (MI.getOperand(" << OpNo - << ").getImm() == " << SourceOperandMap[OpNo].ImmVal << ") &&\n"; + CondStream << CondSep << "MI.getOperand(" << OpNo << ").isImm()" + << CondSep << "(MI.getOperand(" << OpNo + << ").getImm() == " << SourceOperandMap[OpNo].ImmVal + << ")"; break; case OpData::Reg: { const Record *Reg = SourceOperandMap[OpNo].RegRec; - CondStream.indent(8) << "(MI.getOperand(" << OpNo << ").isReg()) &&\n" - << indent(8) << "(MI.getOperand(" << OpNo - << ").getReg() == " << TargetName - << "::" << Reg->getName() << ") &&\n"; + CondStream << CondSep << "MI.getOperand(" << OpNo << ").isReg()" + << CondSep << "(MI.getOperand(" << OpNo + << ").getReg() == " << TargetName << "::" << Reg->getName() + << ")"; break; } } @@ -785,27 +783,26 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, switch (DestOperandMap[OpNo].Kind) { case OpData::Operand: { unsigned OpIdx = DestOperandMap[OpNo].OpInfo.Idx; - DestRec = DestOperandMap[OpNo].OpInfo.DagRec; + const Record *DagRec = DestOperandMap[OpNo].OpInfo.DagRec; // Check that the operand in the Source instruction fits // the type for the Dest instruction. - if (DestRec->isSubClassOf("RegisterClass") || - DestRec->isSubClassOf("RegisterOperand")) { - auto *ClassRec = DestRec->isSubClassOf("RegisterClass") - ? DestRec - : DestRec->getValueAsDef("RegClass"); + if (DagRec->isSubClassOf("RegisterClass") || + DagRec->isSubClassOf("RegisterOperand")) { + auto *ClassRec = DagRec->isSubClassOf("RegisterClass") + ? DagRec + : DagRec->getValueAsDef("RegClass"); // This is a register operand. Check the register class. // Don't check register class if this is a tied operand, it was done // for the operand it's tied to. if (DestOperand.getTiedRegister() == -1) { - CondStream.indent(8) << "MI.getOperand(" << OpIdx << ").isReg()"; + CondStream << CondSep << "MI.getOperand(" << OpIdx << ").isReg()"; if (EType == EmitterType::CheckCompress) CondStream << " && MI.getOperand(" << OpIdx << ").getReg().isPhysical()"; - CondStream << " &&\n" - << indent(8) << TargetName << "MCRegisterClasses[" + CondStream << CondSep << TargetName << "MCRegisterClasses[" << TargetName << "::" << ClassRec->getName() << "RegClassID].contains(MI.getOperand(" << OpIdx - << ").getReg()) &&\n"; + << ").getReg())"; } if (CompressOrUncompress) @@ -815,19 +812,35 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, // Handling immediate operands. if (CompressOrUncompress) { unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates, - DestRec, "MCOperandPredicate"); - CondStream.indent(8) << ValidatorName << "(" - << "MI.getOperand(" << OpIdx << "), STI, " - << Entry << ") &&\n"; + DagRec, "MCOperandPredicate"); + CondStream << CondSep << ValidatorName << "(" + << "MI.getOperand(" << OpIdx << "), STI, " << Entry + << " /* " << DagRec->getName() << " */)"; + // Also check DestRec if different than DagRec. + if (DagRec != DestRec) { + Entry = getPredicates(MCOpPredicateMap, MCOpPredicates, DestRec, + "MCOperandPredicate"); + CondStream << CondSep << ValidatorName << "(" + << "MI.getOperand(" << OpIdx << "), STI, " << Entry + << " /* " << DestRec->getName() << " */)"; + } } else { unsigned Entry = - getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DestRec, + getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DagRec, "ImmediateCode"); - CondStream.indent(8) - << "MI.getOperand(" << OpIdx << ").isImm() &&\n"; - CondStream.indent(8) << TargetName << "ValidateMachineOperand(" - << "MI.getOperand(" << OpIdx << "), &STI, " - << Entry << ") &&\n"; + CondStream << CondSep << "MI.getOperand(" << OpIdx << ").isImm()"; + CondStream << CondSep << TargetName << "ValidateMachineOperand(" + << "MI.getOperand(" << OpIdx << "), &STI, " << Entry + << " /* " << DagRec->getName() << " */)"; + if (DagRec != DestRec) { + Entry = getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, + DestRec, "ImmediateCode"); + CondStream << CondSep << "MI.getOperand(" << OpIdx + << ").isImm()"; + CondStream << CondSep << TargetName << "ValidateMachineOperand(" + << "MI.getOperand(" << OpIdx << "), &STI, " << Entry + << " /* " << DestRec->getName() << " */)"; + } } if (CompressOrUncompress) CodeStream.indent(6) @@ -839,19 +852,18 @@ void CompressInstEmitter::emitCompressInstEmitter(raw_ostream &OS, if (CompressOrUncompress) { unsigned Entry = getPredicates(MCOpPredicateMap, MCOpPredicates, DestRec, "MCOperandPredicate"); - CondStream.indent(8) - << ValidatorName << "(" - << "MCOperand::createImm(" << DestOperandMap[OpNo].ImmVal - << "), STI, " << Entry << ") &&\n"; + CondStream << CondSep << ValidatorName << "(" + << "MCOperand::createImm(" << DestOperandMap[OpNo].ImmVal + << "), STI, " << Entry << " /* " << DestRec->getName() + << " */)"; } else { unsigned Entry = getPredicates(ImmLeafPredicateMap, ImmLeafPredicates, DestRec, "ImmediateCode"); - CondStream.indent(8) - << TargetName - << "ValidateMachineOperand(MachineOperand::CreateImm(" - << DestOperandMap[OpNo].ImmVal << "), &STI, " << Entry - << ") &&\n"; + CondStream << CondSep << TargetName + << "ValidateMachineOperand(MachineOperand::CreateImm(" + << DestOperandMap[OpNo].ImmVal << "), &STI, " << Entry + << " /* " << DestRec->getName() << " */)"; } if (CompressOrUncompress) CodeStream.indent(6) << "OutInst.addOperand(MCOperand::createImm(" diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index fa38d01..6f72b51 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -250,29 +250,38 @@ void InstrInfoEmitter::emitOperandNameMappings( // Map of operand names to their ID. MapVector<StringRef, unsigned> OperandNameToID; - /// The keys of this map is a map which have OpName ID values as their keys - /// and instruction operand indices as their values. The values of this map - /// are lists of instruction names. This map helps to unique entries among + /// A key in this map is a vector mapping OpName ID values to instruction + /// operand indices or -1 (but without any trailing -1 values which will be + /// added later). The corresponding value in this map is the index of that row + /// in the emitted OperandMap table. This map helps to unique entries among /// instructions that have identical OpName -> Operand index mapping. - std::map<std::map<unsigned, unsigned>, std::vector<StringRef>> OperandMap; + MapVector<SmallVector<int>, unsigned> OperandMap; // Max operand index seen. unsigned MaxOperandNo = 0; // Fixed/Predefined instructions do not have UseNamedOperandTable enabled, so - // we can just skip them. + // add a dummy map entry for them. + OperandMap.try_emplace({}, 0); + unsigned FirstTargetVal = TargetInstructions.front()->EnumVal; + SmallVector<unsigned> InstructionIndex(FirstTargetVal, 0); for (const CodeGenInstruction *Inst : TargetInstructions) { - if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) + if (!Inst->TheDef->getValueAsBit("UseNamedOperandTable")) { + InstructionIndex.push_back(0); continue; - std::map<unsigned, unsigned> OpList; + } + SmallVector<int> OpList; for (const auto &Info : Inst->Operands) { unsigned ID = OperandNameToID.try_emplace(Info.Name, OperandNameToID.size()) .first->second; + OpList.resize(std::max((unsigned)OpList.size(), ID + 1), -1); OpList[ID] = Info.MIOperandNo; MaxOperandNo = std::max(MaxOperandNo, Info.MIOperandNo); } - OperandMap[OpList].push_back(Inst->TheDef->getName()); + auto [It, Inserted] = + OperandMap.try_emplace(std::move(OpList), OperandMap.size()); + InstructionIndex.push_back(It->second); } const size_t NumOperandNames = OperandNameToID.size(); @@ -302,28 +311,22 @@ void InstrInfoEmitter::emitOperandNameMappings( StringRef Type = MaxOperandNo <= INT8_MAX ? "int8_t" : "int16_t"; OS << " static constexpr " << Type << " OperandMap[][" << NumOperandNames << "] = {\n"; - for (const auto &Entry : OperandMap) { - const std::map<unsigned, unsigned> &OpList = Entry.first; - + for (const auto &[OpList, _] : OperandMap) { // Emit a row of the OperandMap table. OS << " {"; - for (unsigned ID = 0; ID < NumOperandNames; ++ID) { - auto Iter = OpList.find(ID); - OS << (Iter != OpList.end() ? (int)Iter->second : -1) << ", "; - } + for (unsigned ID = 0; ID < NumOperandNames; ++ID) + OS << (ID < OpList.size() ? OpList[ID] : -1) << ", "; OS << "},\n"; } OS << " };\n"; - OS << " switch(Opcode) {\n"; - for (const auto &[TableIndex, Entry] : enumerate(OperandMap)) { - for (StringRef Name : Entry.second) - OS << " case " << Namespace << "::" << Name << ":\n"; - OS << " return OperandMap[" << TableIndex - << "][static_cast<unsigned>(Name)];\n"; - } - OS << " default: return -1;\n"; - OS << " }\n"; + Type = OperandMap.size() <= UINT8_MAX + 1 ? "uint8_t" : "uint16_t"; + OS << " static constexpr " << Type << " InstructionIndex[] = {"; + for (auto [TableIndex, Entry] : enumerate(InstructionIndex)) + OS << (TableIndex % 16 == 0 ? "\n " : " ") << Entry << ','; + OS << "\n };\n"; + + OS << " return OperandMap[InstructionIndex[Opcode]][(unsigned)Name];\n"; } else { // There are no operands, so no need to emit anything OS << " return -1;\n"; |