aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils')
-rw-r--r--llvm/utils/TableGen/InstrInfoEmitter.cpp1093
-rw-r--r--llvm/utils/UpdateTestChecks/common.py1
-rw-r--r--llvm/utils/UpdateTestChecks/mir.py11
-rw-r--r--llvm/utils/gn/secondary/libcxx/include/BUILD.gn1
-rw-r--r--llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn1
-rwxr-xr-xllvm/utils/update_llc_test_checks.py94
6 files changed, 619 insertions, 582 deletions
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 0b90f91..e725de1 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -341,8 +341,6 @@ emitGetOperandIdxName(raw_ostream &OS,
void InstrInfoEmitter::emitOperandNameMappings(
raw_ostream &OS, const CodeGenTarget &Target,
ArrayRef<const CodeGenInstruction *> TargetInstructions) {
- StringRef Namespace = Target.getInstNamespace();
-
// Map of operand names to their ID.
MapVector<StringRef, unsigned> OperandNameToID;
@@ -383,38 +381,35 @@ void InstrInfoEmitter::emitOperandNameMappings(
const size_t NumOperandNames = OperandNameToID.size();
const unsigned MaxNumOperands = MaxOperandNo + 1;
- OS << "#ifdef GET_INSTRINFO_OPERAND_ENUM\n";
- OS << "#undef GET_INSTRINFO_OPERAND_ENUM\n";
- OS << "namespace llvm::" << Namespace << " {\n";
-
- assert(NumOperandNames <= UINT16_MAX &&
- "Too many operands for the operand index -> name table");
- StringRef EnumType = getMinimalTypeForRange(NumOperandNames);
- OS << "enum class OpName : " << EnumType << " {\n";
- for (const auto &[Op, I] : OperandNameToID)
- OS << " " << Op << " = " << I << ",\n";
- OS << " NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
- OS << "}; // enum class OpName\n\n";
-
- OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName "
- "Name);\n";
- OS << "LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t "
- "Idx);\n";
- OS << "} // end namespace llvm::" << Namespace << '\n';
- OS << "#endif //GET_INSTRINFO_OPERAND_ENUM\n\n";
-
- OS << "#ifdef GET_INSTRINFO_NAMED_OPS\n";
- OS << "#undef GET_INSTRINFO_NAMED_OPS\n";
- OS << "namespace llvm::" << Namespace << " {\n";
-
- emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);
+ const SmallString<32> Namespace({"llvm::", Target.getInstNamespace()});
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_ENUM");
+ NamespaceEmitter NS(OS, Namespace);
+
+ assert(NumOperandNames <= UINT16_MAX &&
+ "Too many operands for the operand index -> name table");
+ StringRef EnumType = getMinimalTypeForRange(NumOperandNames);
+ OS << "enum class OpName : " << EnumType << " {\n";
+ for (const auto &[Op, I] : OperandNameToID)
+ OS << " " << Op << " = " << I << ",\n";
+ OS << " NUM_OPERAND_NAMES = " << NumOperandNames << ",\n";
+ OS << "}; // enum class OpName\n\n";
+
+ OS << "LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, OpName "
+ "Name);\n";
+ OS << "LLVM_READONLY OpName getOperandIdxName(uint16_t Opcode, int16_t "
+ "Idx);\n";
+ }
- emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames);
- emitGetOperandIdxName(OS, OperandNameToID, OperandMap, MaxNumOperands,
- NumOperandNames);
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_NAMED_OPS");
+ NamespaceEmitter NS(OS, Namespace);
+ emitGetInstructionIndexForOpLookup(OS, OperandMap, InstructionIndex);
- OS << "} // end namespace llvm::" << Namespace << '\n';
- OS << "#endif //GET_INSTRINFO_NAMED_OPS\n\n";
+ emitGetNamedOperandIdx(OS, OperandMap, MaxOperandNo, NumOperandNames);
+ emitGetOperandIdxName(OS, OperandNameToID, OperandMap, MaxNumOperands,
+ NumOperandNames);
+ }
}
/// Generate an enum for all the operand types for this target, under the
@@ -439,121 +434,121 @@ void InstrInfoEmitter::emitOperandTypeMappings(
ArrayRef<const Record *> RegisterClasses =
Records.getAllDerivedDefinitions("RegisterClass");
- OS << "#ifdef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
- OS << "#undef GET_INSTRINFO_OPERAND_TYPES_ENUM\n";
- OS << "namespace llvm::" << Namespace << "::OpTypes {\n";
- OS << "enum OperandType {\n";
-
unsigned EnumVal = 0;
- for (ArrayRef<const Record *> RecordsToAdd :
- {Operands, RegisterOperands, RegisterClasses}) {
- for (const Record *Op : RecordsToAdd) {
- if (!Op->isAnonymous())
- OS << " " << Op->getName() << " = " << EnumVal << ",\n";
- ++EnumVal;
+
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_TYPES_ENUM");
+ NamespaceEmitter NS(OS, ("llvm::" + Namespace + "::OpTypes").str());
+ OS << "enum OperandType {\n";
+
+ for (ArrayRef<const Record *> RecordsToAdd :
+ {Operands, RegisterOperands, RegisterClasses}) {
+ for (const Record *Op : RecordsToAdd) {
+ if (!Op->isAnonymous())
+ OS << " " << Op->getName() << " = " << EnumVal << ",\n";
+ ++EnumVal;
+ }
}
+
+ OS << " OPERAND_TYPE_LIST_END" << "\n};\n";
}
- OS << " OPERAND_TYPE_LIST_END"
- << "\n};\n";
- OS << "} // end namespace llvm::" << Namespace << "::OpTypes\n";
- OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n";
-
- OS << "#ifdef GET_INSTRINFO_OPERAND_TYPE\n";
- OS << "#undef GET_INSTRINFO_OPERAND_TYPE\n";
- OS << "namespace llvm::" << Namespace << " {\n";
- OS << "LLVM_READONLY\n";
- OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
- auto getInstrName = [&](int I) -> StringRef {
- return NumberedInstructions[I]->getName();
- };
- // TODO: Factor out duplicate operand lists to compress the tables.
- std::vector<size_t> OperandOffsets;
- std::vector<const Record *> OperandRecords;
- size_t CurrentOffset = 0;
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
- OperandOffsets.push_back(CurrentOffset);
- for (const auto &Op : Inst->Operands) {
- const DagInit *MIOI = Op.MIOperandInfo;
- if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
- // Single, anonymous, operand.
- OperandRecords.push_back(Op.Rec);
- ++CurrentOffset;
- } else {
- for (const Init *Arg : MIOI->getArgs()) {
- OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_OPERAND_TYPE");
+ NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
+ OS << "LLVM_READONLY\n";
+ OS << "static int getOperandType(uint16_t Opcode, uint16_t OpIdx) {\n";
+ auto getInstrName = [&](int I) -> StringRef {
+ return NumberedInstructions[I]->getName();
+ };
+ // TODO: Factor out duplicate operand lists to compress the tables.
+ std::vector<size_t> OperandOffsets;
+ std::vector<const Record *> OperandRecords;
+ size_t CurrentOffset = 0;
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ OperandOffsets.push_back(CurrentOffset);
+ for (const auto &Op : Inst->Operands) {
+ const DagInit *MIOI = Op.MIOperandInfo;
+ if (!ExpandMIOperandInfo || !MIOI || MIOI->getNumArgs() == 0) {
+ // Single, anonymous, operand.
+ OperandRecords.push_back(Op.Rec);
++CurrentOffset;
+ } else {
+ for (const Init *Arg : MIOI->getArgs()) {
+ OperandRecords.push_back(cast<DefInit>(Arg)->getDef());
+ ++CurrentOffset;
+ }
}
}
}
- }
- // Emit the table of offsets (indexes) into the operand type table.
- // Size the unsigned integer offset to save space.
- assert(OperandRecords.size() <= UINT32_MAX &&
- "Too many operands for offset table");
- OS << " static constexpr " << getMinimalTypeForRange(OperandRecords.size());
- OS << " Offsets[] = {\n";
- for (const auto &[Idx, Offset] : enumerate(OperandOffsets))
- OS << " " << Offset << ", // " << getInstrName(Idx) << '\n';
- OS << " };\n";
+ // Emit the table of offsets (indexes) into the operand type table.
+ // Size the unsigned integer offset to save space.
+ assert(OperandRecords.size() <= UINT32_MAX &&
+ "Too many operands for offset table");
+ OS << " static constexpr "
+ << getMinimalTypeForRange(OperandRecords.size());
+ OS << " Offsets[] = {\n";
+ for (const auto &[Idx, Offset] : enumerate(OperandOffsets))
+ OS << " " << Offset << ", // " << getInstrName(Idx) << '\n';
+ OS << " };\n";
- // Add an entry for the end so that we don't need to special case it below.
- OperandOffsets.push_back(OperandRecords.size());
-
- // Emit the actual operand types in a flat table.
- // Size the signed integer operand type to save space.
- assert(EnumVal <= INT16_MAX &&
- "Too many operand types for operand types table");
- OS << "\n using namespace OpTypes;\n";
- OS << " static";
- OS << (EnumVal <= INT8_MAX ? " constexpr int8_t" : " constexpr int16_t");
- OS << " OpcodeOperandTypes[] = {";
- size_t CurOffset = 0;
- for (auto [Idx, OpR] : enumerate(OperandRecords)) {
- // We print each Opcode's operands in its own row.
- if (Idx == OperandOffsets[CurOffset]) {
- OS << "\n /* " << getInstrName(CurOffset) << " */\n ";
- while (OperandOffsets[++CurOffset] == Idx)
- OS << "/* " << getInstrName(CurOffset) << " */\n ";
+ // Add an entry for the end so that we don't need to special case it below.
+ OperandOffsets.push_back(OperandRecords.size());
+
+ // Emit the actual operand types in a flat table.
+ // Size the signed integer operand type to save space.
+ assert(EnumVal <= INT16_MAX &&
+ "Too many operand types for operand types table");
+ OS << "\n using namespace OpTypes;\n";
+ OS << " static";
+ OS << (EnumVal <= INT8_MAX ? " constexpr int8_t" : " constexpr int16_t");
+ OS << " OpcodeOperandTypes[] = {";
+ size_t CurOffset = 0;
+ for (auto [Idx, OpR] : enumerate(OperandRecords)) {
+ // We print each Opcode's operands in its own row.
+ if (Idx == OperandOffsets[CurOffset]) {
+ OS << "\n /* " << getInstrName(CurOffset) << " */\n ";
+ while (OperandOffsets[++CurOffset] == Idx)
+ OS << "/* " << getInstrName(CurOffset) << " */\n ";
+ }
+ if ((OpR->isSubClassOf("Operand") ||
+ OpR->isSubClassOf("RegisterOperand") ||
+ OpR->isSubClassOf("RegisterClass")) &&
+ !OpR->isAnonymous())
+ OS << OpR->getName();
+ else
+ OS << -1;
+ OS << ", ";
}
- if ((OpR->isSubClassOf("Operand") || OpR->isSubClassOf("RegisterOperand") ||
- OpR->isSubClassOf("RegisterClass")) &&
- !OpR->isAnonymous())
- OS << OpR->getName();
- else
- OS << -1;
- OS << ", ";
- }
- OS << "\n };\n";
+ OS << "\n };\n";
- OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
- OS << "}\n";
- OS << "} // end namespace llvm::" << Namespace << '\n';
- OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
-
- OS << "#ifdef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
- OS << "#undef GET_INSTRINFO_MEM_OPERAND_SIZE\n";
- OS << "namespace llvm::" << Namespace << " {\n";
- OS << "LLVM_READONLY\n";
- OS << "static int getMemOperandSize(int OpType) {\n";
- OS << " switch (OpType) {\n";
- std::map<int, SmallVector<StringRef, 0>> SizeToOperandName;
- for (const Record *Op : Operands) {
- if (!Op->isSubClassOf("X86MemOperand"))
- continue;
- if (int Size = Op->getValueAsInt("Size"))
- SizeToOperandName[Size].push_back(Op->getName());
+ OS << " return OpcodeOperandTypes[Offsets[Opcode] + OpIdx];\n";
+ OS << "}\n";
}
- OS << " default: return 0;\n";
- for (const auto &[Size, OperandNames] : SizeToOperandName) {
- for (const StringRef &OperandName : OperandNames)
- OS << " case OpTypes::" << OperandName << ":\n";
- OS << " return " << Size << ";\n\n";
+
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_MEM_OPERAND_SIZE");
+ NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
+
+ OS << "LLVM_READONLY\n";
+ OS << "static int getMemOperandSize(int OpType) {\n";
+ OS << " switch (OpType) {\n";
+ std::map<int, SmallVector<StringRef, 0>> SizeToOperandName;
+ for (const Record *Op : Operands) {
+ if (!Op->isSubClassOf("X86MemOperand"))
+ continue;
+ if (int Size = Op->getValueAsInt("Size"))
+ SizeToOperandName[Size].push_back(Op->getName());
+ }
+ OS << " default: return 0;\n";
+ for (const auto &[Size, OperandNames] : SizeToOperandName) {
+ for (const StringRef &OperandName : OperandNames)
+ OS << " case OpTypes::" << OperandName << ":\n";
+ OS << " return " << Size << ";\n\n";
+ }
+ OS << " }\n}\n";
}
- OS << " }\n}\n";
- OS << "} // end namespace llvm::" << Namespace << '\n';
- OS << "#endif // GET_INSTRINFO_MEM_OPERAND_SIZE\n\n";
}
// Fixed/Predefined instructions do not have UseLogicalOperandMappings
@@ -587,9 +582,8 @@ void InstrInfoEmitter::emitLogicalOperandSizeMappings(
InstMap[I->second].push_back((Namespace + "::" + Inst->getName()).str());
}
- OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
- OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
- OS << "namespace llvm::" << Namespace << " {\n";
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP");
+ NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
OS << "LLVM_READONLY static unsigned\n";
OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
if (!InstMap.empty()) {
@@ -637,9 +631,6 @@ void InstrInfoEmitter::emitLogicalOperandSizeMappings(
OS << " S += getLogicalOperandSize(Opcode, i);\n";
OS << " return S;\n";
OS << "}\n";
-
- OS << "} // end namespace llvm::" << Namespace << '\n';
- OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
}
void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
@@ -647,48 +638,38 @@ void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
ArrayRef<const Record *> TIIPredicates =
Records.getAllDerivedDefinitions("TIIPredicate");
- OS << "#ifdef GET_INSTRINFO_MC_HELPER_DECLS\n";
- OS << "#undef GET_INSTRINFO_MC_HELPER_DECLS\n\n";
-
- OS << "namespace llvm {\n";
- OS << "class MCInst;\n";
- OS << "class FeatureBitset;\n\n";
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_HELPER_DECLS");
+ NamespaceEmitter LlvmNS(OS, "llvm");
+ OS << "class MCInst;\n";
+ OS << "class FeatureBitset;\n\n";
- OS << "namespace " << TargetName << "_MC {\n\n";
+ NamespaceEmitter TargetNS(OS, (TargetName + "_MC").str());
+ for (const Record *Rec : TIIPredicates)
+ OS << "bool " << Rec->getValueAsString("FunctionName")
+ << "(const MCInst &MI);\n";
- for (const Record *Rec : TIIPredicates) {
- OS << "bool " << Rec->getValueAsString("FunctionName")
- << "(const MCInst &MI);\n";
+ OS << "void verifyInstructionPredicates(unsigned Opcode, const "
+ "FeatureBitset "
+ "&Features);\n";
}
- OS << "void verifyInstructionPredicates(unsigned Opcode, const FeatureBitset "
- "&Features);\n";
-
- OS << "\n} // end namespace " << TargetName << "_MC\n";
- OS << "} // end namespace llvm\n\n";
-
- OS << "#endif // GET_INSTRINFO_MC_HELPER_DECLS\n\n";
-
- OS << "#ifdef GET_INSTRINFO_MC_HELPERS\n";
- OS << "#undef GET_INSTRINFO_MC_HELPERS\n\n";
-
- OS << "namespace llvm::" << TargetName << "_MC {\n";
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_HELPERS");
+ NamespaceEmitter NS(OS, ("llvm::" + TargetName + "_MC").str());
- PredicateExpander PE(TargetName);
- PE.setExpandForMC(true);
+ PredicateExpander PE(TargetName);
+ PE.setExpandForMC(true);
- for (const Record *Rec : TIIPredicates) {
- OS << "bool " << Rec->getValueAsString("FunctionName");
- OS << "(const MCInst &MI) {\n";
+ for (const Record *Rec : TIIPredicates) {
+ OS << "bool " << Rec->getValueAsString("FunctionName");
+ OS << "(const MCInst &MI) {\n";
- OS << PE.getIndent();
- PE.expandStatement(OS, Rec->getValueAsDef("Body"));
- OS << "\n}\n\n";
+ OS << PE.getIndent();
+ PE.expandStatement(OS, Rec->getValueAsDef("Body"));
+ OS << "\n}\n\n";
+ }
}
-
- OS << "} // end namespace llvm::" << TargetName << "_MC\n";
-
- OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n\n";
}
static std::string
@@ -710,148 +691,143 @@ void InstrInfoEmitter::emitFeatureVerifier(raw_ostream &OS,
<< " defined(GET_AVAILABLE_OPCODE_CHECKER)\n"
<< "#define GET_COMPUTE_FEATURES\n"
<< "#endif\n";
- OS << "#ifdef GET_COMPUTE_FEATURES\n"
- << "#undef GET_COMPUTE_FEATURES\n"
- << "namespace llvm::" << Target.getName() << "_MC {\n";
-
- // Emit the subtarget feature enumeration.
- SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
- OS);
- // Emit the available features compute function.
- OS << "inline ";
- SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
- Target.getName(), "", "computeAvailableFeatures", SubtargetFeatures, OS);
-
- std::vector<std::vector<const Record *>> FeatureBitsets;
- for (const CodeGenInstruction *Inst : Target.getInstructions()) {
- FeatureBitsets.emplace_back();
- for (const Record *Predicate :
- Inst->TheDef->getValueAsListOfDefs("Predicates")) {
- const auto &I = SubtargetFeatures.find(Predicate);
- if (I != SubtargetFeatures.end())
- FeatureBitsets.back().push_back(I->second.TheDef);
+ std::string Namespace = ("llvm::" + Target.getName() + "_MC").str();
+ {
+ IfDefEmitter IfDef(OS, "GET_COMPUTE_FEATURES");
+ NamespaceEmitter NS(OS, Namespace);
+
+ // Emit the subtarget feature enumeration.
+ SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
+ OS);
+ // Emit the available features compute function.
+ OS << "inline ";
+ SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
+ Target.getName(), "", "computeAvailableFeatures", SubtargetFeatures,
+ OS);
+
+ std::vector<std::vector<const Record *>> FeatureBitsets;
+ for (const CodeGenInstruction *Inst : Target.getInstructions()) {
+ FeatureBitsets.emplace_back();
+ for (const Record *Predicate :
+ Inst->TheDef->getValueAsListOfDefs("Predicates")) {
+ const auto &I = SubtargetFeatures.find(Predicate);
+ if (I != SubtargetFeatures.end())
+ FeatureBitsets.back().push_back(I->second.TheDef);
+ }
}
- }
- llvm::sort(FeatureBitsets, [&](ArrayRef<const Record *> A,
- ArrayRef<const Record *> B) {
- if (A.size() < B.size())
- return true;
- if (A.size() > B.size())
- return false;
- for (auto Pair : zip(A, B)) {
- if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
+ llvm::sort(FeatureBitsets, [&](ArrayRef<const Record *> A,
+ ArrayRef<const Record *> B) {
+ if (A.size() < B.size())
return true;
- if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
+ if (A.size() > B.size())
return false;
+ for (auto Pair : zip(A, B)) {
+ if (std::get<0>(Pair)->getName() < std::get<1>(Pair)->getName())
+ return true;
+ if (std::get<0>(Pair)->getName() > std::get<1>(Pair)->getName())
+ return false;
+ }
+ return false;
+ });
+ FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end());
+ OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n"
+ << " enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
+ << " CEFBS_None,\n";
+ for (const auto &FeatureBitset : FeatureBitsets) {
+ if (FeatureBitset.empty())
+ continue;
+ OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
}
- return false;
- });
- FeatureBitsets.erase(llvm::unique(FeatureBitsets), FeatureBitsets.end());
- OS << "inline FeatureBitset computeRequiredFeatures(unsigned Opcode) {\n"
- << " enum : " << getMinimalTypeForRange(FeatureBitsets.size()) << " {\n"
- << " CEFBS_None,\n";
- for (const auto &FeatureBitset : FeatureBitsets) {
- if (FeatureBitset.empty())
- continue;
- OS << " " << getNameForFeatureBitset(FeatureBitset) << ",\n";
- }
- OS << " };\n\n"
- << " static constexpr FeatureBitset FeatureBitsets[] = {\n"
- << " {}, // CEFBS_None\n";
- for (const auto &FeatureBitset : FeatureBitsets) {
- if (FeatureBitset.empty())
- continue;
- OS << " {";
- for (const auto &Feature : FeatureBitset) {
- const auto &I = SubtargetFeatures.find(Feature);
- assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
- OS << I->second.getEnumBitName() << ", ";
+ OS << " };\n\n"
+ << " static constexpr FeatureBitset FeatureBitsets[] = {\n"
+ << " {}, // CEFBS_None\n";
+ for (const auto &FeatureBitset : FeatureBitsets) {
+ if (FeatureBitset.empty())
+ continue;
+ OS << " {";
+ for (const auto &Feature : FeatureBitset) {
+ const auto &I = SubtargetFeatures.find(Feature);
+ assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
+ OS << I->second.getEnumBitName() << ", ";
+ }
+ OS << "},\n";
}
- OS << "},\n";
- }
- OS << " };\n"
- << " static constexpr " << getMinimalTypeForRange(FeatureBitsets.size())
- << " RequiredFeaturesRefs[] = {\n";
- ArrayRef<const CodeGenInstruction *> NumberedInstructions =
- Target.getInstructions();
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
- OS << " CEFBS";
- unsigned NumPredicates = 0;
- for (const Record *Predicate :
- Inst->TheDef->getValueAsListOfDefs("Predicates")) {
- const auto &I = SubtargetFeatures.find(Predicate);
- if (I != SubtargetFeatures.end()) {
- OS << '_' << I->second.TheDef->getName();
- NumPredicates++;
+ OS << " };\n"
+ << " static constexpr " << getMinimalTypeForRange(FeatureBitsets.size())
+ << " RequiredFeaturesRefs[] = {\n";
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions =
+ Target.getInstructions();
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ OS << " CEFBS";
+ unsigned NumPredicates = 0;
+ for (const Record *Predicate :
+ Inst->TheDef->getValueAsListOfDefs("Predicates")) {
+ const auto &I = SubtargetFeatures.find(Predicate);
+ if (I != SubtargetFeatures.end()) {
+ OS << '_' << I->second.TheDef->getName();
+ NumPredicates++;
+ }
}
+ if (!NumPredicates)
+ OS << "_None";
+ OS << ", // " << Inst->getName() << '\n';
}
- if (!NumPredicates)
- OS << "_None";
- OS << ", // " << Inst->getName() << '\n';
+ OS << " };\n\n"
+ << " assert(Opcode < " << NumberedInstructions.size() << ");\n"
+ << " return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
+ << "}\n\n";
+ } // end scope for GET_COMPUTE_FEATURES
+
+ {
+ IfDefEmitter IfDef(OS, "GET_AVAILABLE_OPCODE_CHECKER");
+ NamespaceEmitter NS(OS, Namespace);
+ OS << "bool isOpcodeAvailable("
+ << "unsigned Opcode, const FeatureBitset &Features) {\n"
+ << " FeatureBitset AvailableFeatures = "
+ << "computeAvailableFeatures(Features);\n"
+ << " FeatureBitset RequiredFeatures = "
+ << "computeRequiredFeatures(Opcode);\n"
+ << " FeatureBitset MissingFeatures =\n"
+ << " (AvailableFeatures & RequiredFeatures) ^\n"
+ << " RequiredFeatures;\n"
+ << " return !MissingFeatures.any();\n"
+ << "}\n";
+ }
+
+ {
+ IfDefEmitter IfDef(OS, "ENABLE_INSTR_PREDICATE_VERIFIER");
+ OS << "#include <sstream>\n\n";
+ NamespaceEmitter NS(OS, Namespace);
+ // Emit the name table for error messages.
+ OS << "#ifndef NDEBUG\n";
+ SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
+ OS << "#endif // NDEBUG\n\n";
+ // Emit the predicate verifier.
+ OS << "void verifyInstructionPredicates(\n"
+ << " unsigned Opcode, const FeatureBitset &Features) {\n"
+ << "#ifndef NDEBUG\n";
+ OS << " FeatureBitset AvailableFeatures = "
+ "computeAvailableFeatures(Features);\n";
+ OS << " FeatureBitset RequiredFeatures = "
+ << "computeRequiredFeatures(Opcode);\n";
+ OS << " FeatureBitset MissingFeatures =\n"
+ << " (AvailableFeatures & RequiredFeatures) ^\n"
+ << " RequiredFeatures;\n"
+ << " if (MissingFeatures.any()) {\n"
+ << " std::ostringstream Msg;\n"
+ << " Msg << \"Attempting to emit \" << &" << Target.getName()
+ << "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
+ << " << \" instruction but the \";\n"
+ << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
+ << " if (MissingFeatures.test(i))\n"
+ << " Msg << SubtargetFeatureNames[i] << \" \";\n"
+ << " Msg << \"predicate(s) are not met\";\n"
+ << " report_fatal_error(Msg.str().c_str());\n"
+ << " }\n"
+ << "#endif // NDEBUG\n";
+ OS << "}\n";
}
- OS << " };\n\n"
- << " assert(Opcode < " << NumberedInstructions.size() << ");\n"
- << " return FeatureBitsets[RequiredFeaturesRefs[Opcode]];\n"
- << "}\n\n";
-
- OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
- << "#endif // GET_COMPUTE_FEATURES\n\n";
-
- OS << "#ifdef GET_AVAILABLE_OPCODE_CHECKER\n"
- << "#undef GET_AVAILABLE_OPCODE_CHECKER\n"
- << "namespace llvm::" << Target.getName() << "_MC {\n";
- OS << "bool isOpcodeAvailable("
- << "unsigned Opcode, const FeatureBitset &Features) {\n"
- << " FeatureBitset AvailableFeatures = "
- << "computeAvailableFeatures(Features);\n"
- << " FeatureBitset RequiredFeatures = "
- << "computeRequiredFeatures(Opcode);\n"
- << " FeatureBitset MissingFeatures =\n"
- << " (AvailableFeatures & RequiredFeatures) ^\n"
- << " RequiredFeatures;\n"
- << " return !MissingFeatures.any();\n"
- << "}\n";
- OS << "} // end namespace llvm::" << Target.getName() << "_MC\n"
- << "#endif // GET_AVAILABLE_OPCODE_CHECKER\n\n";
-
- OS << "#ifdef ENABLE_INSTR_PREDICATE_VERIFIER\n"
- << "#undef ENABLE_INSTR_PREDICATE_VERIFIER\n"
- << "#include <sstream>\n\n";
-
- OS << "namespace llvm::" << Target.getName() << "_MC {\n";
-
- // Emit the name table for error messages.
- OS << "#ifndef NDEBUG\n";
- SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
- OS << "#endif // NDEBUG\n\n";
-
- // Emit the predicate verifier.
- OS << "void verifyInstructionPredicates(\n"
- << " unsigned Opcode, const FeatureBitset &Features) {\n"
- << "#ifndef NDEBUG\n";
- OS << " FeatureBitset AvailableFeatures = "
- "computeAvailableFeatures(Features);\n";
- OS << " FeatureBitset RequiredFeatures = "
- << "computeRequiredFeatures(Opcode);\n";
- OS << " FeatureBitset MissingFeatures =\n"
- << " (AvailableFeatures & RequiredFeatures) ^\n"
- << " RequiredFeatures;\n"
- << " if (MissingFeatures.any()) {\n"
- << " std::ostringstream Msg;\n"
- << " Msg << \"Attempting to emit \" << &" << Target.getName()
- << "InstrNameData[" << Target.getName() << "InstrNameIndices[Opcode]]\n"
- << " << \" instruction but the \";\n"
- << " for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i)\n"
- << " if (MissingFeatures.test(i))\n"
- << " Msg << SubtargetFeatureNames[i] << \" \";\n"
- << " Msg << \"predicate(s) are not met\";\n"
- << " report_fatal_error(Msg.str().c_str());\n"
- << " }\n"
- << "#endif // NDEBUG\n";
- OS << "}\n";
- OS << "} // end namespace llvm::" << Target.getName() << "_MC\n";
- OS << "#endif // ENABLE_INSTR_PREDICATE_VERIFIER\n\n";
}
void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS,
@@ -954,270 +930,263 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || "
"defined(GET_INSTRINFO_CTOR_DTOR)\n\n";
- OS << "#ifdef GET_INSTRINFO_MC_DESC\n";
- OS << "#undef GET_INSTRINFO_MC_DESC\n";
- OS << "namespace llvm {\n\n";
-
- // Emit all of the MCInstrDesc records in reverse ENUM ordering.
- Timer.startTimer("Emit InstrDesc records");
- OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
- OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
- << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
-
- OS << "extern const " << TargetName << "InstrTable " << TargetName
- << "Descs = {\n {\n";
- SequenceToOffsetTable<StringRef> InstrNames;
- unsigned Num = NumberedInstructions.size();
- for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
- // Keep a list of the instruction names.
- InstrNames.add(Inst->getName());
- // Emit the record into the table.
- emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
- }
-
- OS << " }, {\n";
-
- // Emit all of the operand info records.
- Timer.startTimer("Emit operand info");
- EmitOperandInfo(OS, OperandInfoList);
-
- OS << " }, {\n";
-
- // Emit all of the instruction's implicit uses and defs.
- Timer.startTimer("Emit uses/defs");
- for (auto &List : ImplicitLists) {
- OS << " /* " << EmittedLists[List] << " */";
- for (auto &Reg : List)
- OS << ' ' << getQualifiedName(Reg) << ',';
- OS << '\n';
- }
-
- OS << " }\n};\n\n";
-
- // Emit the array of instruction names.
- Timer.startTimer("Emit instruction names");
- InstrNames.layout();
- InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName +
- "InstrNameData[]");
const CodeGenRegBank &RegBank = Target.getRegBank();
const CodeGenHwModes &CGH = Target.getHwModes();
unsigned NumModes = CGH.getNumModeIds();
ArrayRef<const Record *> RegClassByHwMode = Target.getAllRegClassByHwMode();
unsigned NumClassesByHwMode = RegClassByHwMode.size();
- OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
- Num = 0;
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
- // Newline every eight entries.
- if (Num % 8 == 0)
- OS << "\n ";
- OS << InstrNames.get(Inst->getName()) << "U, ";
- ++Num;
- }
- OS << "\n};\n\n";
-
bool HasDeprecationFeatures =
llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
return !Inst->HasComplexDeprecationPredicate &&
!Inst->DeprecatedReason.empty();
});
- if (HasDeprecationFeatures) {
- OS << "extern const uint8_t " << TargetName
- << "InstrDeprecationFeatures[] = {";
- Num = 0;
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
- if (Num % 8 == 0)
- OS << "\n ";
- if (!Inst->HasComplexDeprecationPredicate &&
- !Inst->DeprecatedReason.empty())
- OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
- << ", ";
- else
- OS << "uint8_t(-1), ";
- ++Num;
- }
- OS << "\n};\n\n";
- }
-
bool HasComplexDeprecationInfos =
llvm::any_of(NumberedInstructions, [](const CodeGenInstruction *Inst) {
return Inst->HasComplexDeprecationPredicate;
});
- if (HasComplexDeprecationInfos) {
- OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
- << "InstrComplexDeprecationInfos[] = {";
+
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_MC_DESC");
+ NamespaceEmitter LlvmNS(OS, "llvm");
+
+ // Emit all of the MCInstrDesc records in reverse ENUM ordering.
+ Timer.startTimer("Emit InstrDesc records");
+ OS << "static_assert(sizeof(MCOperandInfo) % sizeof(MCPhysReg) == 0);\n";
+ OS << "static constexpr unsigned " << TargetName << "ImpOpBase = sizeof "
+ << TargetName << "InstrTable::OperandInfo / (sizeof(MCPhysReg));\n\n";
+
+ OS << "extern const " << TargetName << "InstrTable " << TargetName
+ << "Descs = {\n {\n";
+ SequenceToOffsetTable<StringRef> InstrNames;
+ unsigned Num = NumberedInstructions.size();
+ for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) {
+ // Keep a list of the instruction names.
+ InstrNames.add(Inst->getName());
+ // Emit the record into the table.
+ emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS);
+ }
+
+ OS << " }, {\n";
+
+ // Emit all of the operand info records.
+ Timer.startTimer("Emit operand info");
+ EmitOperandInfo(OS, OperandInfoList);
+
+ OS << " }, {\n";
+
+ // Emit all of the instruction's implicit uses and defs.
+ Timer.startTimer("Emit uses/defs");
+ for (auto &List : ImplicitLists) {
+ OS << " /* " << EmittedLists[List] << " */";
+ for (auto &Reg : List)
+ OS << ' ' << getQualifiedName(Reg) << ',';
+ OS << '\n';
+ }
+
+ OS << " }\n};\n\n";
+
+ // Emit the array of instruction names.
+ Timer.startTimer("Emit instruction names");
+ InstrNames.layout();
+ InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") +
+ TargetName + "InstrNameData[]");
+ OS << "extern const unsigned " << TargetName << "InstrNameIndices[] = {";
Num = 0;
for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ // Newline every eight entries.
if (Num % 8 == 0)
OS << "\n ";
- if (Inst->HasComplexDeprecationPredicate)
- // Emit a function pointer to the complex predicate method.
- OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
- else
- OS << "nullptr, ";
+ OS << InstrNames.get(Inst->getName()) << "U, ";
++Num;
}
OS << "\n};\n\n";
- }
-
- // MCInstrInfo initialization routine.
- Timer.startTimer("Emit initialization routine");
-
- if (NumClassesByHwMode != 0) {
- OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
- << NumModes << "][" << NumClassesByHwMode << "] = {\n";
- for (unsigned M = 0; M < NumModes; ++M) {
- OS << " { // " << CGH.getModeName(M, /*IncludeDefault=*/true) << '\n';
- for (unsigned I = 0; I != NumClassesByHwMode; ++I) {
- const Record *Class = RegClassByHwMode[I];
- const HwModeSelect &ModeSelect = CGH.getHwModeSelect(Class);
-
- auto FoundMode =
- find_if(ModeSelect.Items, [=](const HwModeSelect::PairType P) {
- return P.first == M;
- });
-
- if (FoundMode == ModeSelect.Items.end()) {
- // If a RegClassByHwMode doesn't have an entry corresponding to a
- // mode, pad with default register class.
- OS << indent(4) << "-1, // Missing mode entry\n";
- } else {
- const CodeGenRegisterClass *RegClass =
- RegBank.getRegClass(FoundMode->second);
- OS << indent(4) << RegClass->getQualifiedIdName() << ",\n";
- }
+ if (HasDeprecationFeatures) {
+ OS << "extern const uint8_t " << TargetName
+ << "InstrDeprecationFeatures[] = {";
+ Num = 0;
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ if (Num % 8 == 0)
+ OS << "\n ";
+ if (!Inst->HasComplexDeprecationPredicate &&
+ !Inst->DeprecatedReason.empty())
+ OS << Target.getInstNamespace() << "::" << Inst->DeprecatedReason
+ << ", ";
+ else
+ OS << "uint8_t(-1), ";
+ ++Num;
}
-
- OS << " },\n";
+ OS << "\n};\n\n";
}
- OS << "};\n\n";
- }
+ if (HasComplexDeprecationInfos) {
+ OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
+ << TargetName << "InstrComplexDeprecationInfos[] = {";
+ Num = 0;
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ if (Num % 8 == 0)
+ OS << "\n ";
+ if (Inst->HasComplexDeprecationPredicate)
+ // Emit a function pointer to the complex predicate method.
+ OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
+ else
+ OS << "nullptr, ";
+ ++Num;
+ }
+ OS << "\n};\n\n";
+ }
- OS << "static inline void Init" << TargetName
- << "MCInstrInfo(MCInstrInfo *II) {\n";
- OS << " II->InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
- << "InstrNameIndices, " << TargetName << "InstrNameData, ";
- if (HasDeprecationFeatures)
- OS << TargetName << "InstrDeprecationFeatures, ";
- else
- OS << "nullptr, ";
- if (HasComplexDeprecationInfos)
- OS << TargetName << "InstrComplexDeprecationInfos, ";
- else
- OS << "nullptr, ";
- OS << NumberedInstructions.size() << ", ";
-
- if (NumClassesByHwMode != 0) {
- OS << '&' << TargetName << "RegClassByHwModeTables[0][0], "
- << NumClassesByHwMode;
- } else
- OS << "nullptr, 0";
-
- OS << ");\n}\n\n";
+ // MCInstrInfo initialization routine.
+ Timer.startTimer("Emit initialization routine");
+
+ if (NumClassesByHwMode != 0) {
+ OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
+ << NumModes << "][" << NumClassesByHwMode << "] = {\n";
+
+ for (unsigned M = 0; M < NumModes; ++M) {
+ OS << " { // " << CGH.getModeName(M, /*IncludeDefault=*/true) << '\n';
+ for (unsigned I = 0; I != NumClassesByHwMode; ++I) {
+ const Record *Class = RegClassByHwMode[I];
+ const HwModeSelect &ModeSelect = CGH.getHwModeSelect(Class);
+
+ auto FoundMode =
+ find_if(ModeSelect.Items, [=](const HwModeSelect::PairType P) {
+ return P.first == M;
+ });
+
+ if (FoundMode == ModeSelect.Items.end()) {
+ // If a RegClassByHwMode doesn't have an entry corresponding to a
+ // mode, pad with default register class.
+ OS << indent(4) << "-1, // Missing mode entry\n";
+ } else {
+ const CodeGenRegisterClass *RegClass =
+ RegBank.getRegClass(FoundMode->second);
+ OS << indent(4) << RegClass->getQualifiedIdName() << ",\n";
+ }
+ }
- OS << "} // end namespace llvm\n";
+ OS << " },\n";
+ }
- OS << "#endif // GET_INSTRINFO_MC_DESC\n\n";
+ OS << "};\n\n";
+ }
- // Create a TargetInstrInfo subclass to hide the MC layer initialization.
- OS << "#ifdef GET_INSTRINFO_HEADER\n";
- OS << "#undef GET_INSTRINFO_HEADER\n";
+ OS << "static inline void Init" << TargetName
+ << "MCInstrInfo(MCInstrInfo *II) {\n";
+ OS << " II->InitMCInstrInfo(" << TargetName << "Descs.Insts, "
+ << TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, ";
+ if (HasDeprecationFeatures)
+ OS << TargetName << "InstrDeprecationFeatures, ";
+ else
+ OS << "nullptr, ";
+ if (HasComplexDeprecationInfos)
+ OS << TargetName << "InstrComplexDeprecationInfos, ";
+ else
+ OS << "nullptr, ";
+ OS << NumberedInstructions.size() << ", ";
- Twine ClassName = TargetName + "GenInstrInfo";
- OS << "namespace llvm {\n";
- OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
- << " explicit " << ClassName
- << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode = ~0u, "
- "unsigned CFDestroyOpcode = ~0u, "
- "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
- << " ~" << ClassName << "() override = default;\n";
+ if (NumClassesByHwMode != 0) {
+ OS << '&' << TargetName << "RegClassByHwModeTables[0][0], "
+ << NumClassesByHwMode;
+ } else
+ OS << "nullptr, 0";
- OS << "\n};\n} // end namespace llvm\n";
+ OS << ");\n}\n\n";
+ } // end GET_INSTRINFO_MC_DESC scope.
{
- NamespaceEmitter LlvmNS(OS, "llvm");
- NamespaceEmitter TargetNS(OS, Target.getInstNamespace());
+ // Create a TargetInstrInfo subclass to hide the MC layer initialization.
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_HEADER");
+ {
+ NamespaceEmitter LlvmNS(OS, "llvm");
+ Twine ClassName = TargetName + "GenInstrInfo";
+ OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
+ << " explicit " << ClassName
+ << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode = ~0u, "
+ "unsigned CFDestroyOpcode = ~0u, "
+ "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n"
+ << " ~" << ClassName << "() override = default;\n"
+ << "};\n";
+ } // end llvm namespace.
+
+ OS << "\n";
+ NamespaceEmitter InstNS(OS, ("llvm::" + Target.getInstNamespace()).str());
for (const Record *R : Records.getAllDerivedDefinitions("Operand")) {
if (R->isAnonymous())
continue;
- if (const DagInit *D = R->getValueAsDag("MIOperandInfo")) {
- for (unsigned i = 0, e = D->getNumArgs(); i < e; ++i) {
- if (const StringInit *Name = D->getArgName(i))
- OS << "constexpr unsigned SUBOP_" << R->getName() << "_"
- << Name->getValue() << " = " << i << ";\n";
- }
+ const DagInit *D = R->getValueAsDag("MIOperandInfo");
+ if (!D)
+ continue;
+ for (const auto &[Idx, Name] : enumerate(D->getArgNames())) {
+ if (Name)
+ OS << "constexpr unsigned SUBOP_" << R->getName() << "_"
+ << Name->getValue() << " = " << Idx << ";\n";
}
}
- }
-
- OS << "#endif // GET_INSTRINFO_HEADER\n\n";
-
- OS << "#ifdef GET_INSTRINFO_HELPER_DECLS\n";
- OS << "#undef GET_INSTRINFO_HELPER_DECLS\n\n";
- emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
- OS << '\n';
- OS << "#endif // GET_INSTRINFO_HELPER_DECLS\n\n";
-
- OS << "#ifdef GET_INSTRINFO_HELPERS\n";
- OS << "#undef GET_INSTRINFO_HELPERS\n\n";
- emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
- OS << "#endif // GET_INSTRINFO_HELPERS\n\n";
+ } // end GET_INSTRINFO_HEADER scope.
- OS << "#ifdef GET_INSTRINFO_CTOR_DTOR\n";
- OS << "#undef GET_INSTRINFO_CTOR_DTOR\n";
-
- OS << "namespace llvm {\n";
- OS << "extern const " << TargetName << "InstrTable " << TargetName
- << "Descs;\n";
- OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
- OS << "extern const char " << TargetName << "InstrNameData[];\n";
-
- if (NumClassesByHwMode != 0) {
- OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
- << NumModes << "][" << NumClassesByHwMode << "];\n";
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_HELPER_DECLS");
+ emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ false);
}
- if (HasDeprecationFeatures)
- OS << "extern const uint8_t " << TargetName
- << "InstrDeprecationFeatures[];\n";
- if (HasComplexDeprecationInfos)
- OS << "extern const MCInstrInfo::ComplexDeprecationPredicate " << TargetName
- << "InstrComplexDeprecationInfos[];\n";
- OS << ClassName << "::" << ClassName
- << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode, unsigned "
- "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n"
- << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
- "ReturnOpcode";
- if (NumClassesByHwMode != 0)
- OS << ", " << TargetName
- << "RegClassByHwModeTables[STI.getHwMode(MCSubtargetInfo::HwMode_"
- "RegInfo)]";
-
- OS << ") {\n"
- << " InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
- << "InstrNameIndices, " << TargetName << "InstrNameData, ";
- if (HasDeprecationFeatures)
- OS << TargetName << "InstrDeprecationFeatures, ";
- else
- OS << "nullptr, ";
- if (HasComplexDeprecationInfos)
- OS << TargetName << "InstrComplexDeprecationInfos, ";
- else
- OS << "nullptr, ";
- OS << NumberedInstructions.size();
-
- if (NumClassesByHwMode != 0) {
- OS << ", &" << TargetName << "RegClassByHwModeTables[0][0], "
- << NumClassesByHwMode;
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_HELPERS");
+ emitTIIHelperMethods(OS, TargetName, /* ExpandDefinition = */ true);
}
- OS << ");\n"
- "}\n"
- "} // end namespace llvm\n";
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_CTOR_DTOR");
+ NamespaceEmitter LlvmNS(OS, "llvm");
+ OS << "extern const " << TargetName << "InstrTable " << TargetName
+ << "Descs;\n";
+ OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
+ OS << "extern const char " << TargetName << "InstrNameData[];\n";
+
+ if (NumClassesByHwMode != 0) {
+ OS << "extern const int16_t " << TargetName << "RegClassByHwModeTables["
+ << NumModes << "][" << NumClassesByHwMode << "];\n";
+ }
+
+ if (HasDeprecationFeatures)
+ OS << "extern const uint8_t " << TargetName
+ << "InstrDeprecationFeatures[];\n";
+ if (HasComplexDeprecationInfos)
+ OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
+ << TargetName << "InstrComplexDeprecationInfos[];\n";
+ Twine ClassName = TargetName + "GenInstrInfo";
+ OS << ClassName << "::" << ClassName
+ << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode, unsigned "
+ "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n"
+ << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, "
+ "ReturnOpcode";
+ if (NumClassesByHwMode != 0)
+ OS << ", " << TargetName
+ << "RegClassByHwModeTables[STI.getHwMode(MCSubtargetInfo::HwMode_"
+ "RegInfo)]";
+
+ OS << ") {\n"
+ << " InitMCInstrInfo(" << TargetName << "Descs.Insts, " << TargetName
+ << "InstrNameIndices, " << TargetName << "InstrNameData, ";
+ if (HasDeprecationFeatures)
+ OS << TargetName << "InstrDeprecationFeatures, ";
+ else
+ OS << "nullptr, ";
+ if (HasComplexDeprecationInfos)
+ OS << TargetName << "InstrComplexDeprecationInfos, ";
+ else
+ OS << "nullptr, ";
+ OS << NumberedInstructions.size();
- OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n";
+ if (NumClassesByHwMode != 0) {
+ OS << ", &" << TargetName << "RegClassByHwModeTables[0][0], "
+ << NumClassesByHwMode;
+ }
+
+ OS << ");\n"
+ "}\n";
+ } // end GET_INSTRINFO_CTOR_DTOR scope.
ArrayRef<const CodeGenInstruction *> TargetInstructions =
Target.getTargetInstructions();
@@ -1384,8 +1353,6 @@ void InstrInfoEmitter::emitRecord(
void InstrInfoEmitter::emitEnums(
raw_ostream &OS,
ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
- OS << "#ifdef GET_INSTRINFO_ENUM\n";
- OS << "#undef GET_INSTRINFO_ENUM\n";
const CodeGenTarget &Target = CDP.getTargetInfo();
StringRef Namespace = Target.getInstNamespace();
@@ -1393,48 +1360,48 @@ void InstrInfoEmitter::emitEnums(
if (Namespace.empty())
PrintFatalError("No instructions defined!");
- OS << "namespace llvm::" << Namespace << " {\n";
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_ENUM");
+ NamespaceEmitter NS(OS, ("llvm::" + Namespace).str());
- auto II = llvm::max_element(
- NumberedInstructions,
- [](const CodeGenInstruction *InstA, const CodeGenInstruction *InstB) {
- return InstA->getName().size() < InstB->getName().size();
- });
- size_t MaxNameSize = (*II)->getName().size();
+ auto II = llvm::max_element(
+ NumberedInstructions,
+ [](const CodeGenInstruction *InstA, const CodeGenInstruction *InstB) {
+ return InstA->getName().size() < InstB->getName().size();
+ });
+ size_t MaxNameSize = (*II)->getName().size();
- OS << " enum {\n";
- for (const CodeGenInstruction *Inst : NumberedInstructions) {
- OS << " " << left_justify(Inst->getName(), MaxNameSize) << " = "
- << Target.getInstrIntValue(Inst->TheDef) << ", // "
- << SrcMgr.getFormattedLocationNoOffset(Inst->TheDef->getLoc().front())
- << '\n';
+ OS << " enum {\n";
+ for (const CodeGenInstruction *Inst : NumberedInstructions) {
+ OS << " " << left_justify(Inst->getName(), MaxNameSize) << " = "
+ << Target.getInstrIntValue(Inst->TheDef) << ", // "
+ << SrcMgr.getFormattedLocationNoOffset(Inst->TheDef->getLoc().front())
+ << '\n';
+ }
+ OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << '\n';
+ OS << " };\n";
+
+ ArrayRef<const Record *> RegClassesByHwMode =
+ Target.getAllRegClassByHwMode();
+ if (!RegClassesByHwMode.empty()) {
+ OS << " enum RegClassByHwModeUses : uint16_t {\n";
+ for (const Record *ClassByHwMode : RegClassesByHwMode)
+ OS << indent(4) << ClassByHwMode->getName() << ",\n";
+ OS << " };\n";
+ }
}
- OS << " INSTRUCTION_LIST_END = " << NumberedInstructions.size() << '\n';
- OS << " };\n";
- ArrayRef<const Record *> RegClassesByHwMode = Target.getAllRegClassByHwMode();
- if (!RegClassesByHwMode.empty()) {
- OS << " enum RegClassByHwModeUses : uint16_t {\n";
- for (const Record *ClassByHwMode : RegClassesByHwMode)
- OS << indent(4) << ClassByHwMode->getName() << ",\n";
+ {
+ IfDefEmitter IfDef(OS, "GET_INSTRINFO_SCHED_ENUM");
+ NamespaceEmitter NS(OS, ("llvm::" + Namespace + "::Sched").str());
+
+ OS << " enum {\n";
+ auto ExplictClasses = SchedModels.explicitSchedClasses();
+ for (const auto &[Idx, Class] : enumerate(ExplictClasses))
+ OS << " " << Class.Name << "\t= " << Idx << ",\n";
+ OS << " SCHED_LIST_END = " << ExplictClasses.size() << '\n';
OS << " };\n";
}
-
- OS << "} // end namespace llvm::" << Namespace << '\n';
- OS << "#endif // GET_INSTRINFO_ENUM\n\n";
-
- OS << "#ifdef GET_INSTRINFO_SCHED_ENUM\n";
- OS << "#undef GET_INSTRINFO_SCHED_ENUM\n";
- OS << "namespace llvm::" << Namespace << "::Sched {\n";
- OS << " enum {\n";
- auto ExplictClasses = SchedModels.explicitSchedClasses();
- for (const auto &[Idx, Class] : enumerate(ExplictClasses))
- OS << " " << Class.Name << "\t= " << Idx << ",\n";
- OS << " SCHED_LIST_END = " << ExplictClasses.size() << '\n';
- OS << " };\n";
- OS << "} // end namespace llvm::" << Namespace << "::Sched\n";
-
- OS << "#endif // GET_INSTRINFO_SCHED_ENUM\n\n";
}
static TableGen::Emitter::OptClass<InstrInfoEmitter>
diff --git a/llvm/utils/UpdateTestChecks/common.py b/llvm/utils/UpdateTestChecks/common.py
index 2dad16a..baa0377 100644
--- a/llvm/utils/UpdateTestChecks/common.py
+++ b/llvm/utils/UpdateTestChecks/common.py
@@ -605,6 +605,7 @@ TRIPLE_IR_RE = re.compile(r'^\s*target\s+triple\s*=\s*"([^"]+)"$')
TRIPLE_ARG_RE = re.compile(r"-m?triple[= ]([^ ]+)")
MARCH_ARG_RE = re.compile(r"-march[= ]([^ ]+)")
DEBUG_ONLY_ARG_RE = re.compile(r"-debug-only[= ]([^ ]+)")
+STOP_PASS_RE = re.compile(r"-stop-(before|after)=(\w+)")
IS_DEBUG_RECORD_RE = re.compile(r"^(\s+)#dbg_")
IS_SWITCH_CASE_RE = re.compile(r"^\s+i\d+ \d+, label %\S+")
diff --git a/llvm/utils/UpdateTestChecks/mir.py b/llvm/utils/UpdateTestChecks/mir.py
index 24bb8b3..01ee0e1 100644
--- a/llvm/utils/UpdateTestChecks/mir.py
+++ b/llvm/utils/UpdateTestChecks/mir.py
@@ -163,13 +163,15 @@ def add_mir_checks_for_function(
print_fixed_stack,
first_check_is_next,
at_the_function_name,
+ check_indent=None,
):
printed_prefixes = set()
for run in run_list:
for prefix in run[0]:
if prefix in printed_prefixes:
break
- if not func_dict[prefix][func_name]:
+ # func_info can be empty if there was a prefix conflict.
+ if not func_dict[prefix].get(func_name):
continue
if printed_prefixes:
# Add some space between different check prefixes.
@@ -185,6 +187,7 @@ def add_mir_checks_for_function(
func_dict[prefix][func_name],
print_fixed_stack,
first_check_is_next,
+ check_indent,
)
break
else:
@@ -204,6 +207,7 @@ def add_mir_check_lines(
func_info,
print_fixed_stack,
first_check_is_next,
+ check_indent=None,
):
func_body = str(func_info).splitlines()
if single_bb:
@@ -220,7 +224,10 @@ def add_mir_check_lines(
first_line = func_body[0]
indent = len(first_line) - len(first_line.lstrip(" "))
# A check comment, indented the appropriate amount
- check = "{:>{}}; {}".format("", indent, prefix)
+ if check_indent is not None:
+ check = "{}; {}".format(check_indent, prefix)
+ else:
+ check = "{:>{}}; {}".format("", indent, prefix)
output_lines.append("{}-LABEL: name: {}".format(check, func_name))
diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index 9e0b951..27bd2ce 100644
--- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -336,6 +336,7 @@ if (current_toolchain == default_toolchain) {
"__chrono/gps_clock.h",
"__chrono/hh_mm_ss.h",
"__chrono/high_resolution_clock.h",
+ "__chrono/is_clock.h",
"__chrono/leap_second.h",
"__chrono/literals.h",
"__chrono/local_info.h",
diff --git a/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn
index 783eb96..679373d 100644
--- a/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn
+++ b/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn
@@ -72,6 +72,7 @@ static_library("Target") {
"Statistics.cpp",
"StopInfo.cpp",
"StructuredDataPlugin.cpp",
+ "SyntheticFrameProvider.cpp",
"SystemRuntime.cpp",
"Target.cpp",
"TargetList.cpp",
diff --git a/llvm/utils/update_llc_test_checks.py b/llvm/utils/update_llc_test_checks.py
index 8c57e75..98864be 100755
--- a/llvm/utils/update_llc_test_checks.py
+++ b/llvm/utils/update_llc_test_checks.py
@@ -15,7 +15,7 @@ import argparse
import os # Used to advertise this file's name ("autogenerated_note").
import sys
-from UpdateTestChecks import common
+from UpdateTestChecks import common, mir
# llc is the only llc-like in the LLVM tree but downstream forks can add
# additional ones here if they have them.
@@ -33,6 +33,7 @@ def update_test(ti: common.TestInfo):
break
run_list = []
+ mir_run_list = []
for l in ti.run_lines:
if "|" not in l:
common.warn("Skipping unparsable RUN line: " + l)
@@ -57,9 +58,14 @@ def update_test(ti: common.TestInfo):
if m:
march_in_cmd = m.groups()[0]
+ target_list = run_list
m = common.DEBUG_ONLY_ARG_RE.search(llc_cmd)
if m and m.groups()[0] == "isel":
from UpdateTestChecks import isel as output_type
+ elif not m and common.STOP_PASS_RE.search(llc_cmd):
+ # MIR output mode. If -debug-only is present assume
+ # the debug output is the main point of interest.
+ target_list = mir_run_list
else:
from UpdateTestChecks import asm as output_type
@@ -84,7 +90,7 @@ def update_test(ti: common.TestInfo):
# FIXME: We should use multiple check prefixes to common check lines. For
# now, we just ignore all but the last.
- run_list.append(
+ target_list.append(
(
check_prefixes,
llc_tool,
@@ -119,14 +125,20 @@ def update_test(ti: common.TestInfo):
ginfo=ginfo,
)
- for (
- prefixes,
- llc_tool,
- llc_args,
- preprocess_cmd,
- triple_in_cmd,
- march_in_cmd,
- ) in run_list:
+ # Dictionary to store MIR function bodies separately
+ mir_func_dict = {}
+ for run_tuple, is_mir in [(run, False) for run in run_list] + [
+ (run, True) for run in mir_run_list
+ ]:
+ (
+ prefixes,
+ llc_tool,
+ llc_args,
+ preprocess_cmd,
+ triple_in_cmd,
+ march_in_cmd,
+ ) = run_tuple
+
common.debug("Extracted LLC cmd:", llc_tool, llc_args)
common.debug("Extracted FileCheck prefixes:", str(prefixes))
@@ -141,22 +153,54 @@ def update_test(ti: common.TestInfo):
if not triple:
triple = common.get_triple_from_march(march_in_cmd)
- scrubber, function_re = output_type.get_run_handler(triple)
- if 0 == builder.process_run_line(
- function_re, scrubber, raw_tool_output, prefixes
- ):
- common.warn(
- "Couldn't match any function. Possibly the wrong target triple has been provided"
+ if is_mir:
+ # MIR output mode
+ common.debug("Detected MIR output mode for prefixes:", str(prefixes))
+ for prefix in prefixes:
+ if prefix not in mir_func_dict:
+ mir_func_dict[prefix] = {}
+
+ mir.build_function_info_dictionary(
+ ti.path,
+ raw_tool_output,
+ triple,
+ prefixes,
+ mir_func_dict,
+ ti.args.verbose,
)
- builder.processed_prefixes(prefixes)
+ else:
+ # ASM output mode
+ scrubber, function_re = output_type.get_run_handler(triple)
+ if 0 == builder.process_run_line(
+ function_re, scrubber, raw_tool_output, prefixes
+ ):
+ common.warn(
+ "Couldn't match any function. Possibly the wrong target triple has been provided"
+ )
+ builder.processed_prefixes(prefixes)
func_dict = builder.finish_and_get_func_dict()
+
+ # Check for conflicts: same prefix used for both ASM and MIR
+ conflicting_prefixes = set(func_dict.keys()) & set(mir_func_dict.keys())
+ if conflicting_prefixes:
+ common.warn(
+ "The following prefixes are used for both ASM and MIR output, which will cause FileCheck failures: {}".format(
+ ", ".join(sorted(conflicting_prefixes))
+ ),
+ test_file=ti.path,
+ )
+ for prefix in conflicting_prefixes:
+ mir_func_dict[prefix] = {}
+ func_dict[prefix] = {}
+
global_vars_seen_dict = {}
is_in_function = False
is_in_function_start = False
func_name = None
prefix_set = set([prefix for p in run_list for prefix in p[0]])
+ prefix_set.update([prefix for p in mir_run_list for prefix in p[0]])
common.debug("Rewriting FileCheck prefixes:", str(prefix_set))
output_lines = []
@@ -221,6 +265,22 @@ def update_test(ti: common.TestInfo):
is_filtered=builder.is_filtered(),
)
)
+
+ # Also add MIR checks if we have them for this function
+ if mir_run_list and func_name:
+ mir.add_mir_checks_for_function(
+ ti.path,
+ output_lines,
+ mir_run_list,
+ mir_func_dict,
+ func_name,
+ single_bb=False, # Don't skip basic block labels.
+ print_fixed_stack=False, # Don't print fixed stack (ASM tests don't need it).
+ first_check_is_next=False, # First check is LABEL, not NEXT.
+ at_the_function_name=False, # Use "name:" not "@name".
+ check_indent="", # No indentation for IR files (not MIR files).
+ )
+
is_in_function_start = False
if is_in_function: