diff options
Diffstat (limited to 'llvm/utils')
170 files changed, 3559 insertions, 1152 deletions
diff --git a/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp b/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp index b63ce36..a18fed0 100644 --- a/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp +++ b/llvm/utils/TableGen/Basic/ARMTargetDefEmitter.cpp @@ -159,12 +159,15 @@ static void emitARMTargetDef(const RecordKeeper &RK, raw_ostream &OS) { << " if(I.size()) return I;\n" << " I.reserve(" << FMVExts.size() << ");\n"; for (const Record *Rec : FMVExts) { + auto FeatName = Rec->getValueAsString("BackendFeature"); + const Record *FeatRec = ExtensionMap[FeatName]; OS << " I.emplace_back("; OS << "\"" << Rec->getValueAsString("Name") << "\""; - OS << ", " << Rec->getValueAsString("FeatureBit"); + if (FeatRec) + OS << ", " << Rec->getValueAsString("FeatureBit"); + else + OS << ", std::nullopt"; OS << ", " << Rec->getValueAsString("PriorityBit"); - auto FeatName = Rec->getValueAsString("BackendFeature"); - const Record *FeatRec = ExtensionMap[FeatName]; if (FeatRec) OS << ", " << FeatRec->getValueAsString("ArchExtKindSpelling").upper(); else diff --git a/llvm/utils/TableGen/Basic/CMakeLists.txt b/llvm/utils/TableGen/Basic/CMakeLists.txt index 2030e9a..01ab8a0 100644 --- a/llvm/utils/TableGen/Basic/CMakeLists.txt +++ b/llvm/utils/TableGen/Basic/CMakeLists.txt @@ -20,6 +20,7 @@ add_llvm_library(LLVMTableGenBasic OBJECT EXCLUDE_FROM_ALL DISABLE_LLVM_LINK_LLV SDNodeProperties.cpp TableGen.cpp TargetFeaturesEmitter.cpp + TargetLibraryInfoEmitter.cpp VTEmitter.cpp ) diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp index ff89485..d90fcc2 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp @@ -13,6 +13,7 @@ #include "CodeGenIntrinsics.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/TableGen/Error.h" @@ -377,7 +378,19 @@ void CodeGenIntrinsic::setProperty(const Record *R) { ME &= MemoryEffects::argMemOnly(); else if (R->getName() == "IntrInaccessibleMemOnly") ME &= MemoryEffects::inaccessibleMemOnly(); - else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") + else if (R->isSubClassOf("IntrRead")) { + MemoryEffects ReadMask = MemoryEffects::writeOnly(); + for (const Record *RLoc : R->getValueAsListOfDefs("MemLoc")) + ReadMask = ReadMask.getWithModRef(getValueAsIRMemLocation(RLoc), + ModRefInfo::ModRef); + ME &= ReadMask; + } else if (R->isSubClassOf("IntrWrite")) { + MemoryEffects WriteMask = MemoryEffects::readOnly(); + for (const Record *WLoc : R->getValueAsListOfDefs("MemLoc")) + WriteMask = WriteMask.getWithModRef(getValueAsIRMemLocation(WLoc), + ModRefInfo::ModRef); + ME &= WriteMask; + } else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly") ME &= MemoryEffects::inaccessibleOrArgMemOnly(); else if (R->getName() == "Commutative") isCommutative = true; @@ -449,11 +462,50 @@ void CodeGenIntrinsic::setProperty(const Record *R) { int64_t Lower = R->getValueAsInt("Lower"); int64_t Upper = R->getValueAsInt("Upper"); addArgAttribute(ArgNo, Range, Lower, Upper); + } else if (R->isSubClassOf("ArgInfo")) { + unsigned ArgNo = R->getValueAsInt("ArgNo"); + if (ArgNo < 1) + PrintFatalError(R->getLoc(), + "ArgInfo requires ArgNo >= 1 (0 is return value)"); + const ListInit *Properties = R->getValueAsListInit("Properties"); + StringRef ArgName; + StringRef FuncName; + + for (const Init *PropInit : Properties->getElements()) { + if (const auto *PropDef = dyn_cast<DefInit>(PropInit)) { + const Record *PropRec = PropDef->getDef(); + + if (PropRec->isSubClassOf("ArgName")) + ArgName = PropRec->getValueAsString("Name"); + else if (PropRec->isSubClassOf("ImmArgPrinter")) + FuncName = PropRec->getValueAsString("FuncName"); + else + PrintFatalError(PropRec->getLoc(), + "Unknown ArgProperty type: " + PropRec->getName()); + } + } + addPrettyPrintFunction(ArgNo - 1, ArgName, FuncName); } else { llvm_unreachable("Unknown property!"); } } +llvm::IRMemLocation +CodeGenIntrinsic::getValueAsIRMemLocation(const Record *R) const { + StringRef Name = R->getName(); + IRMemLocation Loc = + StringSwitch<IRMemLocation>(Name) + .Case("TargetMem0", IRMemLocation::TargetMem0) + .Case("TargetMem1", IRMemLocation::TargetMem1) + .Case("InaccessibleMem", IRMemLocation::InaccessibleMem) + .Default(IRMemLocation::Other); // fallback enum + + if (Loc == IRMemLocation::Other) + PrintFatalError(R->getLoc(), "unknown IRMemLocation: " + Name); + + return Loc; +} + bool CodeGenIntrinsic::isParamAPointer(unsigned ParamIdx) const { if (ParamIdx >= IS.ParamTys.size()) return false; @@ -476,3 +528,16 @@ void CodeGenIntrinsic::addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V, ArgumentAttributes.resize(Idx + 1); ArgumentAttributes[Idx].emplace_back(AK, V, V2); } + +void CodeGenIntrinsic::addPrettyPrintFunction(unsigned ArgIdx, + StringRef ArgName, + StringRef FuncName) { + auto It = llvm::find_if(PrettyPrintFunctions, [ArgIdx](const auto &Info) { + return Info.ArgIdx == ArgIdx; + }); + if (It != PrettyPrintFunctions.end()) + PrintFatalError(TheDef->getLoc(), "ArgInfo for argument " + Twine(ArgIdx) + + " is already defined as '" + + It->FuncName + "'"); + PrettyPrintFunctions.emplace_back(ArgIdx, ArgName, FuncName); +} diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h index 15e803c..305260a 100644 --- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h @@ -152,6 +152,22 @@ struct CodeGenIntrinsic { void addArgAttribute(unsigned Idx, ArgAttrKind AK, uint64_t V = 0, uint64_t V2 = 0); + /// Structure to store pretty print and argument information. + struct PrettyPrintArgInfo { + unsigned ArgIdx; + StringRef ArgName; + StringRef FuncName; + + PrettyPrintArgInfo(unsigned Idx, StringRef Name, StringRef Func) + : ArgIdx(Idx), ArgName(Name), FuncName(Func) {} + }; + + /// Vector that stores ArgInfo (ArgIndex, ArgName, FunctionName). + SmallVector<PrettyPrintArgInfo> PrettyPrintFunctions; + + void addPrettyPrintFunction(unsigned ArgIdx, StringRef ArgName, + StringRef FuncName); + bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); } /// Goes through all IntrProperties that have IsDefault value set and sets @@ -170,6 +186,8 @@ struct CodeGenIntrinsic { bool isParamImmArg(unsigned ParamIdx) const; + llvm::IRMemLocation getValueAsIRMemLocation(const Record *R) const; + CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx); }; diff --git a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp index 0bb743d..1126c83 100644 --- a/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp +++ b/llvm/utils/TableGen/Basic/DirectiveEmitter.cpp @@ -276,80 +276,81 @@ static void emitDirectivesDecl(const RecordKeeper &Records, raw_ostream &OS) { OS << "#include <utility>\n"; // for std::pair OS << "\n"; NamespaceEmitter LlvmNS(OS, "llvm"); - NamespaceEmitter DirLangNS(OS, DirLang.getCppNamespace()); - - if (DirLang.hasEnableBitmaskEnumInNamespace()) - OS << "LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n\n"; - - // Emit Directive associations - std::vector<const Record *> Associations; - copy_if(DirLang.getAssociations(), std::back_inserter(Associations), - // Skip the "special" value - [](const Record *Def) { return Def->getName() != "AS_FromLeaves"; }); - generateEnumClass(Associations, OS, "Association", - /*Prefix=*/"", /*ExportEnums=*/false); - - generateEnumClass(DirLang.getCategories(), OS, "Category", /*Prefix=*/"", - /*ExportEnums=*/false); - - generateEnumBitmask(DirLang.getSourceLanguages(), OS, "SourceLanguage", + { + NamespaceEmitter DirLangNS(OS, DirLang.getCppNamespace()); + + if (DirLang.hasEnableBitmaskEnumInNamespace()) + OS << "LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();\n\n"; + + // Emit Directive associations + std::vector<const Record *> Associations; + copy_if( + DirLang.getAssociations(), std::back_inserter(Associations), + // Skip the "special" value + [](const Record *Def) { return Def->getName() != "AS_FromLeaves"; }); + generateEnumClass(Associations, OS, "Association", /*Prefix=*/"", /*ExportEnums=*/false); - // Emit Directive enumeration - generateEnumClass(DirLang.getDirectives(), OS, "Directive", - DirLang.getDirectivePrefix(), - DirLang.hasMakeEnumAvailableInNamespace()); + generateEnumClass(DirLang.getCategories(), OS, "Category", /*Prefix=*/"", + /*ExportEnums=*/false); - // Emit Clause enumeration - generateEnumClass(DirLang.getClauses(), OS, "Clause", - DirLang.getClausePrefix(), - DirLang.hasMakeEnumAvailableInNamespace()); + generateEnumBitmask(DirLang.getSourceLanguages(), OS, "SourceLanguage", + /*Prefix=*/"", /*ExportEnums=*/false); - // Emit ClauseVals enumeration - std::string EnumHelperFuncs; - generateClauseEnumVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs); + // Emit Directive enumeration + generateEnumClass(DirLang.getDirectives(), OS, "Directive", + DirLang.getDirectivePrefix(), + DirLang.hasMakeEnumAvailableInNamespace()); - // Generic function signatures - OS << "// Enumeration helper functions\n"; + // Emit Clause enumeration + generateEnumClass(DirLang.getClauses(), OS, "Clause", + DirLang.getClausePrefix(), + DirLang.hasMakeEnumAvailableInNamespace()); - OS << "LLVM_ABI std::pair<Directive, directive::VersionRange> get" << Lang - << "DirectiveKindAndVersions(StringRef Str);\n"; + // Emit ClauseVals enumeration + std::string EnumHelperFuncs; + generateClauseEnumVal(DirLang.getClauses(), OS, DirLang, EnumHelperFuncs); - OS << "inline Directive get" << Lang << "DirectiveKind(StringRef Str) {\n"; - OS << " return get" << Lang << "DirectiveKindAndVersions(Str).first;\n"; - OS << "}\n"; - OS << "\n"; + // Generic function signatures + OS << "// Enumeration helper functions\n"; - OS << "LLVM_ABI StringRef get" << Lang - << "DirectiveName(Directive D, unsigned Ver = 0);\n"; - OS << "\n"; + OS << "LLVM_ABI std::pair<Directive, directive::VersionRange> get" << Lang + << "DirectiveKindAndVersions(StringRef Str);\n"; - OS << "LLVM_ABI std::pair<Clause, directive::VersionRange> get" << Lang - << "ClauseKindAndVersions(StringRef Str);\n"; - OS << "\n"; + OS << "inline Directive get" << Lang << "DirectiveKind(StringRef Str) {\n"; + OS << " return get" << Lang << "DirectiveKindAndVersions(Str).first;\n"; + OS << "}\n"; + OS << "\n"; - OS << "inline Clause get" << Lang << "ClauseKind(StringRef Str) {\n"; - OS << " return get" << Lang << "ClauseKindAndVersions(Str).first;\n"; - OS << "}\n"; - OS << "\n"; + OS << "LLVM_ABI StringRef get" << Lang + << "DirectiveName(Directive D, unsigned Ver = 0);\n"; + OS << "\n"; - OS << "LLVM_ABI StringRef get" << Lang - << "ClauseName(Clause C, unsigned Ver = 0);\n"; - OS << "\n"; + OS << "LLVM_ABI std::pair<Clause, directive::VersionRange> get" << Lang + << "ClauseKindAndVersions(StringRef Str);\n"; + OS << "\n"; - OS << "/// Return true if \\p C is a valid clause for \\p D in version \\p " - << "Version.\n"; - OS << "LLVM_ABI bool isAllowedClauseForDirective(Directive D, " - << "Clause C, unsigned Version);\n"; - OS << "\n"; - OS << "constexpr std::size_t getMaxLeafCount() { return " - << getMaxLeafCount(DirLang) << "; }\n"; - OS << "LLVM_ABI Association getDirectiveAssociation(Directive D);\n"; - OS << "LLVM_ABI Category getDirectiveCategory(Directive D);\n"; - OS << "LLVM_ABI SourceLanguage getDirectiveLanguages(Directive D);\n"; - OS << EnumHelperFuncs; + OS << "inline Clause get" << Lang << "ClauseKind(StringRef Str) {\n"; + OS << " return get" << Lang << "ClauseKindAndVersions(Str).first;\n"; + OS << "}\n"; + OS << "\n"; - DirLangNS.close(); + OS << "LLVM_ABI StringRef get" << Lang + << "ClauseName(Clause C, unsigned Ver = 0);\n"; + OS << "\n"; + + OS << "/// Return true if \\p C is a valid clause for \\p D in version \\p " + << "Version.\n"; + OS << "LLVM_ABI bool isAllowedClauseForDirective(Directive D, " + << "Clause C, unsigned Version);\n"; + OS << "\n"; + OS << "constexpr std::size_t getMaxLeafCount() { return " + << getMaxLeafCount(DirLang) << "; }\n"; + OS << "LLVM_ABI Association getDirectiveAssociation(Directive D);\n"; + OS << "LLVM_ABI Category getDirectiveCategory(Directive D);\n"; + OS << "LLVM_ABI SourceLanguage getDirectiveLanguages(Directive D);\n"; + OS << EnumHelperFuncs; + } // close DirLangNS // These specializations need to be in ::llvm. for (StringRef Enum : {"Association", "Category", "Directive", "Clause"}) { @@ -728,11 +729,12 @@ static void emitLeafTable(const DirectiveLanguage &DirLang, raw_ostream &OS, static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang, raw_ostream &OS) { enum struct Association { - None = 0, // None should be the smallest value. - Block, // The values of the rest don't matter. - Declaration, + None = 0, // None should be the smallest value. + Block, // If the order of the rest of these changes, update the + Declaration, // 'Reduce' function below. Delimited, - Loop, + LoopNest, + LoopSeq, Separating, FromLeaves, Invalid, @@ -745,7 +747,8 @@ static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang, .Case("AS_Block", Association::Block) .Case("AS_Declaration", Association::Declaration) .Case("AS_Delimited", Association::Delimited) - .Case("AS_Loop", Association::Loop) + .Case("AS_LoopNest", Association::LoopNest) + .Case("AS_LoopSeq", Association::LoopSeq) .Case("AS_None", Association::None) .Case("AS_Separating", Association::Separating) .Case("AS_FromLeaves", Association::FromLeaves) @@ -776,13 +779,12 @@ static void generateGetDirectiveAssociation(const DirectiveLanguage &DirLang, // Calculate the result using the following rules: // x + x = x // AS_None + x = x - // AS_Block + AS_Loop = AS_Loop + // AS_Block + AS_Loop{Nest|Seq} = AS_Loop{Nest|Seq} if (A == Association::None || A == B) return B; - if (A == Association::Block && B == Association::Loop) + if (A == Association::Block && + (B == Association::LoopNest || B == Association::LoopSeq)) return B; - if (A == Association::Loop && B == Association::Block) - return A; return Association::Invalid; }; diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp index 452d2b0..9fed592 100644 --- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp @@ -60,8 +60,16 @@ public: raw_ostream &OS); void EmitIntrinsicToOverloadTable(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); + void EmitIntrinsicToPrettyPrintTable(const CodeGenIntrinsicTable &Ints, + raw_ostream &OS); + void EmitIntrinsicBitTable( + const CodeGenIntrinsicTable &Ints, raw_ostream &OS, StringRef Guard, + StringRef TableName, StringRef Comment, + function_ref<bool(const CodeGenIntrinsic &Int)> GetProperty); void EmitGenerator(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); void EmitAttributes(const CodeGenIntrinsicTable &Ints, raw_ostream &OS); + void EmitPrettyPrintArguments(const CodeGenIntrinsicTable &Ints, + raw_ostream &OS); void EmitIntrinsicToBuiltinMap(const CodeGenIntrinsicTable &Ints, bool IsClang, raw_ostream &OS); }; @@ -109,6 +117,12 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) { // Emit the intrinsic parameter attributes. EmitAttributes(Ints, OS); + // Emit the intrinsic ID -> pretty print table. + EmitIntrinsicToPrettyPrintTable(Ints, OS); + + // Emit Pretty Print attribute. + EmitPrettyPrintArguments(Ints, OS); + // Emit code to translate Clang builtins into LLVM intrinsics. EmitIntrinsicToBuiltinMap(Ints, true, OS); @@ -240,6 +254,29 @@ static constexpr IntrinsicTargetInfo TargetInfos[] = { )"; } +/// Helper function to emit a bit table for intrinsic properties. +/// This is used for both overload and pretty print bit tables. +void IntrinsicEmitter::EmitIntrinsicBitTable( + const CodeGenIntrinsicTable &Ints, raw_ostream &OS, StringRef Guard, + StringRef TableName, StringRef Comment, + function_ref<bool(const CodeGenIntrinsic &Int)> GetProperty) { + OS << formatv("// {}\n", Comment); + OS << formatv("#ifdef {}\n", Guard); + OS << formatv("static constexpr uint8_t {}[] = {{\n", TableName); + OS << " 0\n "; + for (auto [I, Int] : enumerate(Ints)) { + // Add one to the index so we emit a null bit for the invalid #0 intrinsic. + size_t Idx = I + 1; + if (Idx % 8 == 0) + OS << ",\n 0"; + if (GetProperty(Int)) + OS << " | (1<<" << Idx % 8 << ')'; + } + OS << "\n};\n\n"; + OS << formatv("return ({}[id/8] & (1 << (id%8))) != 0;\n", TableName); + OS << formatv("#endif // {}\n\n", Guard); +} + void IntrinsicEmitter::EmitIntrinsicToNameTable( const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { // Built up a table of the intrinsic names. @@ -276,24 +313,10 @@ static constexpr unsigned IntrinsicNameOffsetTable[] = { void IntrinsicEmitter::EmitIntrinsicToOverloadTable( const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { - OS << R"(// Intrinsic ID to overload bitset. -#ifdef GET_INTRINSIC_OVERLOAD_TABLE -static constexpr uint8_t OTable[] = { - 0 - )"; - for (auto [I, Int] : enumerate(Ints)) { - // Add one to the index so we emit a null bit for the invalid #0 intrinsic. - size_t Idx = I + 1; - - if (Idx % 8 == 0) - OS << ",\n 0"; - if (Int.isOverloaded) - OS << " | (1<<" << Idx % 8 << ')'; - } - OS << "\n};\n\n"; - // OTable contains a true bit at the position if the intrinsic is overloaded. - OS << "return (OTable[id/8] & (1 << (id%8))) != 0;\n"; - OS << "#endif\n\n"; + EmitIntrinsicBitTable( + Ints, OS, "GET_INTRINSIC_OVERLOAD_TABLE", "OTable", + "Intrinsic ID to overload bitset.", + [](const CodeGenIntrinsic &Int) { return Int.isOverloaded; }); } using TypeSigTy = SmallVector<unsigned char>; @@ -576,10 +599,10 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) { if (!UniqFnAttributes.try_emplace(&Int, ID).second) continue; OS << formatv(R"( - case {}: + case {}: // {} return AttributeSet::get(C, {{ )", - ID); + ID, Int.Name); auto addAttribute = [&OS](StringRef Attr) { OS << formatv(" Attribute::get(C, Attribute::{}),\n", Attr); }; @@ -809,6 +832,52 @@ AttributeSet Intrinsic::getFnAttributes(LLVMContext &C, ID id) {{ NoFunctionAttrsID); } +void IntrinsicEmitter::EmitIntrinsicToPrettyPrintTable( + const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { + EmitIntrinsicBitTable(Ints, OS, "GET_INTRINSIC_PRETTY_PRINT_TABLE", "PPTable", + "Intrinsic ID to pretty print bitset.", + [](const CodeGenIntrinsic &Int) { + return !Int.PrettyPrintFunctions.empty(); + }); +} + +void IntrinsicEmitter::EmitPrettyPrintArguments( + const CodeGenIntrinsicTable &Ints, raw_ostream &OS) { + OS << R"( +#ifdef GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS +void Intrinsic::printImmArg(ID IID, unsigned ArgIdx, raw_ostream &OS, const Constant *ImmArgVal) { + using namespace Intrinsic; + switch (IID) { +)"; + + for (const CodeGenIntrinsic &Int : Ints) { + if (Int.PrettyPrintFunctions.empty()) + continue; + + OS << " case " << Int.EnumName << ":\n"; + OS << " switch (ArgIdx) {\n"; + for (const auto [ArgIdx, ArgName, FuncName] : Int.PrettyPrintFunctions) { + OS << " case " << ArgIdx << ":\n"; + OS << " OS << \"" << ArgName << "=\";\n"; + if (!FuncName.empty()) { + OS << " "; + if (!Int.TargetPrefix.empty()) + OS << Int.TargetPrefix << "::"; + OS << FuncName << "(OS, ImmArgVal);\n"; + } + OS << " return;\n"; + } + OS << " }\n"; + OS << " break;\n"; + } + OS << R"( default: + break; + } +} +#endif // GET_INTRINSIC_PRETTY_PRINT_ARGUMENTS +)"; +} + void IntrinsicEmitter::EmitIntrinsicToBuiltinMap( const CodeGenIntrinsicTable &Ints, bool IsClang, raw_ostream &OS) { StringRef CompilerName = IsClang ? "Clang" : "MS"; diff --git a/llvm/utils/TableGen/Basic/SequenceToOffsetTable.h b/llvm/utils/TableGen/Basic/SequenceToOffsetTable.h index 761ef1f..1cd18b7 100644 --- a/llvm/utils/TableGen/Basic/SequenceToOffsetTable.h +++ b/llvm/utils/TableGen/Basic/SequenceToOffsetTable.h @@ -162,7 +162,8 @@ public: /// emit - Print out the table as the body of an array initializer. /// Use the Print function to print elements. - void emit(raw_ostream &OS, void (*Print)(raw_ostream &, ElemT)) const { + void emit(raw_ostream &OS, + function_ref<void(raw_ostream &, ElemT)> Print) const { assert(IsLaidOut && "Call layout() before emit()"); for (const auto &[Seq, Offset] : Seqs) { OS << " /* " << Offset << " */ "; diff --git a/llvm/utils/TableGen/Basic/TableGen.cpp b/llvm/utils/TableGen/Basic/TableGen.cpp index edb7791..a655cbb 100644 --- a/llvm/utils/TableGen/Basic/TableGen.cpp +++ b/llvm/utils/TableGen/Basic/TableGen.cpp @@ -60,7 +60,9 @@ static TableGen::Emitter::Opt X[] = { true}, {"print-detailed-records", EmitDetailedRecords, "Print full details of all records to stdout"}, - {"null-backend", [](const RecordKeeper &Records, raw_ostream &OS) {}, + {"null-backend", + TableGen::Emitter::FnT( + [](const RecordKeeper &Records, raw_ostream &OS) {}), "Do nothing after parsing (useful for timing)"}, {"dump-json", EmitJSON, "Dump all records as machine-readable JSON"}, {"print-enums", printEnums, "Print enum values for a class"}, @@ -71,7 +73,8 @@ int tblgen_main(int argc, char **argv) { InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv); - return TableGenMain(argv[0]); + MultiFileTableGenMainFn MainFn = nullptr; + return TableGenMain(argv[0], MainFn); } #ifndef __has_feature diff --git a/llvm/utils/TableGen/Basic/TargetLibraryInfoEmitter.cpp b/llvm/utils/TableGen/Basic/TargetLibraryInfoEmitter.cpp new file mode 100644 index 0000000..253d9df --- /dev/null +++ b/llvm/utils/TableGen/Basic/TargetLibraryInfoEmitter.cpp @@ -0,0 +1,185 @@ +//===- TargetLibraryInfoEmitter.cpp - Properties from TargetLibraryInfo.td ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SequenceToOffsetTable.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Error.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/SetTheory.h" +#include "llvm/TableGen/StringToOffsetTable.h" +#include "llvm/TableGen/TableGenBackend.h" +#include <cstddef> + +#define DEBUG_TYPE "target-library-info-emitter" + +using namespace llvm; + +namespace { +class TargetLibraryInfoEmitter { +private: + const RecordKeeper &Records; + SmallVector<const Record *, 1024> AllTargetLibcalls; + +private: + void emitTargetLibraryInfoEnum(raw_ostream &OS) const; + void emitTargetLibraryInfoStringTable(raw_ostream &OS) const; + void emitTargetLibraryInfoSignatureTable(raw_ostream &OS) const; + +public: + TargetLibraryInfoEmitter(const RecordKeeper &R); + + void run(raw_ostream &OS); +}; + +} // End anonymous namespace. + +TargetLibraryInfoEmitter::TargetLibraryInfoEmitter(const RecordKeeper &R) + : Records(R) { + ArrayRef<const Record *> All = + Records.getAllDerivedDefinitions("TargetLibCall"); + AllTargetLibcalls.append(All.begin(), All.end()); + // Make sure that the records are in the same order as the input. + // TODO Find a better sorting order when all is migrated. + sort(AllTargetLibcalls, [](const Record *A, const Record *B) { + return A->getID() < B->getID(); + }); +} + +// Emits the LibFunc enumeration, which is an abstract name for each library +// function. +void TargetLibraryInfoEmitter::emitTargetLibraryInfoEnum( + raw_ostream &OS) const { + OS << "#ifdef GET_TARGET_LIBRARY_INFO_ENUM\n"; + OS << "#undef GET_TARGET_LIBRARY_INFO_ENUM\n"; + OS << "enum LibFunc : unsigned {\n"; + OS.indent(2) << "NotLibFunc = 0,\n"; + for (const auto *R : AllTargetLibcalls) { + OS.indent(2) << "LibFunc_" << R->getName() << ",\n"; + } + OS.indent(2) << "NumLibFuncs,\n"; + OS.indent(2) << "End_LibFunc = NumLibFuncs,\n"; + if (AllTargetLibcalls.size()) { + OS.indent(2) << "Begin_LibFunc = LibFunc_" + << AllTargetLibcalls[0]->getName() << ",\n"; + } else { + OS.indent(2) << "Begin_LibFunc = NotLibFunc,\n"; + } + OS << "};\n"; + OS << "#endif\n\n"; +} + +// The names of the functions are stored in a long string, along with support +// tables for accessing the offsets of the function names from the beginning of +// the string. +void TargetLibraryInfoEmitter::emitTargetLibraryInfoStringTable( + raw_ostream &OS) const { + llvm::StringToOffsetTable Table( + /*AppendZero=*/true, + "TargetLibraryInfoImpl::", /*UsePrefixForStorageMember=*/false); + for (const auto *R : AllTargetLibcalls) + Table.GetOrAddStringOffset(R->getValueAsString("String")); + + OS << "#ifdef GET_TARGET_LIBRARY_INFO_STRING_TABLE\n"; + OS << "#undef GET_TARGET_LIBRARY_INFO_STRING_TABLE\n"; + Table.EmitStringTableDef(OS, "StandardNamesStrTable"); + OS << "\n"; + size_t NumEl = AllTargetLibcalls.size() + 1; + OS << "const llvm::StringTable::Offset " + "TargetLibraryInfoImpl::StandardNamesOffsets[" + << NumEl + << "] = " + "{\n"; + OS.indent(2) << "0, //\n"; + for (const auto *R : AllTargetLibcalls) { + StringRef Str = R->getValueAsString("String"); + OS.indent(2) << Table.GetStringOffset(Str) << ", // " << Str << "\n"; + } + OS << "};\n"; + OS << "const uint8_t TargetLibraryInfoImpl::StandardNamesSizeTable[" << NumEl + << "] = {\n"; + OS << " 0,\n"; + for (const auto *R : AllTargetLibcalls) + OS.indent(2) << R->getValueAsString("String").size() << ",\n"; + OS << "};\n"; + OS << "#endif\n\n"; + OS << "#ifdef GET_TARGET_LIBRARY_INFO_IMPL_DECL\n"; + OS << "#undef GET_TARGET_LIBRARY_INFO_IMPL_DECL\n"; + OS << "LLVM_ABI static const llvm::StringTable StandardNamesStrTable;\n"; + OS << "LLVM_ABI static const llvm::StringTable::Offset StandardNamesOffsets[" + << NumEl << "];\n"; + OS << "LLVM_ABI static const uint8_t StandardNamesSizeTable[" << NumEl + << "];\n"; + OS << "#endif\n\n"; +} + +// Since there are much less type signatures then library functions, the type +// signatures are stored reusing existing entries. To access a table entry, an +// offset table is used. +void TargetLibraryInfoEmitter::emitTargetLibraryInfoSignatureTable( + raw_ostream &OS) const { + SmallVector<const Record *, 1024> FuncTypeArgs( + Records.getAllDerivedDefinitions("FuncArgType")); + + // Sort the records by ID. + sort(FuncTypeArgs, [](const Record *A, const Record *B) { + return A->getID() < B->getID(); + }); + + using Signature = std::vector<StringRef>; + SequenceToOffsetTable<Signature> SignatureTable("NoFuncArgType"); + auto GetSignature = [](const Record *R) -> Signature { + const auto *Tys = R->getValueAsListInit("ArgumentTypes"); + Signature Sig; + Sig.reserve(Tys->size() + 1); + const Record *RetType = R->getValueAsOptionalDef("ReturnType"); + if (RetType) + Sig.push_back(RetType->getName()); + for (unsigned I = 0, E = Tys->size(); I < E; ++I) { + Sig.push_back(Tys->getElementAsRecord(I)->getName()); + } + return Sig; + }; + Signature NoFuncSig({StringRef("Void")}); + SignatureTable.add(NoFuncSig); + for (const auto *R : AllTargetLibcalls) + SignatureTable.add(GetSignature(R)); + SignatureTable.layout(); + + OS << "#ifdef GET_TARGET_LIBRARY_INFO_SIGNATURE_TABLE\n"; + OS << "#undef GET_TARGET_LIBRARY_INFO_SIGNATURE_TABLE\n"; + OS << "enum FuncArgTypeID : char {\n"; + OS.indent(2) << "NoFuncArgType = 0,\n"; + for (const auto *R : FuncTypeArgs) { + OS.indent(2) << R->getName() << ",\n"; + } + OS << "};\n"; + OS << "static const FuncArgTypeID SignatureTable[] = {\n"; + SignatureTable.emit(OS, [](raw_ostream &OS, StringRef E) { OS << E; }); + OS << "};\n"; + OS << "static const uint16_t SignatureOffset[] = {\n"; + OS.indent(2) << SignatureTable.get(NoFuncSig) << ", //\n"; + for (const auto *R : AllTargetLibcalls) { + OS.indent(2) << SignatureTable.get(GetSignature(R)) << ", // " + << R->getName() << "\n"; + } + OS << "};\n"; + OS << "#endif\n\n"; +} + +void TargetLibraryInfoEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("Target Library Info Source Fragment", OS, Records); + + emitTargetLibraryInfoEnum(OS); + emitTargetLibraryInfoStringTable(OS); + emitTargetLibraryInfoSignatureTable(OS); +} + +static TableGen::Emitter::OptClass<TargetLibraryInfoEmitter> + X("gen-target-library-info", "Generate TargetLibraryInfo"); diff --git a/llvm/utils/TableGen/Basic/VTEmitter.cpp b/llvm/utils/TableGen/Basic/VTEmitter.cpp index 301b27d..87f5f4b 100644 --- a/llvm/utils/TableGen/Basic/VTEmitter.cpp +++ b/llvm/utils/TableGen/Basic/VTEmitter.cpp @@ -91,11 +91,14 @@ void VTEmitter::run(raw_ostream &OS) { emitSourceFileHeader("ValueTypes Source Fragment", OS, Records); std::vector<const Record *> VTsByNumber{512}; - for (auto *VT : Records.getAllDerivedDefinitions("ValueType")) { - auto Number = VT->getValueAsInt("Value"); - assert(0 <= Number && Number < (int)VTsByNumber.size() && - "ValueType should be uint16_t"); - assert(!VTsByNumber[Number] && "Duplicate ValueType"); + unsigned Number = 0; + std::vector<const Record *> Defs( + Records.getAllDerivedDefinitions("ValueType")); + // Emit VTs in the order they were declared so that VTRanges stay contiguous. + llvm::sort(Defs, LessRecordByID()); + for (auto *VT : Defs) { + ++Number; + assert(Number < VTsByNumber.size() && "ValueType should be uint16_t"); VTsByNumber[Number] = VT; } @@ -120,13 +123,12 @@ void VTEmitter::run(raw_ostream &OS) { } }; - OS << "#ifdef GET_VT_ATTR // (Ty, n, sz, Any, Int, FP, Vec, Sc, Tup, NF, " + OS << "#ifdef GET_VT_ATTR // (Ty, sz, Any, Int, FP, Vec, Sc, Tup, NF, " "NElem, EltTy)\n"; for (const auto *VT : VTsByNumber) { if (!VT) continue; auto Name = VT->getValueAsString("LLVMName"); - auto Value = VT->getValueAsInt("Value"); bool IsInteger = VT->getValueAsBit("isInteger"); bool IsFP = VT->getValueAsBit("isFP"); bool IsVector = VT->getValueAsBit("isVector"); @@ -158,7 +160,6 @@ void VTEmitter::run(raw_ostream &OS) { // clang-format off OS << " GET_VT_ATTR(" << Name << ", " - << Value << ", " << VT->getValueAsInt("Size") << ", " << VT->getValueAsBit("isOverloaded") << ", " << (IsInteger ? Name[0] == 'i' ? 3 : 1 : 0) << ", " diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp b/llvm/utils/TableGen/CallingConvEmitter.cpp index e0d9337..369238d 100644 --- a/llvm/utils/TableGen/CallingConvEmitter.cpp +++ b/llvm/utils/TableGen/CallingConvEmitter.cpp @@ -15,6 +15,7 @@ #include "Common/CodeGenTarget.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/InterleavedRange.h" +#include "llvm/TableGen/CodeGenHelpers.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/TGTimer.h" @@ -54,6 +55,21 @@ private: }; } // End anonymous namespace +static void emitCCHeader(raw_ostream &O, const Record *CC, StringRef Suffix) { + unsigned Pad = CC->getName().size(); + if (CC->getValueAsBit("Entry")) { + O << "bool llvm::"; + Pad += 12; + } else { + O << "static bool "; + Pad += 13; + } + O << CC->getName() << "(unsigned ValNo, MVT ValVT,\n" + << indent(Pad) << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" + << indent(Pad) << "ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)" + << Suffix; +} + void CallingConvEmitter::run(raw_ostream &O) { emitSourceFileHeader("Calling Convention Implementation Fragment", O); @@ -63,35 +79,20 @@ void CallingConvEmitter::run(raw_ostream &O) { // Emit prototypes for all of the non-custom CC's so that they can forward ref // each other. Records.getTimer().startTimer("Emit prototypes"); - O << "#ifndef GET_CC_REGISTER_LISTS\n\n"; + IfGuardEmitter IfGuard(O, "!defined(GET_CC_REGISTER_LISTS)"); for (const Record *CC : CCs) { - if (!CC->getValueAsBit("Custom")) { - unsigned Pad = CC->getName().size(); - if (CC->getValueAsBit("Entry")) { - O << "bool llvm::"; - Pad += 12; - } else { - O << "static bool "; - Pad += 13; - } - O << CC->getName() << "(unsigned ValNo, MVT ValVT,\n" - << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" - << std::string(Pad, ' ') - << "ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State);\n"; - } + if (!CC->getValueAsBit("Custom")) + emitCCHeader(O, CC, ";\n"); } // Emit each non-custom calling convention description in full. Records.getTimer().startTimer("Emit full descriptions"); for (const Record *CC : CCs) { - if (!CC->getValueAsBit("Custom")) { + if (!CC->getValueAsBit("Custom")) emitCallingConv(CC, O); - } } emitArgRegisterLists(O); - - O << "\n#endif // CC_REGISTER_LIST\n"; } void CallingConvEmitter::emitCallingConv(const Record *CC, raw_ostream &O) { @@ -105,18 +106,7 @@ void CallingConvEmitter::emitCallingConv(const Record *CC, raw_ostream &O) { AssignedRegsMap[CurrentAction] = {}; O << "\n\n"; - unsigned Pad = CurrentAction.size(); - if (CC->getValueAsBit("Entry")) { - O << "bool llvm::"; - Pad += 12; - } else { - O << "static bool "; - Pad += 13; - } - O << CurrentAction << "(unsigned ValNo, MVT ValVT,\n" - << std::string(Pad, ' ') << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n" - << std::string(Pad, ' ') << "ISD::ArgFlagsTy ArgFlags, Type *OrigTy, " - << "CCState &State) {\n"; + emitCCHeader(O, CC, " {\n"); // Emit all of the actions, in order. for (unsigned I = 0, E = CCActions->size(); I != E; ++I) { const Record *Action = CCActions->getElementAsRecord(I); @@ -281,9 +271,9 @@ void CallingConvEmitter::emitAction(const Record *Action, indent Indent, O << Indent << "return false;\n"; } else if (Action->isSubClassOf("CCPromoteToType")) { const Record *DestTy = Action->getValueAsDef("DestTy"); - MVT::SimpleValueType DestVT = getValueType(DestTy); + MVT DestVT = getValueType(DestTy); O << Indent << "LocVT = " << getEnumName(DestVT) << ";\n"; - if (MVT(DestVT).isFloatingPoint()) { + if (DestVT.isFloatingPoint()) { O << Indent << "LocInfo = CCValAssign::FPExt;\n"; } else { O << Indent << "if (ArgFlags.isSExt())\n" @@ -295,9 +285,9 @@ void CallingConvEmitter::emitAction(const Record *Action, indent Indent, } } else if (Action->isSubClassOf("CCPromoteToUpperBitsInType")) { const Record *DestTy = Action->getValueAsDef("DestTy"); - MVT::SimpleValueType DestVT = getValueType(DestTy); + MVT DestVT = getValueType(DestTy); O << Indent << "LocVT = " << getEnumName(DestVT) << ";\n"; - if (MVT(DestVT).isFloatingPoint()) { + if (DestVT.isFloatingPoint()) { PrintFatalError(Action->getLoc(), "CCPromoteToUpperBitsInType does not handle floating " "point"); diff --git a/llvm/utils/TableGen/CodeEmitterGen.cpp b/llvm/utils/TableGen/CodeEmitterGen.cpp index f2fd889..278fcd7 100644 --- a/llvm/utils/TableGen/CodeEmitterGen.cpp +++ b/llvm/utils/TableGen/CodeEmitterGen.cpp @@ -103,7 +103,7 @@ bool CodeEmitterGen::addCodeToMergeInOperand(const Record *R, const std::string &VarName, std::string &Case, std::string &BitOffsetCase) { - CodeGenInstruction &CGI = Target.getInstruction(R); + const CodeGenInstruction &CGI = Target.getInstruction(R); // Determine if VarName actually contributes to the Inst encoding. int Bit = BI->getNumBits() - 1; diff --git a/llvm/utils/TableGen/CodeGenMapTable.cpp b/llvm/utils/TableGen/CodeGenMapTable.cpp index e502578..35ec495 100644 --- a/llvm/utils/TableGen/CodeGenMapTable.cpp +++ b/llvm/utils/TableGen/CodeGenMapTable.cpp @@ -80,6 +80,7 @@ #include "TableGenBackends.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/TableGen/CodeGenHelpers.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" @@ -549,9 +550,8 @@ void llvm::EmitMapTable(const RecordKeeper &Records, raw_ostream &OS) { if (InstrMapVec.empty()) return; - OS << "#ifdef GET_INSTRMAP_INFO\n"; - OS << "#undef GET_INSTRMAP_INFO\n"; - OS << "namespace llvm::" << NameSpace << " {\n\n"; + IfDefEmitter IfDef(OS, "GET_INSTRMAP_INFO"); + NamespaceEmitter NS(OS, ("llvm::" + NameSpace).str()); // Emit coulumn field names and their values as enums. emitEnums(OS, Records); @@ -574,6 +574,4 @@ void llvm::EmitMapTable(const RecordKeeper &Records, raw_ostream &OS) { // Emit map tables and the functions to query them. IMap.emitTablesWithFunc(OS); } - OS << "} // end namespace llvm::" << NameSpace << '\n'; - OS << "#endif // GET_INSTRMAP_INFO\n\n"; } diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp index 34355d5..364817f 100644 --- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp @@ -1830,10 +1830,6 @@ bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo, return UpdateNodeType(ResNo, getValueTypeByHwMode(R, T.getHwModes()), TP); } - // PointerLikeRegClass has a type that is determined at runtime. - if (Operand->isSubClassOf("PointerLikeRegClass")) - return UpdateNodeType(ResNo, MVT::iPTR, TP); - // Both RegisterClass and RegisterOperand operands derive their types from a // register class def. const Record *RC = nullptr; @@ -1921,8 +1917,8 @@ SDNodeInfo::SDNodeInfo(const Record *R, const CodeGenHwModes &CGH) : Def(R) { /// getKnownType - If the type constraints on this node imply a fixed type /// (e.g. all stores return void, etc), then return it as an -/// MVT::SimpleValueType. Otherwise, return EEVT::Other. -MVT::SimpleValueType SDNodeInfo::getKnownType(unsigned ResNo) const { +/// MVT. Otherwise, return EEVT::Other. +MVT SDNodeInfo::getKnownType(unsigned ResNo) const { unsigned NumResults = getNumResults(); assert(NumResults <= 1 && "We only work with nodes with zero or one result so far!"); @@ -1990,7 +1986,8 @@ static unsigned GetNumNodeResults(const Record *Operator, } if (Operator->isSubClassOf("Instruction")) { - CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(Operator); + const CodeGenInstruction &InstInfo = + CDP.getTargetInfo().getInstruction(Operator); unsigned NumDefsToAdd = InstInfo.Operands.NumDefs; @@ -2412,12 +2409,6 @@ static TypeSetByHwMode getImplicitType(const Record *R, unsigned ResNo, const CodeGenHwModes &CGH = CDP.getTargetInfo().getHwModes(); return TypeSetByHwMode(getValueTypeByHwMode(T, CGH)); } - if (R->isSubClassOf("PointerLikeRegClass")) { - assert(ResNo == 0 && "Regclass can only have one result!"); - TypeSetByHwMode VTS(MVT::iPTR); - TP.getInfer().expandOverloads(VTS); - return VTS; - } if (R->getName() == "node" || R->getName() == "srcvalue" || R->getName() == "zero_reg" || R->getName() == "immAllOnesV" || @@ -2585,14 +2576,14 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { ValueTypeByHwMode VVT = TP.getInfer().getConcrete(Types[0], false); for (auto &P : VVT) { - MVT::SimpleValueType VT = P.second.SimpleTy; + MVT VT = P.second; // Can only check for types of a known size if (VT == MVT::iPTR) continue; // Check that the value doesn't use more bits than we have. It must // either be a sign- or zero-extended equivalent of the original. - unsigned Width = MVT(VT).getFixedSizeInBits(); + unsigned Width = VT.getFixedSizeInBits(); int64_t Val = II->getValue(); if (!isIntN(Width, Val) && !isUIntN(Width, Val)) { TP.error("Integer value '" + Twine(Val) + @@ -2629,8 +2620,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { for (unsigned i = 0, e = getNumChildren() - 1; i != e; ++i) { MadeChange |= getChild(i + 1).ApplyTypeConstraints(TP, NotRegisters); - MVT::SimpleValueType OpVT = - getValueType(Int->IS.ParamTys[i]->getValueAsDef("VT")); + MVT OpVT = getValueType(Int->IS.ParamTys[i]->getValueAsDef("VT")); assert(getChild(i + 1).getNumTypes() == 1 && "Unhandled case"); MadeChange |= getChild(i + 1).UpdateNodeType(0, OpVT, TP); } @@ -2657,7 +2647,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { if (getOperator()->isSubClassOf("Instruction")) { const DAGInstruction &Inst = CDP.getInstruction(getOperator()); - CodeGenInstruction &InstInfo = + const CodeGenInstruction &InstInfo = CDP.getTargetInfo().getInstruction(getOperator()); bool MadeChange = false; @@ -2676,8 +2666,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { // FIXME: Generalize to multiple possible types and multiple possible // ImplicitDefs. - MVT::SimpleValueType VT = - InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()); + MVT VT = InstInfo.HasOneImplicitDefWithKnownVT(CDP.getTargetInfo()); if (VT != MVT::Other) MadeChange |= UpdateNodeType(ResNo, VT, TP); @@ -2923,6 +2912,14 @@ TreePattern::TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput, Trees.push_back(ParseTreePattern(Pat, "")); } +TreePattern::TreePattern(const Record *TheRec, ArrayRef<const Init *> Args, + ArrayRef<const StringInit *> ArgNames, bool isInput, + CodeGenDAGPatterns &cdp) + : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false), + Infer(*this) { + Trees.push_back(ParseRootlessTreePattern(Args, ArgNames)); +} + TreePattern::TreePattern(const Record *TheRec, TreePatternNodePtr Pat, bool isInput, CodeGenDAGPatterns &cdp) : TheRecord(TheRec), CDP(cdp), isInputPattern(isInput), HasError(false), @@ -2951,6 +2948,19 @@ void TreePattern::ComputeNamedNodes(TreePatternNode &N) { ComputeNamedNodes(Child); } +TreePatternNodePtr +TreePattern::ParseRootlessTreePattern(ArrayRef<const Init *> Args, + ArrayRef<const StringInit *> ArgNames) { + std::vector<TreePatternNodePtr> Children; + + for (auto [Arg, ArgName] : llvm::zip_equal(Args, ArgNames)) { + StringRef NameStr = ArgName ? ArgName->getValue() : ""; + Children.push_back(ParseTreePattern(Arg, NameStr)); + } + + return makeIntrusiveRefCnt<TreePatternNode>(nullptr, std::move(Children), 1); +} + TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit, StringRef OpName) { RecordKeeper &RK = TheInit->getRecordKeeper(); @@ -3488,20 +3498,12 @@ void CodeGenDAGPatterns::ParseDefaultOperands() { ArrayRef<const Record *> DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps"); - // Find some SDNode. - assert(!SDNodes.empty() && "No SDNodes parsed?"); - const Init *SomeSDNode = SDNodes.begin()->first->getDefInit(); - for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) { const DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps"); - // Clone the DefaultInfo dag node, changing the operator from 'ops' to - // SomeSDnode so that we can parse this. - const DagInit *DI = DagInit::get(SomeSDNode, DefaultInfo->getArgs(), - DefaultInfo->getArgNames()); - // Create a TreePattern to parse this. - TreePattern P(DefaultOps[i], DI, false, *this); + TreePattern P(DefaultOps[i], DefaultInfo->getArgs(), + DefaultInfo->getArgNames(), false, *this); assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!"); // Copy the operands over into a DAGDefaultOperand. @@ -3649,8 +3651,7 @@ void CodeGenDAGPatterns::FindPatternInputsAndOutputs( if (Val->getDef()->isSubClassOf("RegisterClassLike") || Val->getDef()->isSubClassOf("ValueType") || - Val->getDef()->isSubClassOf("RegisterOperand") || - Val->getDef()->isSubClassOf("PointerLikeRegClass")) { + Val->getDef()->isSubClassOf("RegisterOperand")) { if (Dest->getName().empty()) I.error("set destination must have a name!"); if (!InstResults.insert_or_assign(Dest->getName(), Dest).second) @@ -3871,7 +3872,7 @@ static void getInstructionsInTree(TreePatternNode &Tree, /// Check the class of a pattern leaf node against the instruction operand it /// represents. -static bool checkOperandClass(CGIOperandList::OperandInfo &OI, +static bool checkOperandClass(const CGIOperandList::OperandInfo &OI, const Record *Leaf) { if (OI.Rec == Leaf) return true; @@ -3888,7 +3889,7 @@ static bool checkOperandClass(CGIOperandList::OperandInfo &OI, return false; } -void CodeGenDAGPatterns::parseInstructionPattern(CodeGenInstruction &CGI, +void CodeGenDAGPatterns::parseInstructionPattern(const CodeGenInstruction &CGI, const ListInit *Pat, DAGInstMap &DAGInsts) { @@ -3987,7 +3988,7 @@ void CodeGenDAGPatterns::parseInstructionPattern(CodeGenInstruction &CGI, std::vector<TreePatternNodePtr> ResultNodeOperands; std::vector<const Record *> Operands; for (unsigned i = NumResults, e = CGI.Operands.size(); i != e; ++i) { - CGIOperandList::OperandInfo &Op = CGI.Operands[i]; + const CGIOperandList::OperandInfo &Op = CGI.Operands[i]; StringRef OpName = Op.Name; if (OpName.empty()) { I.error("Operand #" + Twine(i) + " in operands list has no name!"); @@ -4093,7 +4094,7 @@ void CodeGenDAGPatterns::ParseInstructions() { std::vector<const Record *> Results; std::vector<const Record *> Operands; - CodeGenInstruction &InstInfo = Target.getInstruction(Instr); + const CodeGenInstruction &InstInfo = Target.getInstruction(Instr); if (InstInfo.Operands.size() != 0) { for (unsigned j = 0, e = InstInfo.Operands.NumDefs; j < e; ++j) @@ -4112,7 +4113,7 @@ void CodeGenDAGPatterns::ParseInstructions() { continue; // no pattern. } - CodeGenInstruction &CGI = Target.getInstruction(Instr); + const CodeGenInstruction &CGI = Target.getInstruction(Instr); parseInstructionPattern(CGI, LI, Instructions); } diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h index aa9a0a4..9a67933 100644 --- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h @@ -71,7 +71,7 @@ struct MachineValueTypeSet { return Count; } LLVM_ATTRIBUTE_ALWAYS_INLINE - void clear() { std::memset(Words.data(), 0, NumWords * sizeof(WordType)); } + void clear() { Words.fill(0); } LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const { for (WordType W : Words) @@ -86,7 +86,7 @@ struct MachineValueTypeSet { } std::pair<MachineValueTypeSet &, bool> insert(MVT T) { assert(T.SimpleTy < Capacity && "Capacity needs to be enlarged"); - bool V = count(T.SimpleTy); + bool V = count(T); Words[T.SimpleTy / WordWidth] |= WordType(1) << (T.SimpleTy % WordWidth); return {*this, V}; } @@ -138,25 +138,19 @@ struct MachineValueTypeSet { private: unsigned find_from_pos(unsigned P) const { unsigned SkipWords = P / WordWidth; - unsigned SkipBits = P % WordWidth; - unsigned Count = SkipWords * WordWidth; - - // If P is in the middle of a word, process it manually here, because - // the trailing bits need to be masked off to use findFirstSet. - if (SkipBits != 0) { - WordType W = Set->Words[SkipWords]; - W &= maskLeadingOnes<WordType>(WordWidth - SkipBits); - if (W != 0) - return Count + llvm::countr_zero(W); - Count += WordWidth; - SkipWords++; - } for (unsigned i = SkipWords; i != NumWords; ++i) { WordType W = Set->Words[i]; + + // If P is in the middle of a word, process it manually here, because + // the trailing bits need to be masked off to use countr_zero. + if (i == SkipWords) { + unsigned SkipBits = P % WordWidth; + W &= maskTrailingZeros<WordType>(SkipBits); + } + if (W != 0) - return Count + llvm::countr_zero(W); - Count += WordWidth; + return i * WordWidth + llvm::countr_zero(W); } return Capacity; } @@ -191,8 +185,7 @@ struct TypeSetByHwMode : public InfoByHwMode<MachineValueTypeSet> { TypeSetByHwMode() = default; TypeSetByHwMode(const TypeSetByHwMode &VTS) = default; TypeSetByHwMode &operator=(const TypeSetByHwMode &) = default; - TypeSetByHwMode(MVT::SimpleValueType VT) - : TypeSetByHwMode(ValueTypeByHwMode(VT)) {} + TypeSetByHwMode(MVT VT) : TypeSetByHwMode(ValueTypeByHwMode(VT)) {} TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList); SetType &getOrCreate(unsigned Mode) { return Map[Mode]; } @@ -259,7 +252,7 @@ struct TypeInfer { /// otherwise. bool MergeInTypeInfo(TypeSetByHwMode &Out, const TypeSetByHwMode &In) const; - bool MergeInTypeInfo(TypeSetByHwMode &Out, MVT::SimpleValueType InVT) const { + bool MergeInTypeInfo(TypeSetByHwMode &Out, MVT InVT) const { return MergeInTypeInfo(Out, TypeSetByHwMode(InVT)); } bool MergeInTypeInfo(TypeSetByHwMode &Out, @@ -451,8 +444,8 @@ public: /// getKnownType - If the type constraints on this node imply a fixed type /// (e.g. all stores return void, etc), then return it as an - /// MVT::SimpleValueType. Otherwise, return MVT::Other. - MVT::SimpleValueType getKnownType(unsigned ResNo) const; + /// MVT. Otherwise, return MVT::Other. + MVT getKnownType(unsigned ResNo) const; unsigned getProperties() const { return Properties; } @@ -698,8 +691,8 @@ public: } TypeSetByHwMode &getExtType(unsigned ResNo) { return Types[ResNo]; } void setType(unsigned ResNo, const TypeSetByHwMode &T) { Types[ResNo] = T; } - MVT::SimpleValueType getSimpleType(unsigned ResNo) const { - return Types[ResNo].getMachineValueType().SimpleTy; + MVT getSimpleType(unsigned ResNo) const { + return Types[ResNo].getMachineValueType(); } bool hasConcreteType(unsigned ResNo) const { @@ -850,8 +843,7 @@ public: // Higher level manipulation routines. /// bool UpdateNodeType(unsigned ResNo, const TypeSetByHwMode &InTy, TreePattern &TP); - bool UpdateNodeType(unsigned ResNo, MVT::SimpleValueType InTy, - TreePattern &TP); + bool UpdateNodeType(unsigned ResNo, MVT InTy, TreePattern &TP); bool UpdateNodeType(unsigned ResNo, const ValueTypeByHwMode &InTy, TreePattern &TP); @@ -925,6 +917,9 @@ public: CodeGenDAGPatterns &ise); TreePattern(const Record *TheRec, const DagInit *Pat, bool isInput, CodeGenDAGPatterns &ise); + TreePattern(const Record *TheRec, ArrayRef<const Init *> Args, + ArrayRef<const StringInit *> ArgNames, bool isInput, + CodeGenDAGPatterns &ise); TreePattern(const Record *TheRec, TreePatternNodePtr Pat, bool isInput, CodeGenDAGPatterns &ise); @@ -989,6 +984,9 @@ public: private: TreePatternNodePtr ParseTreePattern(const Init *DI, StringRef OpName); + TreePatternNodePtr + ParseRootlessTreePattern(ArrayRef<const Init *> Args, + ArrayRef<const StringInit *> ArgNames); void ComputeNamedNodes(); void ComputeNamedNodes(TreePatternNode &N); }; @@ -1001,8 +999,7 @@ inline bool TreePatternNode::UpdateNodeType(unsigned ResNo, return TP.getInfer().MergeInTypeInfo(Types[ResNo], VTS); } -inline bool TreePatternNode::UpdateNodeType(unsigned ResNo, - MVT::SimpleValueType InTy, +inline bool TreePatternNode::UpdateNodeType(unsigned ResNo, MVT InTy, TreePattern &TP) { TypeSetByHwMode VTS(InTy); TP.getInfer().expandOverloads(VTS); @@ -1224,8 +1221,8 @@ public: /// Parse the Pattern for an instruction, and insert the result in DAGInsts. using DAGInstMap = std::map<const Record *, DAGInstruction, LessRecordByID>; - void parseInstructionPattern(CodeGenInstruction &CGI, const ListInit *Pattern, - DAGInstMap &DAGInsts); + void parseInstructionPattern(const CodeGenInstruction &CGI, + const ListInit *Pattern, DAGInstMap &DAGInsts); const DAGInstruction &getInstruction(const Record *R) const { auto F = Instructions.find(R); diff --git a/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp b/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp index 6c1a3e9..d3050c0 100644 --- a/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp +++ b/llvm/utils/TableGen/Common/CodeGenInstAlias.cpp @@ -40,24 +40,21 @@ unsigned CodeGenInstAlias::ResultOperand::getMINumOperands() const { using ResultOperand = CodeGenInstAlias::ResultOperand; -static Expected<ResultOperand> matchSimpleOperand(const Init *Arg, - const StringInit *ArgName, - const Record *Op, - const CodeGenTarget &T) { - if (Op->isSubClassOf("RegisterClass") || - Op->isSubClassOf("RegisterOperand")) { - const Record *OpRC = - Op->isSubClassOf("RegisterClass") ? Op : Op->getValueAsDef("RegClass"); - +static Expected<ResultOperand> +matchSimpleOperand(const Init *Arg, const StringInit *ArgName, const Record *Op, + const CodeGenTarget &T, ArrayRef<SMLoc> Loc) { + if (const Record *OpRC = T.getAsRegClassLike(Op)) { if (const auto *ArgDef = dyn_cast<DefInit>(Arg)) { const Record *ArgRec = ArgDef->getDef(); // Match 'RegClass:$name' or 'RegOp:$name'. if (const Record *ArgRC = T.getInitValueAsRegClassLike(Arg)) { if (ArgRC->isSubClassOf("RegisterClass")) { - if (!T.getRegisterClass(OpRC).hasSubClass(&T.getRegisterClass(ArgRC))) + if (!OpRC->isSubClassOf("RegisterClass") || + !T.getRegisterClass(OpRC, Loc).hasSubClass( + &T.getRegisterClass(ArgRC, Loc))) return createStringError( - "argument register class" + ArgRC->getName() + + "argument register class " + ArgRC->getName() + " is not a subclass of operand register class " + OpRC->getName()); if (!ArgName) @@ -73,7 +70,8 @@ static Expected<ResultOperand> matchSimpleOperand(const Init *Arg, // Match 'Reg'. if (ArgRec->isSubClassOf("Register")) { - if (!T.getRegisterClass(OpRC).contains(T.getRegBank().getReg(ArgRec))) + if (!T.getRegisterClass(OpRC, Loc).contains( + T.getRegBank().getReg(ArgRec))) return createStringError( "register argument " + ArgRec->getName() + " is not a member of operand register class " + OpRC->getName()); @@ -111,11 +109,9 @@ static Expected<ResultOperand> matchSimpleOperand(const Init *Arg, return ResultOperand::createRecord(ArgName->getAsUnquotedString(), ArgDef->getDef()); } - - return createStringError("argument must be a subclass of Operand"); } - - llvm_unreachable("Unknown operand kind"); + return createStringError("argument must be a subclass of 'Operand' but got " + + Op->getName() + " instead"); } static Expected<ResultOperand> matchComplexOperand(const Init *Arg, @@ -204,7 +200,8 @@ CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T) const Record *SubOp = cast<DefInit>(OpInfo.MIOperandInfo->getArg(SubOpIdx))->getDef(); Expected<ResultOperand> ResOpOrErr = matchSimpleOperand( - ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T); + ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T, + R->getLoc()); if (!ResOpOrErr) PrintFatalError(R, "in argument #" + Twine(ArgIdx) + "." + Twine(SubOpIdx) + ": " + @@ -225,8 +222,9 @@ CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T) } else { // Simple operand (RegisterClass, RegisterOperand or Operand with empty // MIOperandInfo). - Expected<ResultOperand> ResOpOrErr = matchSimpleOperand( - Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op, T); + Expected<ResultOperand> ResOpOrErr = + matchSimpleOperand(Result->getArg(ArgIdx), Result->getArgName(ArgIdx), + Op, T, R->getLoc()); if (!ResOpOrErr) PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " + toString(ResOpOrErr.takeError())); diff --git a/llvm/utils/TableGen/Common/CodeGenInstAlias.h b/llvm/utils/TableGen/Common/CodeGenInstAlias.h index e9f6031..1cb68d6 100644 --- a/llvm/utils/TableGen/Common/CodeGenInstAlias.h +++ b/llvm/utils/TableGen/Common/CodeGenInstAlias.h @@ -41,7 +41,7 @@ public: /// ResultInst - The instruction generated by the alias (decoded from /// Result). - CodeGenInstruction *ResultInst; + const CodeGenInstruction *ResultInst; class ResultOperand { std::string Name; diff --git a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp index 93d4f4b..62a7b54 100644 --- a/llvm/utils/TableGen/Common/CodeGenInstruction.cpp +++ b/llvm/utils/TableGen/Common/CodeGenInstruction.cpp @@ -499,7 +499,7 @@ CodeGenInstruction::CodeGenInstruction(const Record *R) /// HasOneImplicitDefWithKnownVT - If the instruction has at least one /// implicit def and it has a known VT, return the VT, otherwise return /// MVT::Other. -MVT::SimpleValueType CodeGenInstruction::HasOneImplicitDefWithKnownVT( +MVT CodeGenInstruction::HasOneImplicitDefWithKnownVT( const CodeGenTarget &TargetInfo) const { if (ImplicitDefs.empty()) return MVT::Other; @@ -510,7 +510,7 @@ MVT::SimpleValueType CodeGenInstruction::HasOneImplicitDefWithKnownVT( const std::vector<ValueTypeByHwMode> &RegVTs = TargetInfo.getRegisterVTs(FirstImplicitDef); if (RegVTs.size() == 1 && RegVTs[0].isSimple()) - return RegVTs[0].getSimple().SimpleTy; + return RegVTs[0].getSimple(); return MVT::Other; } diff --git a/llvm/utils/TableGen/Common/CodeGenInstruction.h b/llvm/utils/TableGen/Common/CodeGenInstruction.h index 7295837..a50b190 100644 --- a/llvm/utils/TableGen/Common/CodeGenInstruction.h +++ b/llvm/utils/TableGen/Common/CodeGenInstruction.h @@ -289,8 +289,7 @@ public: /// HasOneImplicitDefWithKnownVT - If the instruction has at least one /// implicit def and it has a known VT, return the VT, otherwise return /// MVT::Other. - MVT::SimpleValueType - HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; + MVT HasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const; /// FlattenAsmStringVariants - Flatten the specified AsmString to only /// include text from the specified variant, returning the new string. diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp index 2f0ff3f..65a2594 100644 --- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp @@ -734,8 +734,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, if (const Record *RV = R->getValueAsOptionalDef("RegInfos")) RSI = RegSizeInfoByHwMode(RV, RegBank.getHwModes()); unsigned Size = R->getValueAsInt("Size"); - assert((RSI.hasDefault() || Size != 0 || VTs[0].isSimple()) && - "Impossible to determine register size"); + if (!RSI.hasDefault() && Size == 0 && !VTs[0].isSimple()) + PrintFatalError(R->getLoc(), "Impossible to determine register size"); if (!RSI.hasDefault()) { RegSizeInfo RI; RI.RegSize = RI.SpillSize = @@ -1316,11 +1316,19 @@ CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC, return {&RegClasses.back(), true}; } -CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def) const { +CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def, + ArrayRef<SMLoc> Loc) const { + assert(Def->isSubClassOf("RegisterClassLike")); if (CodeGenRegisterClass *RC = Def2RC.lookup(Def)) return RC; - PrintFatalError(Def->getLoc(), "Not a known RegisterClass!"); + ArrayRef<SMLoc> DiagLoc = Loc.empty() ? Def->getLoc() : Loc; + // TODO: Ideally we should update the API to allow resolving HwMode. + if (Def->isSubClassOf("RegClassByHwMode")) + PrintError(DiagLoc, "cannot resolve HwMode for " + Def->getName()); + else + PrintError(DiagLoc, Def->getName() + " is not a known RegisterClass!"); + PrintFatalNote(Def->getLoc(), Def->getName() + " defined here"); } CodeGenSubRegIndex * diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h index c02d04b..a3ad0b7 100644 --- a/llvm/utils/TableGen/Common/CodeGenRegisters.h +++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h @@ -815,7 +815,8 @@ public: } // Find a register class from its def. - CodeGenRegisterClass *getRegClass(const Record *) const; + CodeGenRegisterClass *getRegClass(const Record *, + ArrayRef<SMLoc> Loc = {}) const; /// getRegisterClassForRegister - Find the register class that contains the /// specified physical register. If the register is not in a register diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.cpp b/llvm/utils/TableGen/Common/CodeGenTarget.cpp index 1e93788..cca318a 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/Common/CodeGenTarget.cpp @@ -18,12 +18,12 @@ #include "CodeGenRegisters.h" #include "CodeGenSchedule.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" -#include <iterator> #include <tuple> using namespace llvm; @@ -40,18 +40,24 @@ static cl::opt<unsigned> cl::desc("Make -gen-asm-writer emit assembly writer #N"), cl::cat(AsmWriterCat)); -/// getValueType - Return the MVT::SimpleValueType that the specified TableGen +/// Returns the MVT that the specified TableGen /// record corresponds to. -MVT::SimpleValueType llvm::getValueType(const Record *Rec) { - return (MVT::SimpleValueType)Rec->getValueAsInt("Value"); +MVT llvm::getValueType(const Record *Rec) { + return StringSwitch<MVT>(Rec->getValueAsString("LLVMName")) +#define GET_VT_ATTR(Ty, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \ + .Case(#Ty, MVT::Ty) +#include "llvm/CodeGen/GenVT.inc" +#undef GET_VT_ATTR + .Case("INVALID_SIMPLE_VALUE_TYPE", MVT::INVALID_SIMPLE_VALUE_TYPE); } -StringRef llvm::getEnumName(MVT::SimpleValueType T) { +StringRef llvm::getEnumName(MVT T) { // clang-format off - switch (T) { -#define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \ + switch (T.SimpleTy) { +#define GET_VT_ATTR(Ty, Sz, Any, Int, FP, Vec, Sc, Tup, NF, NElem, EltTy) \ case MVT::Ty: return "MVT::" # Ty; #include "llvm/CodeGen/GenVT.inc" +#undef GET_VT_ATTR default: llvm_unreachable("ILLEGAL VALUE TYPE!"); } // clang-format on @@ -167,8 +173,8 @@ const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const { } const CodeGenRegisterClass & -CodeGenTarget::getRegisterClass(const Record *R) const { - return *getRegBank().getRegClass(R); +CodeGenTarget::getRegisterClass(const Record *R, ArrayRef<SMLoc> Loc) const { + return *getRegBank().getRegClass(R, Loc); } std::vector<ValueTypeByHwMode> @@ -221,12 +227,14 @@ const Record *CodeGenTarget::getInitValueAsRegClassLike(const Init *V) const { const DefInit *VDefInit = dyn_cast<DefInit>(V); if (!VDefInit) return nullptr; + return getAsRegClassLike(VDefInit->getDef()); +} - const Record *RegClass = VDefInit->getDef(); - if (RegClass->isSubClassOf("RegisterOperand")) - return RegClass->getValueAsDef("RegClass"); +const Record *CodeGenTarget::getAsRegClassLike(const Record *Rec) const { + if (Rec->isSubClassOf("RegisterOperand")) + return Rec->getValueAsDef("RegClass"); - return RegClass->isSubClassOf("RegisterClassLike") ? RegClass : nullptr; + return Rec->isSubClassOf("RegisterClassLike") ? Rec : nullptr; } CodeGenSchedModels &CodeGenTarget::getSchedModels() const { @@ -284,15 +292,25 @@ void CodeGenTarget::ComputeInstrsByEnum() const { assert(EndOfPredefines == getNumFixedInstructions() && "Missing generic opcode"); + [[maybe_unused]] unsigned SkippedInsts = 0; + for (const auto &[_, CGIUp] : InstMap) { const CodeGenInstruction *CGI = CGIUp.get(); if (CGI->Namespace != "TargetOpcode") { + + if (CGI->TheDef->isSubClassOf( + "TargetSpecializedStandardPseudoInstruction")) { + ++SkippedInsts; + continue; + } + InstrsByEnum.push_back(CGI); NumPseudoInstructions += CGI->TheDef->getValueAsBit("isPseudo"); } } - assert(InstrsByEnum.size() == InstMap.size() && "Missing predefined instr"); + assert(InstrsByEnum.size() + SkippedInsts == InstMap.size() && + "Missing predefined instr"); // All of the instructions are now in random order based on the map iteration. llvm::sort( diff --git a/llvm/utils/TableGen/Common/CodeGenTarget.h b/llvm/utils/TableGen/Common/CodeGenTarget.h index c1ed70d..dc1740b 100644 --- a/llvm/utils/TableGen/Common/CodeGenTarget.h +++ b/llvm/utils/TableGen/Common/CodeGenTarget.h @@ -41,11 +41,11 @@ class CodeGenRegisterClass; class CodeGenSchedModels; class CodeGenSubRegIndex; -/// getValueType - Return the MVT::SimpleValueType that the specified TableGen +/// Returns the MVT that the specified TableGen /// record corresponds to. -MVT::SimpleValueType getValueType(const Record *Rec); +MVT getValueType(const Record *Rec); -StringRef getEnumName(MVT::SimpleValueType T); +StringRef getEnumName(MVT T); /// getQualifiedName - Return the name of the specified record, with a /// namespace qualifier if the record contains one. @@ -131,7 +131,8 @@ public: return RegAltNameIndices; } - const CodeGenRegisterClass &getRegisterClass(const Record *R) const; + const CodeGenRegisterClass &getRegisterClass(const Record *R, + ArrayRef<SMLoc> Loc = {}) const; /// Convenience wrapper to avoid hardcoding the name of RegClassByHwMode /// everywhere. This is here instead of CodeGenRegBank to avoid the fatal @@ -165,6 +166,7 @@ public: /// return the Record. This is used as a convenience function to handle direct /// RegisterClass references, or those wrapped in a RegisterOperand. const Record *getInitValueAsRegClassLike(const Init *V) const; + const Record *getAsRegClassLike(const Record *V) const; CodeGenSchedModels &getSchedModels() const; diff --git a/llvm/utils/TableGen/Common/DAGISelMatcher.cpp b/llvm/utils/TableGen/Common/DAGISelMatcher.cpp index 4fdb386..6f03989 100644 --- a/llvm/utils/TableGen/Common/DAGISelMatcher.cpp +++ b/llvm/utils/TableGen/Common/DAGISelMatcher.cpp @@ -286,7 +286,7 @@ void EmitNodeMatcherCommon::printImpl(raw_ostream &OS, indent Indent) const { OS << (isa<MorphNodeToMatcher>(this) ? "MorphNodeTo: " : "EmitNode: ") << CGI.Namespace << "::" << CGI.getName() << ": <todo flags> "; - for (MVT::SimpleValueType VT : VTs) + for (MVT VT : VTs) OS << ' ' << getEnumName(VT); OS << '('; for (unsigned Operand : Operands) @@ -321,8 +321,7 @@ void MorphNodeToMatcher::anchor() {} // isContradictoryImpl Implementations. -static bool TypesAreContradictory(MVT::SimpleValueType T1, - MVT::SimpleValueType T2) { +static bool TypesAreContradictory(MVT T1, MVT T2) { // If the two types are the same, then they are the same, so they don't // contradict. if (T1 == T2) @@ -339,16 +338,16 @@ static bool TypesAreContradictory(MVT::SimpleValueType T1, // If either type is about iPtr, then they don't conflict unless the other // one is not a scalar integer type. if (T1 == MVT::iPTR) - return !MVT(T2).isInteger() || MVT(T2).isVector(); + return !T2.isInteger() || T2.isVector(); if (T2 == MVT::iPTR) - return !MVT(T1).isInteger() || MVT(T1).isVector(); + return !T1.isInteger() || T1.isVector(); if (T1 == MVT::cPTR) - return !MVT(T2).isCheriCapability() || MVT(T2).isVector(); + return !T2.isCheriCapability() || T2.isVector(); if (T2 == MVT::cPTR) - return !MVT(T1).isCheriCapability() || MVT(T1).isVector(); + return !T1.isCheriCapability() || T1.isVector(); // Otherwise, they are two different non-iPTR/cPTR types, they conflict. return true; @@ -370,7 +369,7 @@ bool CheckOpcodeMatcher::isContradictoryImpl(const Matcher *M) const { if (CT->getResNo() >= getOpcode().getNumResults()) return true; - MVT::SimpleValueType NodeType = getOpcode().getKnownType(CT->getResNo()); + MVT NodeType = getOpcode().getKnownType(CT->getResNo()); if (NodeType != MVT::Other) return TypesAreContradictory(NodeType, CT->getType()); } diff --git a/llvm/utils/TableGen/Common/DAGISelMatcher.h b/llvm/utils/TableGen/Common/DAGISelMatcher.h index a19f444..e947dac 100644 --- a/llvm/utils/TableGen/Common/DAGISelMatcher.h +++ b/llvm/utils/TableGen/Common/DAGISelMatcher.h @@ -517,14 +517,14 @@ private: /// CheckTypeMatcher - This checks to see if the current node has the /// specified type at the specified result, if not it fails to match. class CheckTypeMatcher : public Matcher { - MVT::SimpleValueType Type; + MVT Type; unsigned ResNo; public: - CheckTypeMatcher(MVT::SimpleValueType type, unsigned resno) + CheckTypeMatcher(MVT type, unsigned resno) : Matcher(CheckType), Type(type), ResNo(resno) {} - MVT::SimpleValueType getType() const { return Type; } + MVT getType() const { return Type; } unsigned getResNo() const { return ResNo; } static bool classof(const Matcher *N) { return N->getKind() == CheckType; } @@ -542,11 +542,10 @@ private: /// then the match fails. This is semantically equivalent to a Scope node where /// every child does a CheckType, but is much faster. class SwitchTypeMatcher : public Matcher { - SmallVector<std::pair<MVT::SimpleValueType, Matcher *>, 8> Cases; + SmallVector<std::pair<MVT, Matcher *>, 8> Cases; public: - SwitchTypeMatcher( - SmallVectorImpl<std::pair<MVT::SimpleValueType, Matcher *>> &&cases) + SwitchTypeMatcher(SmallVectorImpl<std::pair<MVT, Matcher *>> &&cases) : Matcher(SwitchType), Cases(std::move(cases)) {} ~SwitchTypeMatcher() override; @@ -554,7 +553,7 @@ public: unsigned getNumCases() const { return Cases.size(); } - MVT::SimpleValueType getCaseType(unsigned i) const { return Cases[i].first; } + MVT getCaseType(unsigned i) const { return Cases[i].first; } Matcher *getCaseMatcher(unsigned i) { return Cases[i].second; } const Matcher *getCaseMatcher(unsigned i) const { return Cases[i].second; } @@ -567,14 +566,14 @@ private: /// specified type, if not it fails to match. class CheckChildTypeMatcher : public Matcher { unsigned ChildNo; - MVT::SimpleValueType Type; + MVT Type; public: - CheckChildTypeMatcher(unsigned childno, MVT::SimpleValueType type) + CheckChildTypeMatcher(unsigned childno, MVT type) : Matcher(CheckChildType), ChildNo(childno), Type(type) {} unsigned getChildNo() const { return ChildNo; } - MVT::SimpleValueType getType() const { return Type; } + MVT getType() const { return Type; } static bool classof(const Matcher *N) { return N->getKind() == CheckChildType; @@ -684,13 +683,12 @@ private: /// CheckValueTypeMatcher - This checks to see if the current node is a /// VTSDNode with the specified type, if not it fails to match. class CheckValueTypeMatcher : public Matcher { - MVT::SimpleValueType VT; + MVT VT; public: - CheckValueTypeMatcher(MVT::SimpleValueType SimpleVT) - : Matcher(CheckValueType), VT(SimpleVT) {} + CheckValueTypeMatcher(MVT SimpleVT) : Matcher(CheckValueType), VT(SimpleVT) {} - MVT::SimpleValueType getVT() const { return VT; } + MVT getVT() const { return VT; } static bool classof(const Matcher *N) { return N->getKind() == CheckValueType; @@ -832,18 +830,18 @@ private: /// EmitIntegerMatcher - This creates a new TargetConstant. class EmitIntegerMatcher : public Matcher { int64_t Val; - MVT::SimpleValueType VT; + MVT VT; unsigned ResultNo; public: - EmitIntegerMatcher(int64_t val, MVT::SimpleValueType vt, unsigned resultNo) + EmitIntegerMatcher(int64_t val, MVT vt, unsigned resultNo) : Matcher(EmitInteger), Val(SignExtend64(val, MVT(vt).getFixedSizeInBits())), VT(vt), ResultNo(resultNo) {} int64_t getValue() const { return Val; } - MVT::SimpleValueType getVT() const { return VT; } + MVT getVT() const { return VT; } unsigned getResultNo() const { return ResultNo; } static bool classof(const Matcher *N) { return N->getKind() == EmitInteger; } @@ -860,17 +858,16 @@ private: /// by a string. class EmitStringIntegerMatcher : public Matcher { std::string Val; - MVT::SimpleValueType VT; + MVT VT; unsigned ResultNo; public: - EmitStringIntegerMatcher(const std::string &val, MVT::SimpleValueType vt, - unsigned resultNo) + EmitStringIntegerMatcher(const std::string &val, MVT vt, unsigned resultNo) : Matcher(EmitStringInteger), Val(val), VT(vt), ResultNo(resultNo) {} const std::string &getValue() const { return Val; } - MVT::SimpleValueType getVT() const { return VT; } + MVT getVT() const { return VT; } unsigned getResultNo() const { return ResultNo; } static bool classof(const Matcher *N) { @@ -890,17 +887,16 @@ class EmitRegisterMatcher : public Matcher { /// Reg - The def for the register that we're emitting. If this is null, then /// this is a reference to zero_reg. const CodeGenRegister *Reg; - MVT::SimpleValueType VT; + MVT VT; unsigned ResultNo; public: - EmitRegisterMatcher(const CodeGenRegister *reg, MVT::SimpleValueType vt, - unsigned resultNo) + EmitRegisterMatcher(const CodeGenRegister *reg, MVT vt, unsigned resultNo) : Matcher(EmitRegister), Reg(reg), VT(vt), ResultNo(resultNo) {} const CodeGenRegister *getReg() const { return Reg; } - MVT::SimpleValueType getVT() const { return VT; } + MVT getVT() const { return VT; } unsigned getResultNo() const { return ResultNo; } static bool classof(const Matcher *N) { return N->getKind() == EmitRegister; } @@ -1028,7 +1024,7 @@ private: /// MorphNodeTo. class EmitNodeMatcherCommon : public Matcher { const CodeGenInstruction &CGI; - const SmallVector<MVT::SimpleValueType, 3> VTs; + const SmallVector<MVT, 3> VTs; const SmallVector<unsigned, 6> Operands; bool HasChain, HasInGlue, HasOutGlue, HasMemRefs; @@ -1038,8 +1034,7 @@ class EmitNodeMatcherCommon : public Matcher { int NumFixedArityOperands; public: - EmitNodeMatcherCommon(const CodeGenInstruction &cgi, - ArrayRef<MVT::SimpleValueType> vts, + EmitNodeMatcherCommon(const CodeGenInstruction &cgi, ArrayRef<MVT> vts, ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue, bool hasOutGlue, bool hasmemrefs, int numfixedarityoperands, bool isMorphNodeTo) @@ -1051,7 +1046,7 @@ public: const CodeGenInstruction &getInstruction() const { return CGI; } unsigned getNumVTs() const { return VTs.size(); } - MVT::SimpleValueType getVT(unsigned i) const { + MVT getVT(unsigned i) const { assert(i < VTs.size()); return VTs[i]; } @@ -1062,7 +1057,7 @@ public: return Operands[i]; } - const SmallVectorImpl<MVT::SimpleValueType> &getVTList() const { return VTs; } + const SmallVectorImpl<MVT> &getVTList() const { return VTs; } const SmallVectorImpl<unsigned> &getOperandList() const { return Operands; } bool hasChain() const { return HasChain; } @@ -1086,8 +1081,7 @@ class EmitNodeMatcher : public EmitNodeMatcherCommon { unsigned FirstResultSlot; public: - EmitNodeMatcher(const CodeGenInstruction &cgi, - ArrayRef<MVT::SimpleValueType> vts, + EmitNodeMatcher(const CodeGenInstruction &cgi, ArrayRef<MVT> vts, ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue, bool hasOutGlue, bool hasmemrefs, int numfixedarityoperands, unsigned firstresultslot) @@ -1106,8 +1100,7 @@ class MorphNodeToMatcher : public EmitNodeMatcherCommon { const PatternToMatch &Pattern; public: - MorphNodeToMatcher(const CodeGenInstruction &cgi, - ArrayRef<MVT::SimpleValueType> vts, + MorphNodeToMatcher(const CodeGenInstruction &cgi, ArrayRef<MVT> vts, ArrayRef<unsigned> operands, bool hasChain, bool hasInGlue, bool hasOutGlue, bool hasmemrefs, int numfixedarityoperands, const PatternToMatch &pattern) diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp index 7af757c..8540fae 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp @@ -440,9 +440,7 @@ bool LLTCodeGen::operator<(const LLTCodeGen &Other) const { //===- LLTCodeGen Helpers -------------------------------------------------===// -std::optional<LLTCodeGen> llvm::gi::MVTToLLT(MVT::SimpleValueType SVT) { - MVT VT(SVT); - +std::optional<LLTCodeGen> llvm::gi::MVTToLLT(MVT VT) { if (VT.isVector() && !VT.getVectorElementCount().isScalar()) return LLTCodeGen( LLT::vector(VT.getVectorElementCount(), VT.getScalarSizeInBits())); diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h index d71fdb4..6a80178 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h @@ -267,7 +267,7 @@ extern std::set<LLTCodeGen> KnownTypes; /// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...). -std::optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT); +std::optional<LLTCodeGen> MVTToLLT(MVT VT); using TempTypeIdx = int64_t; class LLTCodeGenOrTempType { diff --git a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp index ad5089d..8e4a850 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp +++ b/llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp @@ -113,7 +113,8 @@ PatternParser::parseInstructionPattern(const Init &Arg, StringRef Name) { std::unique_ptr<InstructionPattern> Pat; if (const DagInit *IP = getDagWithOperatorOfSubClass(Arg, "Instruction")) { - auto &Instr = CGT.getInstruction(IP->getOperatorAsDef(DiagLoc)); + const CodeGenInstruction &Instr = + CGT.getInstruction(IP->getOperatorAsDef(DiagLoc)); Pat = std::make_unique<CodeGenInstructionPattern>(Instr, insertStrRef(Name)); } else if (const DagInit *IP = diff --git a/llvm/utils/TableGen/Common/InfoByHwMode.h b/llvm/utils/TableGen/Common/InfoByHwMode.h index ef688a6..bd24fb8 100644 --- a/llvm/utils/TableGen/Common/InfoByHwMode.h +++ b/llvm/utils/TableGen/Common/InfoByHwMode.h @@ -24,7 +24,6 @@ #include <map> #include <string> #include <tuple> -#include <utility> namespace llvm { @@ -104,6 +103,8 @@ template <typename InfoT> struct InfoByHwMode { LLVM_ATTRIBUTE_ALWAYS_INLINE const_iterator end() const { return Map.end(); } LLVM_ATTRIBUTE_ALWAYS_INLINE + size_t size() const { return Map.size(); } + LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const { return Map.empty(); } LLVM_ATTRIBUTE_ALWAYS_INLINE diff --git a/llvm/utils/TableGen/Common/InstructionEncoding.cpp b/llvm/utils/TableGen/Common/InstructionEncoding.cpp index 30bbac4..e9c2d93 100644 --- a/llvm/utils/TableGen/Common/InstructionEncoding.cpp +++ b/llvm/utils/TableGen/Common/InstructionEncoding.cpp @@ -35,9 +35,6 @@ InstructionEncoding::findOperandDecoderMethod(const Record *Record) { Decoder = "Decode" + Record->getName().str() + "RegisterClass"; } else if (Record->isSubClassOf("RegClassByHwMode")) { Decoder = "Decode" + Record->getName().str() + "RegClassByHwMode"; - } else if (Record->isSubClassOf("PointerLikeRegClass")) { - Decoder = "DecodePointerLikeRegClass" + - utostr(Record->getValueAsInt("RegClassKind")); } return {Decoder, true}; diff --git a/llvm/utils/TableGen/CompressInstEmitter.cpp b/llvm/utils/TableGen/CompressInstEmitter.cpp index d8c5ca7..94fe382 100644 --- a/llvm/utils/TableGen/CompressInstEmitter.cpp +++ b/llvm/utils/TableGen/CompressInstEmitter.cpp @@ -142,7 +142,8 @@ class CompressInstEmitter { void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType); bool validateTypes(const Record *DagOpType, const Record *InstOpType, bool IsSourceInst); - bool validateRegister(const Record *Reg, const Record *RegClass); + bool validateRegister(const Record *Reg, const Record *RegClass, + ArrayRef<SMLoc> Loc); void checkDagOperandMapping(const Record *Rec, const StringMap<ArgData> &DestOperands, const DagInit *SourceDag, const DagInit *DestDag); @@ -162,11 +163,12 @@ public: } // End anonymous namespace. bool CompressInstEmitter::validateRegister(const Record *Reg, - const Record *RegClass) { + const Record *RegClass, + ArrayRef<SMLoc> Loc) { assert(Reg->isSubClassOf("Register") && "Reg record should be a Register"); - assert(RegClass->isSubClassOf("RegisterClass") && - "RegClass record should be a RegisterClass"); - const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass); + assert(RegClass->isSubClassOf("RegisterClassLike") && + "RegClass record should be RegisterClassLike"); + const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass, Loc); const CodeGenRegister *R = Target.getRegBank().getReg(Reg); assert(R != nullptr && "Register not defined!!"); return RC.contains(R); @@ -255,7 +257,7 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec, if (const auto *DI = dyn_cast<DefInit>(Dag->getArg(DAGOpNo))) { if (DI->getDef()->isSubClassOf("Register")) { // Check if the fixed register belongs to the Register class. - if (!validateRegister(DI->getDef(), OpndRec)) + if (!validateRegister(DI->getDef(), OpndRec, Rec->getLoc())) PrintFatalError(Rec->getLoc(), "Error in Dag '" + Dag->getAsString() + "'Register: '" + DI->getDef()->getName() + diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp index 6d6d72e..aaea963 100644 --- a/llvm/utils/TableGen/DAGISelEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp @@ -51,7 +51,7 @@ static unsigned getResultPatternCost(const TreePatternNode &P, const Record *Op = P.getOperator(); if (Op->isSubClassOf("Instruction")) { Cost++; - CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op); + const CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(Op); if (II.usesCustomInserter) Cost += 10; } diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp index ee10500..f89187a 100644 --- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -339,8 +339,9 @@ unsigned MatcherTableEmitter::SizeMatcher(Matcher *N, raw_ostream &OS) { Size += 2; // Count the child's opcode. } else { Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i); - Size += GetVBRSize(cast<SwitchTypeMatcher>(N)->getCaseType( - i)); // Count the child's type. + Size += GetVBRSize(cast<SwitchTypeMatcher>(N) + ->getCaseType(i) + .SimpleTy); // Count the child's type. } const unsigned ChildSize = SizeMatcherList(Child, OS); assert(ChildSize != 0 && "Matcher cannot have child of size 0"); @@ -604,8 +605,10 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, IdxSize = 2; // size of opcode in table is 2 bytes. } else { Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i); - IdxSize = GetVBRSize(cast<SwitchTypeMatcher>(N)->getCaseType( - i)); // size of type in table is sizeof(VBR(MVT)) byte. + IdxSize = GetVBRSize( + cast<SwitchTypeMatcher>(N) + ->getCaseType(i) + .SimpleTy); // size of type in table is sizeof(VBR(MVT)) byte. } if (i != 0) { @@ -625,8 +628,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, if (!OmitComments) OS << "/*" << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << "*/"; - EmitVBRValue(cast<SwitchTypeMatcher>(N)->getCaseType(i), - OS); + EmitVBRValue(cast<SwitchTypeMatcher>(N)->getCaseType(i).SimpleTy, OS); } if (!OmitComments) OS << "// ->" << CurrentIdx + ChildSize; @@ -652,8 +654,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, case Matcher::CheckType: { if (cast<CheckTypeMatcher>(N)->getResNo() == 0) { - MVT::SimpleValueType VT = cast<CheckTypeMatcher>(N)->getType(); - switch (VT) { + MVT VT = cast<CheckTypeMatcher>(N)->getType(); + switch (VT.SimpleTy) { case MVT::i32: case MVT::i64: OS << "OPC_CheckTypeI" << MVT(VT).getSizeInBits() << ",\n"; @@ -662,7 +664,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, OS << "OPC_CheckType, "; if (!OmitComments) OS << "/*" << getEnumName(VT) << "*/"; - unsigned NumBytes = EmitVBRValue(VT, OS); + unsigned NumBytes = EmitVBRValue(VT.SimpleTy, OS); OS << "\n"; return NumBytes + 1; } @@ -670,14 +672,15 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo() << ", "; if (!OmitComments) OS << "/*" << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << "*/"; - unsigned NumBytes = EmitVBRValue(cast<CheckTypeMatcher>(N)->getType(), OS); + unsigned NumBytes = + EmitVBRValue(cast<CheckTypeMatcher>(N)->getType().SimpleTy, OS); OS << "\n"; return NumBytes + 2; } case Matcher::CheckChildType: { - MVT::SimpleValueType VT = cast<CheckChildTypeMatcher>(N)->getType(); - switch (VT) { + MVT VT = cast<CheckChildTypeMatcher>(N)->getType(); + switch (VT.SimpleTy) { case MVT::i32: case MVT::i64: OS << "OPC_CheckChild" << cast<CheckChildTypeMatcher>(N)->getChildNo() @@ -688,7 +691,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, << "Type, "; if (!OmitComments) OS << "/*" << getEnumName(VT) << "*/"; - unsigned NumBytes = EmitVBRValue(VT, OS); + unsigned NumBytes = EmitVBRValue(VT.SimpleTy, OS); OS << "\n"; return NumBytes + 1; } @@ -725,7 +728,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, OS << "/*" << getEnumName(cast<CheckValueTypeMatcher>(N)->getVT()) << "*/"; unsigned NumBytes = - EmitVBRValue(cast<CheckValueTypeMatcher>(N)->getVT(), OS); + EmitVBRValue(cast<CheckValueTypeMatcher>(N)->getVT().SimpleTy, OS); OS << "\n"; return NumBytes + 1; } @@ -784,21 +787,21 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, case Matcher::EmitInteger: { int64_t Val = cast<EmitIntegerMatcher>(N)->getValue(); - MVT::SimpleValueType VT = cast<EmitIntegerMatcher>(N)->getVT(); + MVT VT = cast<EmitIntegerMatcher>(N)->getVT(); unsigned OpBytes; - switch (VT) { + switch (VT.SimpleTy) { case MVT::i8: case MVT::i16: case MVT::i32: case MVT::i64: OpBytes = 1; - OS << "OPC_EmitInteger" << MVT(VT).getSizeInBits() << ", "; + OS << "OPC_EmitInteger" << VT.getSizeInBits() << ", "; break; default: OS << "OPC_EmitInteger, "; if (!OmitComments) OS << "/*" << getEnumName(VT) << "*/"; - OpBytes = EmitVBRValue(VT, OS) + 1; + OpBytes = EmitVBRValue(VT.SimpleTy, OS) + 1; break; } unsigned Bytes = OpBytes + EmitSignedVBRValue(Val, OS); @@ -809,19 +812,19 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, } case Matcher::EmitStringInteger: { const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue(); - MVT::SimpleValueType VT = cast<EmitStringIntegerMatcher>(N)->getVT(); + MVT VT = cast<EmitStringIntegerMatcher>(N)->getVT(); // These should always fit into 7 bits. unsigned OpBytes; - switch (VT) { + switch (VT.SimpleTy) { case MVT::i32: OpBytes = 1; - OS << "OPC_EmitStringInteger" << MVT(VT).getSizeInBits() << ", "; + OS << "OPC_EmitStringInteger" << VT.getSizeInBits() << ", "; break; default: OS << "OPC_EmitStringInteger, "; if (!OmitComments) OS << "/*" << getEnumName(VT) << "*/"; - OpBytes = EmitVBRValue(VT, OS) + 1; + OpBytes = EmitVBRValue(VT.SimpleTy, OS) + 1; break; } OS << Val << ','; @@ -834,7 +837,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, case Matcher::EmitRegister: { const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N); const CodeGenRegister *Reg = Matcher->getReg(); - MVT::SimpleValueType VT = Matcher->getVT(); + MVT VT = Matcher->getVT(); unsigned OpBytes; // If the enum value of the register is larger than one byte can handle, // use EmitRegister2. @@ -842,21 +845,21 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, OS << "OPC_EmitRegister2, "; if (!OmitComments) OS << "/*" << getEnumName(VT) << "*/"; - OpBytes = EmitVBRValue(VT, OS); + OpBytes = EmitVBRValue(VT.SimpleTy, OS); OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n"; return OpBytes + 3; } - switch (VT) { + switch (VT.SimpleTy) { case MVT::i32: case MVT::i64: OpBytes = 1; - OS << "OPC_EmitRegisterI" << MVT(VT).getSizeInBits() << ", "; + OS << "OPC_EmitRegisterI" << VT.getSizeInBits() << ", "; break; default: OS << "OPC_EmitRegister, "; if (!OmitComments) OS << "/*" << getEnumName(VT) << "*/"; - OpBytes = EmitVBRValue(VT, OS) + 1; + OpBytes = EmitVBRValue(VT.SimpleTy, OS) + 1; break; } if (Reg) { @@ -957,6 +960,13 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, } } const EmitNodeMatcherCommon *EN = cast<EmitNodeMatcherCommon>(N); + bool SupportsDeactivationSymbol = + EN->getInstruction().TheDef->getValueAsBit( + "supportsDeactivationSymbol"); + if (SupportsDeactivationSymbol) { + OS << "OPC_CaptureDeactivationSymbol,\n"; + OS.indent(FullIndexWidth + Indent); + } bool IsEmitNode = isa<EmitNodeMatcher>(EN); OS << (IsEmitNode ? "OPC_EmitNode" : "OPC_MorphNodeTo"); bool CompressVTs = EN->getNumVTs() < 3; @@ -1014,7 +1024,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i) { if (!OmitComments) OS << "/*" << getEnumName(EN->getVT(i)) << "*/"; - NumTypeBytes += EmitVBRValue(EN->getVT(i), OS); + NumTypeBytes += EmitVBRValue(EN->getVT(i).SimpleTy, OS); } OS << EN->getNumOperands(); @@ -1049,8 +1059,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N, OS << '\n'; } - return 4 + !CompressVTs + !CompressNodeInfo + NumTypeBytes + - NumOperandBytes + NumCoveredBytes; + return 4 + SupportsDeactivationSymbol + !CompressVTs + !CompressNodeInfo + + NumTypeBytes + NumOperandBytes + NumCoveredBytes; } case Matcher::CompleteMatch: { const CompleteMatchMatcher *CM = cast<CompleteMatchMatcher>(N); diff --git a/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/llvm/utils/TableGen/DAGISelMatcherGen.cpp index d84bfa8..d1c63d7 100644 --- a/llvm/utils/TableGen/DAGISelMatcherGen.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherGen.cpp @@ -23,10 +23,9 @@ using namespace llvm; /// getRegisterValueType - Look up and return the ValueType of the specified /// register. If the register is a member of multiple register classes, they /// must all have the same type. -static MVT::SimpleValueType getRegisterValueType(const Record *R, - const CodeGenTarget &T) { +static MVT getRegisterValueType(const Record *R, const CodeGenTarget &T) { bool FoundRC = false; - MVT::SimpleValueType VT = MVT::Other; + MVT VT = MVT::Other; const CodeGenRegister *Reg = T.getRegBank().getReg(R); for (const auto &RC : T.getRegBank().getRegClasses()) { @@ -37,14 +36,14 @@ static MVT::SimpleValueType getRegisterValueType(const Record *R, FoundRC = true; const ValueTypeByHwMode &VVT = RC.getValueTypeNum(0); assert(VVT.isSimple()); - VT = VVT.getSimple().SimpleTy; + VT = VVT.getSimple(); continue; } #ifndef NDEBUG // If this occurs in multiple register classes, they all have to agree. const ValueTypeByHwMode &VVT = RC.getValueTypeNum(0); - assert(VVT.isSimple() && VVT.getSimple().SimpleTy == VT && + assert(VVT.isSimple() && VVT.getSimple() == VT && "ValueType mismatch between register classes for this register"); #endif } @@ -240,7 +239,6 @@ void MatcherGen::EmitLeafMatchCode(const TreePatternNode &N) { if ( // Handle register references. Nothing to do here, they always match. LeafRec->isSubClassOf("RegisterClassLike") || LeafRec->isSubClassOf("RegisterOperand") || - LeafRec->isSubClassOf("PointerLikeRegClass") || LeafRec->isSubClassOf("SubRegIndex") || // Place holder for SRCVALUE nodes. Nothing to do here. LeafRec->getName() == "srcvalue") @@ -687,10 +685,10 @@ void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode &N, } if (Def->getName() == "undef_tied_input") { - MVT::SimpleValueType ResultVT = N.getSimpleType(0); + MVT ResultVT = N.getSimpleType(0); auto IDOperandNo = NextRecordedOperandNo++; const Record *ImpDef = Def->getRecords().getDef("IMPLICIT_DEF"); - CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(ImpDef); + const CodeGenInstruction &II = CGP.getTargetInfo().getInstruction(ImpDef); AddMatcher(new EmitNodeMatcher(II, ResultVT, {}, false, false, false, false, -1, IDOperandNo)); ResultOps.push_back(IDOperandNo); @@ -749,7 +747,7 @@ static bool mayInstNodeLoadOrStore(const TreePatternNode &N, const CodeGenDAGPatterns &CGP) { const Record *Op = N.getOperator(); const CodeGenTarget &CGT = CGP.getTargetInfo(); - CodeGenInstruction &II = CGT.getInstruction(Op); + const CodeGenInstruction &II = CGT.getInstruction(Op); return II.mayLoad || II.mayStore; } @@ -776,7 +774,7 @@ void MatcherGen::EmitResultInstructionAsOperand( const TreePatternNode &N, SmallVectorImpl<unsigned> &OutputOps) { const Record *Op = N.getOperator(); const CodeGenTarget &CGT = CGP.getTargetInfo(); - CodeGenInstruction &II = CGT.getInstruction(Op); + const CodeGenInstruction &II = CGT.getInstruction(Op); const DAGInstruction &Inst = CGP.getInstruction(Op); bool isRoot = &N == &Pattern.getDstPattern(); @@ -896,7 +894,7 @@ void MatcherGen::EmitResultInstructionAsOperand( // Result order: node results, chain, glue // Determine the result types. - SmallVector<MVT::SimpleValueType, 4> ResultVTs; + SmallVector<MVT, 4> ResultVTs; for (unsigned i = 0, e = N.getNumTypes(); i != e; ++i) ResultVTs.push_back(N.getSimpleType(i)); @@ -973,7 +971,7 @@ void MatcherGen::EmitResultInstructionAsOperand( NumFixedArityOperands, NextRecordedOperandNo)); // The non-chain and non-glue results of the newly emitted node get recorded. - for (MVT::SimpleValueType ResultVT : ResultVTs) { + for (MVT ResultVT : ResultVTs) { if (ResultVT == MVT::Other || ResultVT == MVT::Glue) break; OutputOps.push_back(NextRecordedOperandNo++); @@ -1046,7 +1044,7 @@ void MatcherGen::EmitResultCode() { const TreePatternNode &DstPat = Pattern.getDstPattern(); if (!DstPat.isLeaf() && DstPat.getOperator()->isSubClassOf("Instruction")) { const CodeGenTarget &CGT = CGP.getTargetInfo(); - CodeGenInstruction &II = CGT.getInstruction(DstPat.getOperator()); + const CodeGenInstruction &II = CGT.getInstruction(DstPat.getOperator()); if (II.HasOneImplicitDefWithKnownVT(CGT) != MVT::Other) HandledReg = II.ImplicitDefs[0]; diff --git a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp index 268e6bb..af73eb2 100644 --- a/llvm/utils/TableGen/DAGISelMatcherOpt.cpp +++ b/llvm/utils/TableGen/DAGISelMatcherOpt.cpp @@ -282,7 +282,7 @@ static void ContractNodes(std::unique_ptr<Matcher> &InputMatcherPtr, #endif if (ResultsMatch) { - ArrayRef<MVT::SimpleValueType> VTs = EN->getVTList(); + ArrayRef<MVT> VTs = EN->getVTList(); ArrayRef<unsigned> Operands = EN->getOperandList(); MatcherPtr->reset(new MorphNodeToMatcher( EN->getInstruction(), VTs, Operands, EN->hasChain(), @@ -556,17 +556,17 @@ static void FactorScope(std::unique_ptr<Matcher> &MatcherPtr) { // If all the options are CheckType's, we can form the SwitchType, woot. if (AllTypeChecks) { DenseMap<unsigned, unsigned> TypeEntry; - SmallVector<std::pair<MVT::SimpleValueType, Matcher *>, 8> Cases; + SmallVector<std::pair<MVT, Matcher *>, 8> Cases; for (Matcher *Optn : OptionsToMatch) { Matcher *M = FindNodeWithKind(Optn, Matcher::CheckType); assert(M && isa<CheckTypeMatcher>(M) && "Unknown Matcher type"); auto *CTM = cast<CheckTypeMatcher>(M); Matcher *MatcherWithoutCTM = Optn->unlinkNode(CTM); - MVT::SimpleValueType CTMTy = CTM->getType(); + MVT CTMTy = CTM->getType(); delete CTM; - unsigned &Entry = TypeEntry[CTMTy]; + unsigned &Entry = TypeEntry[CTMTy.SimpleTy]; if (Entry != 0) { // If we have unfactored duplicate types, then we should factor them. Matcher *PrevMatcher = Cases[Entry - 1].second; diff --git a/llvm/utils/TableGen/FastISelEmitter.cpp b/llvm/utils/TableGen/FastISelEmitter.cpp index ed05af0..d7f21f1c 100644 --- a/llvm/utils/TableGen/FastISelEmitter.cpp +++ b/llvm/utils/TableGen/FastISelEmitter.cpp @@ -189,7 +189,7 @@ struct OperandsSignature { /// are supported, false otherwise. /// bool initialize(TreePatternNode &InstPatNode, const CodeGenTarget &Target, - MVT::SimpleValueType VT, ImmPredicateSet &ImmediatePredicates, + MVT VT, ImmPredicateSet &ImmediatePredicates, const CodeGenRegisterClass *OrigDstRC) { if (InstPatNode.isLeaf()) return false; @@ -367,8 +367,8 @@ class FastISelMap { // A multimap is needed instead of a "plain" map because the key is // the instruction's complexity (an int) and they are not unique. using PredMap = std::multimap<int, InstructionMemo>; - using RetPredMap = std::map<MVT::SimpleValueType, PredMap>; - using TypeRetPredMap = std::map<MVT::SimpleValueType, RetPredMap>; + using RetPredMap = std::map<MVT, PredMap>; + using TypeRetPredMap = std::map<MVT, RetPredMap>; using OpcodeTypeRetPredMap = std::map<StringRef, TypeRetPredMap>; using OperandsOpcodeTypeRetPredMap = std::map<OperandsSignature, OpcodeTypeRetPredMap>; @@ -376,8 +376,7 @@ class FastISelMap { OperandsOpcodeTypeRetPredMap SimplePatterns; // This is used to check that there are no duplicate predicates - std::set<std::tuple<OperandsSignature, StringRef, MVT::SimpleValueType, - MVT::SimpleValueType, std::string>> + std::set<std::tuple<OperandsSignature, StringRef, MVT, MVT, std::string>> SimplePatternsCheck; std::map<OperandsSignature, std::vector<OperandsSignature>> @@ -440,7 +439,7 @@ void FastISelMap::collectPatterns(const CodeGenDAGPatterns &CGP) { const Record *Op = Dst.getOperator(); if (!Op->isSubClassOf("Instruction")) continue; - CodeGenInstruction &Inst = CGP.getTargetInfo().getInstruction(Op); + const CodeGenInstruction &Inst = CGP.getTargetInfo().getInstruction(Op); if (Inst.Operands.empty()) continue; @@ -501,10 +500,10 @@ void FastISelMap::collectPatterns(const CodeGenDAGPatterns &CGP) { const Record *InstPatOp = InstPatNode.getOperator(); StringRef OpcodeName = CGP.getSDNodeInfo(InstPatOp).getEnumName(); - MVT::SimpleValueType RetVT = MVT::isVoid; + MVT RetVT = MVT::isVoid; if (InstPatNode.getNumTypes()) RetVT = InstPatNode.getSimpleType(0); - MVT::SimpleValueType VT = RetVT; + MVT VT = RetVT; if (InstPatNode.getNumChildren()) { assert(InstPatNode.getChild(0).getNumTypes() == 1); VT = InstPatNode.getChild(0).getSimpleType(0); diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index f7993ce..bd79c42 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -282,7 +282,7 @@ static Expected<LLTCodeGen> getInstResultType(const TreePatternNode &Dst, // While we allow more than one output (both implicit and explicit defs) // below, we only expect one explicit def here. assert(Dst.getOperator()->isSubClassOf("Instruction")); - CodeGenInstruction &InstInfo = Target.getInstruction(Dst.getOperator()); + const CodeGenInstruction &InstInfo = Target.getInstruction(Dst.getOperator()); if (!InstInfo.Operands.NumDefs) return failedImport("Dst pattern child needs a def"); @@ -1034,8 +1034,8 @@ Error GlobalISelEmitter::importChildMatcher( if (ChildRec->isSubClassOf("ValueType") && !SrcChild.hasName()) { // An unnamed ValueType as in (sext_inreg GPR:$foo, i8). GISel represents // this as a literal constant with the scalar size. - MVT::SimpleValueType VT = llvm::getValueType(ChildRec); - OM.addPredicate<LiteralIntOperandMatcher>(MVT(VT).getScalarSizeInBits()); + MVT VT = llvm::getValueType(ChildRec); + OM.addPredicate<LiteralIntOperandMatcher>(VT.getScalarSizeInBits()); return Error::success(); } } @@ -1513,7 +1513,7 @@ GlobalISelEmitter::createInstructionRenderer(action_iterator InsertPt, "Pattern operator isn't an instruction (it's a ValueType)"); return failedImport("Pattern operator isn't an instruction"); } - CodeGenInstruction *DstI = &Target.getInstruction(DstOp); + const CodeGenInstruction *DstI = &Target.getInstruction(DstOp); // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy. @@ -1597,7 +1597,8 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers( action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, const TreePatternNode &Dst) const { const CodeGenInstruction *DstI = DstMIBuilder.getCGI(); - CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst.getOperator()); + const CodeGenInstruction *OrigDstI = + &Target.getInstruction(Dst.getOperator()); StringRef Name = OrigDstI->getName(); unsigned ExpectedDstINumUses = Dst.getNumChildren(); @@ -2140,7 +2141,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { // We need to replace the def and all its uses with the specified // operand. However, we must also insert COPY's wherever needed. // For now, emit a copy and let the register allocator clean up. - auto &DstI = Target.getInstruction(RK.getDef("COPY")); + const CodeGenInstruction &DstI = Target.getInstruction(RK.getDef("COPY")); const auto &DstIOperand = DstI.Operands[0]; OperandMatcher &OM0 = InsnMatcher.getOperand(0); diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp index ee3cd8c..9cd6ad2 100644 --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -72,6 +72,13 @@ private: using OperandInfoListTy = std::vector<OperandInfoTy>; using OperandInfoMapTy = std::map<OperandInfoTy, unsigned>; + DenseMap<const CodeGenInstruction *, const CodeGenInstruction *> + TargetSpecializedPseudoInsts; + + /// Compute mapping of opcodes which should have their definitions overridden + /// by a target version. + void buildTargetSpecializedPseudoInstsMap(); + /// Generate member functions in the target-specific GenInstrInfo class. /// /// This method is used to custom expand TIIPredicate definitions. @@ -155,21 +162,29 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) { Res += ", "; } else if (OpR->isSubClassOf("RegisterClass")) Res += getQualifiedName(OpR) + "RegClassID, "; - else if (OpR->isSubClassOf("PointerLikeRegClass")) - Res += utostr(OpR->getValueAsInt("RegClassKind")) + ", "; - else + else if (OpR->isSubClassOf("PointerLikeRegClass")) { + if (Inst.isPseudo) { + // TODO: Verify this is a fixed pseudo + PrintError(Inst.TheDef, + "missing target override for pseudoinstruction " + "using PointerLikeRegClass"); + PrintNote(OpR->getLoc(), + "target should define equivalent instruction " + "with RegisterClassLike replacement; (use " + "RemapAllTargetPseudoPointerOperands?)"); + } else { + PrintError(Inst.TheDef, + "non-pseudoinstruction user of PointerLikeRegClass"); + } + } else // -1 means the operand does not have a fixed register class. Res += "-1, "; // Fill in applicable flags. Res += "0"; - if (OpR->isSubClassOf("RegClassByHwMode")) { + if (OpR->isSubClassOf("RegClassByHwMode")) Res += "|(1<<MCOI::LookupRegClassByHwMode)"; - } else if (OpR->isSubClassOf("PointerLikeRegClass")) { - // Ptr value whose register class is resolved via callback. - Res += "|(1<<MCOI::LookupPtrRegClass)"; - } // Predicate operands. Check to see if the original unexpanded operand // was of type PredicateOp. @@ -216,6 +231,10 @@ InstrInfoEmitter::CollectOperandInfo(OperandInfoListTy &OperandInfoList, const CodeGenTarget &Target = CDP.getTargetInfo(); unsigned Offset = 0; for (const CodeGenInstruction *Inst : Target.getInstructions()) { + auto OverrideEntry = TargetSpecializedPseudoInsts.find(Inst); + if (OverrideEntry != TargetSpecializedPseudoInsts.end()) + Inst = OverrideEntry->second; + OperandInfoTy OperandInfo = GetOperandInfo(*Inst); if (OperandInfoMap.try_emplace(OperandInfo, Offset).second) { OperandInfoList.push_back(OperandInfo); @@ -859,6 +878,25 @@ void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, } } +void InstrInfoEmitter::buildTargetSpecializedPseudoInstsMap() { + ArrayRef<const Record *> SpecializedInsts = Records.getAllDerivedDefinitions( + "TargetSpecializedStandardPseudoInstruction"); + const CodeGenTarget &Target = CDP.getTargetInfo(); + + for (const Record *SpecializedRec : SpecializedInsts) { + const CodeGenInstruction &SpecializedInst = + Target.getInstruction(SpecializedRec); + const Record *BaseInstRec = SpecializedRec->getValueAsDef("Instruction"); + + const CodeGenInstruction &BaseInst = Target.getInstruction(BaseInstRec); + + if (!TargetSpecializedPseudoInsts.insert({&BaseInst, &SpecializedInst}) + .second) + PrintFatalError(SpecializedRec, "multiple overrides of '" + + BaseInst.getName() + "' defined"); + } +} + //===----------------------------------------------------------------------===// // Main Output. //===----------------------------------------------------------------------===// @@ -881,6 +919,8 @@ void InstrInfoEmitter::run(raw_ostream &OS) { // Collect all of the operand info records. Timer.startTimer("Collect operand info"); + buildTargetSpecializedPseudoInstsMap(); + OperandInfoListTy OperandInfoList; OperandInfoMapTy OperandInfoMap; unsigned OperandInfoSize = @@ -911,24 +951,23 @@ void InstrInfoEmitter::run(raw_ostream &OS) { } } - OS << "#if defined(GET_INSTRINFO_MC_DESC) || " - "defined(GET_INSTRINFO_CTOR_DTOR)\n"; - - OS << "namespace llvm {\n\n"; - - OS << "struct " << TargetName << "InstrTable {\n"; - OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n"; - OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), " - "\"Unwanted padding between Insts and OperandInfo\");\n"; - OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n"; - OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), " - "\"Unwanted padding between OperandInfo and ImplicitOps\");\n"; - OS << " MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) << "];\n"; - OS << "};\n\n"; - - OS << "} // end namespace llvm\n"; - OS << "#endif // defined(GET_INSTRINFO_MC_DESC) || " - "defined(GET_INSTRINFO_CTOR_DTOR)\n\n"; + { + IfGuardEmitter IfGuard( + OS, + "defined(GET_INSTRINFO_MC_DESC) || defined(GET_INSTRINFO_CTOR_DTOR)"); + NamespaceEmitter NS(OS, "llvm"); + + OS << "struct " << TargetName << "InstrTable {\n"; + OS << " MCInstrDesc Insts[" << NumberedInstructions.size() << "];\n"; + OS << " static_assert(alignof(MCInstrDesc) >= alignof(MCOperandInfo), " + "\"Unwanted padding between Insts and OperandInfo\");\n"; + OS << " MCOperandInfo OperandInfo[" << OperandInfoSize << "];\n"; + OS << " static_assert(alignof(MCOperandInfo) >= alignof(MCPhysReg), " + "\"Unwanted padding between OperandInfo and ImplicitOps\");\n"; + OS << " MCPhysReg ImplicitOps[" << std::max(ImplicitListSize, 1U) + << "];\n"; + OS << "};"; + } const CodeGenRegBank &RegBank = Target.getRegBank(); const CodeGenHwModes &CGH = Target.getHwModes(); @@ -963,6 +1002,11 @@ void InstrInfoEmitter::run(raw_ostream &OS) { for (const CodeGenInstruction *Inst : reverse(NumberedInstructions)) { // Keep a list of the instruction names. InstrNames.add(Inst->getName()); + + auto OverrideEntry = TargetSpecializedPseudoInsts.find(Inst); + if (OverrideEntry != TargetSpecializedPseudoInsts.end()) + Inst = OverrideEntry->second; + // Emit the record into the table. emitRecord(*Inst, --Num, InstrInfo, EmittedLists, OperandInfoMap, OS); } @@ -1103,7 +1147,8 @@ void InstrInfoEmitter::run(raw_ostream &OS) { Twine ClassName = TargetName + "GenInstrInfo"; OS << "struct " << ClassName << " : public TargetInstrInfo {\n" << " explicit " << ClassName - << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode = ~0u, " + << "(const TargetSubtargetInfo &STI, const TargetRegisterInfo &TRI, " + "unsigned CFSetupOpcode = ~0u, " "unsigned CFDestroyOpcode = ~0u, " "unsigned CatchRetOpcode = ~0u, unsigned ReturnOpcode = ~0u);\n" << " ~" << ClassName << "() override = default;\n" @@ -1157,9 +1202,11 @@ void InstrInfoEmitter::run(raw_ostream &OS) { << TargetName << "InstrComplexDeprecationInfos[];\n"; Twine ClassName = TargetName + "GenInstrInfo"; OS << ClassName << "::" << ClassName - << "(const TargetSubtargetInfo &STI, unsigned CFSetupOpcode, unsigned " + << "(const TargetSubtargetInfo &STI, const TargetRegisterInfo &TRI, " + "unsigned CFSetupOpcode, unsigned " "CFDestroyOpcode, unsigned CatchRetOpcode, unsigned ReturnOpcode)\n" - << " : TargetInstrInfo(CFSetupOpcode, CFDestroyOpcode, CatchRetOpcode, " + << " : TargetInstrInfo(TRI, CFSetupOpcode, CFDestroyOpcode, " + "CatchRetOpcode, " "ReturnOpcode"; if (NumClassesByHwMode != 0) OS << ", " << TargetName diff --git a/llvm/utils/TableGen/README.md b/llvm/utils/TableGen/README.md index ab3657d..7c5b450 100644 --- a/llvm/utils/TableGen/README.md +++ b/llvm/utils/TableGen/README.md @@ -33,8 +33,8 @@ that the backend developer needs. Resources for learning the language: * [TableGen Overview](https://llvm.org/docs/TableGen/index.html) -* [Programmer's reference guide](https://llvm.org/docs/TableGen/ProgRef.html) * [Tutorial](jupyter/tablegen_tutorial_part_1.ipynb) +* [Programmer's reference guide](https://llvm.org/docs/TableGen/ProgRef.html) * [Tools for Learning LLVM TableGen](https://blog.llvm.org/posts/2023-12-07-tools-for-learning-llvm-tablegen/) * [Lessons in TableGen](https://www.youtube.com/watch?v=45gmF77JFBY) (video), [slides](https://archive.fosdem.org/2019/schedule/event/llvm_tablegen/attachments/slides/3304/export/events/attachments/llvm_tablegen/slides/3304/tablegen.pdf) diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index 3e6e23f..02fd864 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -68,19 +68,22 @@ public: } // runEnums - Print out enum values for all of the registers. - void runEnums(raw_ostream &OS); + void runEnums(raw_ostream &OS, raw_ostream &MainOS, StringRef FilenamePrefix); // runMCDesc - Print out MC register descriptions. - void runMCDesc(raw_ostream &OS); + void runMCDesc(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix); // runTargetHeader - Emit a header fragment for the register info emitter. - void runTargetHeader(raw_ostream &OS); + void runTargetHeader(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix); // runTargetDesc - Output the target register and register file descriptions. - void runTargetDesc(raw_ostream &OS); + void runTargetDesc(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix); // run - Output the register file description. - void run(raw_ostream &OS); + TableGenOutputFiles run(StringRef FilenamePrefix); void debugDump(raw_ostream &OS); @@ -97,8 +100,19 @@ private: } // end anonymous namespace +static void emitInclude(StringRef FilenamePrefix, StringRef IncludeFile, + StringRef GuardMacro, raw_ostream &OS) { + OS << "#ifdef " << GuardMacro << '\n'; + OS << "#undef " << GuardMacro << '\n'; + OS << "#include \"" << FilenamePrefix << IncludeFile << "\"\n"; + OS << "#endif\n\n"; +} + // runEnums - Print out enum values for all of the registers. -void RegisterInfoEmitter::runEnums(raw_ostream &OS) { +void RegisterInfoEmitter::runEnums(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix) { + emitInclude(FilenamePrefix, "Enums.inc", "GET_REGINFO_ENUM", MainOS); + const auto &Registers = RegBank.getRegisters(); // Register enums are stored as uint16_t in the tables. Make sure we'll fit. @@ -108,9 +122,6 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { emitSourceFileHeader("Target Register Enum Values", OS); - OS << "\n#ifdef GET_REGINFO_ENUM\n"; - OS << "#undef GET_REGINFO_ENUM\n\n"; - OS << "namespace llvm {\n\n"; OS << "class MCRegisterClass;\n" @@ -194,7 +205,6 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) { OS << '\n'; OS << "} // end namespace llvm\n\n"; - OS << "#endif // GET_REGINFO_ENUM\n\n"; } static void printInt(raw_ostream &OS, int Val) { OS << Val; } @@ -234,9 +244,9 @@ void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS, } OS << "/// Get the weight in units of pressure for this register unit.\n" << "unsigned " << ClassName << "::\n" - << "getRegUnitWeight(unsigned RegUnit) const {\n" - << " assert(RegUnit < " << RegBank.getNumNativeRegUnits() - << " && \"invalid register unit\");\n"; + << "getRegUnitWeight(MCRegUnit RegUnit) const {\n" + << " assert(static_cast<unsigned>(RegUnit) < " + << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n"; if (!RegUnitsHaveUnitWeight) { OS << " static const uint8_t RUWeightTable[] = {\n "; for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); @@ -246,7 +256,7 @@ void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS, OS << RU.Weight << ", "; } OS << "};\n" - << " return RUWeightTable[RegUnit];\n"; + << " return RUWeightTable[static_cast<unsigned>(RegUnit)];\n"; } else { OS << " // All register units have unit weight.\n" << " return 1;\n"; @@ -330,9 +340,9 @@ void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS, << "register unit.\n" << "/// Returns a -1 terminated array of pressure set IDs\n" << "const int *" << ClassName << "::\n" - << "getRegUnitPressureSets(unsigned RegUnit) const {\n" - << " assert(RegUnit < " << RegBank.getNumNativeRegUnits() - << " && \"invalid register unit\");\n"; + << "getRegUnitPressureSets(MCRegUnit RegUnit) const {\n" + << " assert(static_cast<unsigned>(RegUnit) < " + << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n"; OS << " static const " << getMinimalTypeForRange(PSetsSeqs.size() - 1, 32) << " RUSetStartTable[] = {\n "; for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); @@ -341,7 +351,8 @@ void RegisterInfoEmitter::EmitRegUnitPressure(raw_ostream &OS, << ","; } OS << "};\n" - << " return &RCSetsTable[RUSetStartTable[RegUnit]];\n" + << " return " + "&RCSetsTable[RUSetStartTable[static_cast<unsigned>(RegUnit)]];\n" << "}\n\n"; } @@ -605,7 +616,7 @@ public: void print(raw_ostream &OS) { printBitVectorAsHex(OS, Values, 8); } }; -static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) { +static void printSimpleValueType(raw_ostream &OS, MVT VT) { OS << getEnumName(VT); } @@ -692,8 +703,7 @@ void RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS, SmallVector<unsigned, 4> RowMap; SmallVector<SmallVector<const CodeGenSubRegIndex *, 4>, 4> Rows; - auto SubRegIndicesSize = - std::distance(SubRegIndices.begin(), SubRegIndices.end()); + size_t SubRegIndicesSize = llvm::size(SubRegIndices); for (const auto &Idx : SubRegIndices) { unsigned Found = ~0u; for (unsigned r = 0, re = Rows.size(); r != re; ++r) { @@ -901,11 +911,11 @@ void RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS, // // runMCDesc - Print out MC register descriptions. // -void RegisterInfoEmitter::runMCDesc(raw_ostream &OS) { - emitSourceFileHeader("MC Register Information", OS); +void RegisterInfoEmitter::runMCDesc(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix) { + emitInclude(FilenamePrefix, "MCDesc.inc", "GET_REGINFO_MC_DESC", MainOS); - OS << "\n#ifdef GET_REGINFO_MC_DESC\n"; - OS << "#undef GET_REGINFO_MC_DESC\n\n"; + emitSourceFileHeader("MC Register Information", OS); const auto &Regs = RegBank.getRegisters(); @@ -1122,7 +1132,7 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS) { << RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, " << TargetName << "LaneMaskLists, " << TargetName << "RegStrings, " << TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, " - << (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n" + << (llvm::size(SubRegIndices) + 1) << ",\n" << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, false); @@ -1130,14 +1140,13 @@ void RegisterInfoEmitter::runMCDesc(raw_ostream &OS) { OS << "}\n\n"; OS << "} // end namespace llvm\n\n"; - OS << "#endif // GET_REGINFO_MC_DESC\n\n"; } -void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS) { - emitSourceFileHeader("Register Information Header Fragment", OS); +void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix) { + emitInclude(FilenamePrefix, "Header.inc", "GET_REGINFO_HEADER", MainOS); - OS << "\n#ifdef GET_REGINFO_HEADER\n"; - OS << "#undef GET_REGINFO_HEADER\n\n"; + emitSourceFileHeader("Register Information Header Fragment", OS); const std::string &TargetName = Target.getName().str(); std::string ClassName = TargetName + "GenRegisterInfo"; @@ -1168,7 +1177,7 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS) { } OS << " const RegClassWeight &getRegClassWeight(" << "const TargetRegisterClass *RC) const override;\n" - << " unsigned getRegUnitWeight(unsigned RegUnit) const override;\n" + << " unsigned getRegUnitWeight(MCRegUnit RegUnit) const override;\n" << " unsigned getNumRegPressureSets() const override;\n" << " const char *getRegPressureSetName(unsigned Idx) const override;\n" << " unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned " @@ -1176,7 +1185,7 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS) { << " const int *getRegClassPressureSets(" << "const TargetRegisterClass *RC) const override;\n" << " const int *getRegUnitPressureSets(" - << "unsigned RegUnit) const override;\n" + << "MCRegUnit RegUnit) const override;\n" << " ArrayRef<const char *> getRegMaskNames() const override;\n" << " ArrayRef<const uint32_t *> getRegMasks() const override;\n" << " bool isGeneralPurposeRegister(const MachineFunction &, " @@ -1214,17 +1223,17 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS) { OS << "} // end namespace " << RegisterClasses.front().Namespace << "\n\n"; } OS << "} // end namespace llvm\n\n"; - OS << "#endif // GET_REGINFO_HEADER\n\n"; } // // runTargetDesc - Output the target register and register file descriptions. // -void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { - emitSourceFileHeader("Target Register and Register Classes Information", OS); +void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS, + StringRef FilenamePrefix) { + emitInclude(FilenamePrefix, "TargetDesc.inc", "GET_REGINFO_TARGET_DESC", + MainOS); - OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n"; - OS << "#undef GET_REGINFO_TARGET_DESC\n\n"; + emitSourceFileHeader("Target Register and Register Classes Information", OS); OS << "namespace llvm {\n\n"; @@ -1251,14 +1260,14 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { unsigned NumModes = CGH.getNumModeIds(); // Build a shared array of value types. - SequenceToOffsetTable<std::vector<MVT::SimpleValueType>> VTSeqs( + SequenceToOffsetTable<std::vector<MVT>> VTSeqs( /*Terminator=*/MVT::Other); for (unsigned M = 0; M < NumModes; ++M) { for (const auto &RC : RegisterClasses) { - std::vector<MVT::SimpleValueType> S; + std::vector<MVT> S; for (const ValueTypeByHwMode &VVT : RC.VTs) if (VVT.hasDefault() || VVT.hasMode(M)) - S.push_back(VVT.get(M).SimpleTy); + S.push_back(VVT.get(M)); VTSeqs.add(S); } } @@ -1319,10 +1328,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { const RegSizeInfo &RI = RC.RSI.get(M); OS << " { " << RI.RegSize << ", " << RI.SpillSize << ", " << RI.SpillAlignment; - std::vector<MVT::SimpleValueType> VTs; + std::vector<MVT> VTs; for (const ValueTypeByHwMode &VVT : RC.VTs) if (VVT.hasDefault() || VVT.hasMode(M)) - VTs.push_back(VVT.get(M).SimpleTy); + VTs.push_back(VVT.get(M)); OS << ", /*VTLists+*/" << VTSeqs.get(VTs) << " }, // " << RC.getName() << '\n'; } @@ -1517,8 +1526,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { std::string ClassName = Target.getName().str() + "GenRegisterInfo"; - auto SubRegIndicesSize = - std::distance(SubRegIndices.begin(), SubRegIndices.end()); + size_t SubRegIndicesSize = llvm::size(SubRegIndices); if (!SubRegIndices.empty()) { emitComposeSubRegIndices(OS, ClassName); @@ -1839,25 +1847,42 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) { << "}\n\n"; OS << "} // end namespace llvm\n\n"; - OS << "#endif // GET_REGINFO_TARGET_DESC\n\n"; } -void RegisterInfoEmitter::run(raw_ostream &OS) { +TableGenOutputFiles RegisterInfoEmitter::run(StringRef FilenamePrefix) { TGTimer &Timer = Records.getTimer(); Timer.startTimer("Print enums"); - runEnums(OS); + std::string Main; + raw_string_ostream MainOS(Main); + std::string Enums; + raw_string_ostream EnumsOS(Enums); + runEnums(EnumsOS, MainOS, FilenamePrefix); Timer.startTimer("Print MC registers"); - runMCDesc(OS); + std::string MCDesc; + raw_string_ostream MCDescOS(MCDesc); + runMCDesc(MCDescOS, MainOS, FilenamePrefix); Timer.startTimer("Print header fragment"); - runTargetHeader(OS); + std::string Header; + raw_string_ostream HeaderOS(Header); + runTargetHeader(HeaderOS, MainOS, FilenamePrefix); Timer.startTimer("Print target registers"); - runTargetDesc(OS); + std::string TargetDesc; + raw_string_ostream TargetDescOS(TargetDesc); + runTargetDesc(TargetDescOS, MainOS, FilenamePrefix); if (RegisterInfoDebug) debugDump(errs()); + + // The suffixes should be in sync with the tablegen function in + // llvm/cmake/modules/TableGen.cmake. + return {Main, + {{"Enums.inc", Enums}, + {"MCDesc.inc", MCDesc}, + {"Header.inc", Header}, + {"TargetDesc.inc", TargetDesc}}}; } void RegisterInfoEmitter::debugDump(raw_ostream &OS) { @@ -1934,5 +1959,5 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) { } } -static TableGen::Emitter::OptClass<RegisterInfoEmitter> +static TableGen::Emitter::MultiFileOptClass<RegisterInfoEmitter> X("gen-register-info", "Generate registers and register classes info"); diff --git a/llvm/utils/TableGen/SDNodeInfoEmitter.cpp b/llvm/utils/TableGen/SDNodeInfoEmitter.cpp index dd18d29..0f2f117 100644 --- a/llvm/utils/TableGen/SDNodeInfoEmitter.cpp +++ b/llvm/utils/TableGen/SDNodeInfoEmitter.cpp @@ -195,15 +195,29 @@ static StringRef getTypeConstraintKindName(SDTypeConstraint::KindTy Kind) { #undef CASE } -static void emitTypeConstraint(raw_ostream &OS, SDTypeConstraint C) { +static void emitTypeConstraint( + raw_ostream &OS, SDTypeConstraint C, + const std::map<ValueTypeByHwMode, unsigned> &VTByHwModeTable) { unsigned OtherOpNo = 0; - MVT VT; + unsigned NumHwModes = 0; + unsigned VTByHwModeOffset = 0; + MVT VT = MVT::INVALID_SIMPLE_VALUE_TYPE; switch (C.ConstraintType) { case SDTypeConstraint::SDTCisVT: + // SequenceToOffsetTable::emit() prints a "dummy" (default-constructed) + // element if the table would otherwise be empty. VVT is empty in this case. + if (C.VVT.empty()) + break; + [[fallthrough]]; case SDTypeConstraint::SDTCVecEltisVT: - if (C.VVT.isSimple()) + if (C.VVT.isSimple()) { VT = C.VVT.getSimple(); + } else { + NumHwModes = C.VVT.size(); + assert(NumHwModes && "Empty type set?"); + VTByHwModeOffset = VTByHwModeTable.at(C.VVT); + } break; case SDTypeConstraint::SDTCisPtrTy: case SDTypeConstraint::SDTCisInt: @@ -221,15 +235,22 @@ static void emitTypeConstraint(raw_ostream &OS, SDTypeConstraint C) { break; } - StringRef KindName = getTypeConstraintKindName(C.ConstraintType); - StringRef VTName = VT.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE - ? "MVT::INVALID_SIMPLE_VALUE_TYPE" - : getEnumName(VT.SimpleTy); - OS << formatv("{{{}, {}, {}, {}}", KindName, C.OperandNo, OtherOpNo, VTName); + OS << '{' << getTypeConstraintKindName(C.ConstraintType) << ", " + << C.OperandNo << ", " << OtherOpNo << ", " << NumHwModes << ", "; + if (NumHwModes) { + OS << VTByHwModeOffset; + } else { + OS << (VT == MVT::INVALID_SIMPLE_VALUE_TYPE + ? "MVT::INVALID_SIMPLE_VALUE_TYPE" + : getEnumName(VT)); + } + OS << '}'; } std::vector<std::pair<unsigned, unsigned>> SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const { + std::map<ValueTypeByHwMode, unsigned> VTByHwModeTable; + using ConstraintsVecTy = SmallVector<SDTypeConstraint, 0>; SequenceToOffsetTable<ConstraintsVecTy> ConstraintTable( /*Terminator=*/std::nullopt); @@ -258,6 +279,16 @@ SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const { if (Constraints.empty()) continue; + for (const SDTypeConstraint &C : Constraints) { + if (C.ConstraintType == SDTypeConstraint::SDTCisVT || + C.ConstraintType == SDTypeConstraint::SDTCVecEltisVT) { + if (!C.VVT.isSimple()) { + assert(!C.VVT.empty() && "Unexpected empty type set"); + VTByHwModeTable.try_emplace(C.VVT); + } + } + } + // SequenceToOffsetTable reuses the storage if a sequence matches another // sequence's *suffix*. It is more likely that we have a matching *prefix*, // so reverse the order to increase the likelihood of a match. @@ -266,9 +297,26 @@ SDNodeInfoEmitter::emitTypeConstraints(raw_ostream &OS) const { ConstraintTable.layout(); + OS << "static const VTByHwModePair " << Target.getName() + << "VTByHwModeTable[] = {\n"; + unsigned VTByHwModeOffset = 0; + for (auto &[VTByHwMode, Offset] : VTByHwModeTable) { + OS << " /* " << VTByHwModeOffset << " */ "; + for (auto [Mode, VT] : VTByHwMode) + OS << '{' << Mode << ", " << getEnumName(VT.SimpleTy) << "}, "; + OS << '\n'; + Offset = VTByHwModeOffset; + VTByHwModeOffset += VTByHwMode.size(); + } + // Avoid "zero size arrays are an extension" warning. + if (VTByHwModeTable.empty()) + OS << " /* dummy */ {0, MVT::INVALID_SIMPLE_VALUE_TYPE}\n"; + OS << "};\n\n"; + OS << "static const SDTypeConstraint " << Target.getName() << "SDTypeConstraints[] = {\n"; - ConstraintTable.emit(OS, emitTypeConstraint); + ConstraintTable.emit(OS, std::bind(emitTypeConstraint, std::placeholders::_1, + std::placeholders::_2, VTByHwModeTable)); OS << "};\n\n"; for (const auto &[EnumName, Nodes] : NodesByName) { @@ -338,8 +386,8 @@ void SDNodeInfoEmitter::emitDescs(raw_ostream &OS) const { OS << "};\n\n"; OS << formatv("static const SDNodeInfo {0}GenSDNodeInfo(\n" - " /*NumOpcodes=*/{1}, {0}SDNodeDescs,\n" - " {0}SDNodeNames, {0}SDTypeConstraints);\n", + " /*NumOpcodes=*/{1}, {0}SDNodeDescs, {0}SDNodeNames,\n" + " {0}VTByHwModeTable, {0}SDTypeConstraints);\n", TargetName, NodesByName.size()); } diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 2f15cc8..ae0431e 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -27,6 +27,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/CodeGenHelpers.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringToOffsetTable.h" @@ -75,7 +76,15 @@ class SubtargetEmitter : TargetFeaturesEmitter { CodeGenTarget TGT; CodeGenSchedModels &SchedModels; + FeatureMapTy emitEnums(raw_ostream &OS); void emitSubtargetInfoMacroCalls(raw_ostream &OS); + std::tuple<unsigned, unsigned, unsigned> + emitMCDesc(raw_ostream &OS, const FeatureMapTy &FeatureMap); + void emitTargetDesc(raw_ostream &OS); + void emitHeader(raw_ostream &OS); + void emitCtor(raw_ostream &OS, unsigned NumNames, unsigned NumFeatures, + unsigned NumProcs); + unsigned featureKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap); unsigned cpuKeyValues(raw_ostream &OS, const FeatureMapTy &FeatureMap); unsigned cpuNames(raw_ostream &OS); @@ -141,7 +150,9 @@ public: /// Emit some information about the SubtargetFeature as calls to a macro so /// that they can be used from C++. void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) { - OS << "\n#ifdef GET_SUBTARGETINFO_MACRO\n"; + // Undef the GET_SUBTARGETINFO_MACRO macro at the end of the scope since it's + // used within the scope. + IfDefEmitter IfDefMacro(OS, "GET_SUBTARGETINFO_MACRO", /*LateUndef=*/true); std::vector<const Record *> FeatureList = Records.getAllDerivedDefinitions("SubtargetFeature"); @@ -167,14 +178,6 @@ void SubtargetEmitter::emitSubtargetInfoMacroCalls(raw_ostream &OS) { OS << "GET_SUBTARGETINFO_MACRO(" << FieldName << ", " << Default << ", " << Getter << ")\n"; } - OS << "#undef GET_SUBTARGETINFO_MACRO\n"; - OS << "#endif // GET_SUBTARGETINFO_MACRO\n\n"; - - OS << "\n#ifdef GET_SUBTARGETINFO_MC_DESC\n"; - OS << "#undef GET_SUBTARGETINFO_MC_DESC\n\n"; - - if (Target == "AArch64") - OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n"; } // @@ -440,26 +443,24 @@ void SubtargetEmitter::emitStageAndOperandCycleData( continue; StringRef Name = ProcModel.ItinsDef->getName(); - OS << "\n// Functional units for \"" << Name << "\"\n" - << "namespace " << Name << "FU {\n"; - - for (const auto &[Idx, FU] : enumerate(FUs)) - OS << " const InstrStage::FuncUnits " << FU->getName() << " = 1ULL << " - << Idx << ";\n"; + { + OS << "\n// Functional units for \"" << Name << "\"\n"; + NamespaceEmitter FUNamespace(OS, (Name + Twine("FU")).str()); - OS << "} // end namespace " << Name << "FU\n"; + for (const auto &[Idx, FU] : enumerate(FUs)) + OS << " const InstrStage::FuncUnits " << FU->getName() << " = 1ULL << " + << Idx << ";\n"; + } ConstRecVec BPs = ProcModel.ItinsDef->getValueAsListOfDefs("BP"); if (BPs.empty()) continue; - OS << "\n// Pipeline forwarding paths for itineraries \"" << Name << "\"\n" - << "namespace " << Name << "Bypass {\n"; + OS << "\n// Pipeline forwarding paths for itineraries \"" << Name << "\"\n"; + NamespaceEmitter BypassNamespace(OS, (Name + Twine("Bypass")).str()); OS << " const unsigned NoBypass = 0;\n"; for (const auto &[Idx, BP] : enumerate(BPs)) OS << " const unsigned " << BP->getName() << " = 1 << " << Idx << ";\n"; - - OS << "} // end namespace " << Name << "Bypass\n"; } // Begin stages table @@ -1940,13 +1941,14 @@ void SubtargetEmitter::parseFeaturesFunction(raw_ostream &OS) { } void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { - OS << "namespace " << Target << "_MC {\n" - << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n" - << " const MCInst *MI, const MCInstrInfo *MCII, " - << "const MCSubtargetInfo &STI, unsigned CPUID) {\n"; - emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true); - OS << "}\n"; - OS << "} // end namespace " << Target << "_MC\n\n"; + { + NamespaceEmitter NS(OS, (Target + Twine("_MC")).str()); + OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n" + << " const MCInst *MI, const MCInstrInfo *MCII, " + << "const MCSubtargetInfo &STI, unsigned CPUID) {\n"; + emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true); + OS << "}\n"; + } OS << "struct " << Target << "GenMCSubtargetInfo : public MCSubtargetInfo {\n"; @@ -1982,46 +1984,37 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { } void SubtargetEmitter::emitMcInstrAnalysisPredicateFunctions(raw_ostream &OS) { - OS << "\n#ifdef GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n"; - OS << "#undef GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n"; - STIPredicateExpander PE(Target, /*Indent=*/0); - PE.setExpandForMC(true); - PE.setByRef(true); - for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates()) - PE.expandSTIPredicate(OS, Fn); - - OS << "#endif // GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS\n\n"; - OS << "\n#ifdef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n"; - OS << "#undef GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n"; + { + IfDefEmitter IfDefDecls(OS, "GET_STIPREDICATE_DECLS_FOR_MC_ANALYSIS"); + PE.setExpandForMC(true); + PE.setByRef(true); + for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates()) + PE.expandSTIPredicate(OS, Fn); + } + IfDefEmitter IfDefDefs(OS, "GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS"); std::string ClassPrefix = Target + "MCInstrAnalysis"; PE.setExpandDefinition(true); PE.setClassPrefix(ClassPrefix); for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates()) PE.expandSTIPredicate(OS, Fn); - - OS << "#endif // GET_STIPREDICATE_DEFS_FOR_MC_ANALYSIS\n\n"; } -// -// SubtargetEmitter::run - Main subtarget enumeration emitter. -// -void SubtargetEmitter::run(raw_ostream &OS) { - emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); - - OS << "\n#ifdef GET_SUBTARGETINFO_ENUM\n"; - OS << "#undef GET_SUBTARGETINFO_ENUM\n\n"; - - OS << "namespace llvm {\n"; - auto FeatureMap = enumeration(OS); - OS << "} // end namespace llvm\n\n"; - OS << "#endif // GET_SUBTARGETINFO_ENUM\n\n"; +FeatureMapTy SubtargetEmitter::emitEnums(raw_ostream &OS) { + IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_ENUM"); + NamespaceEmitter NS(OS, "llvm"); + return enumeration(OS); +} - emitSubtargetInfoMacroCalls(OS); +std::tuple<unsigned, unsigned, unsigned> +SubtargetEmitter::emitMCDesc(raw_ostream &OS, const FeatureMapTy &FeatureMap) { + IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_MC_DESC"); + if (Target == "AArch64") + OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n"; + NamespaceEmitter LlvmNS(OS, "llvm"); - OS << "namespace llvm {\n"; unsigned NumFeatures = featureKeyValues(OS, FeatureMap); OS << "\n"; emitSchedModel(OS); @@ -2067,13 +2060,11 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "nullptr, nullptr, nullptr"; } OS << ");\n}\n\n"; + return {NumNames, NumFeatures, NumProcs}; +} - OS << "} // end namespace llvm\n\n"; - - OS << "#endif // GET_SUBTARGETINFO_MC_DESC\n\n"; - - OS << "\n#ifdef GET_SUBTARGETINFO_TARGET_DESC\n"; - OS << "#undef GET_SUBTARGETINFO_TARGET_DESC\n\n"; +void SubtargetEmitter::emitTargetDesc(raw_ostream &OS) { + IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_TARGET_DESC"); OS << "#include \"llvm/ADT/BitmaskEnum.h\"\n"; OS << "#include \"llvm/Support/Debug.h\"\n"; @@ -2081,21 +2072,21 @@ void SubtargetEmitter::run(raw_ostream &OS) { if (Target == "AArch64") OS << "#include \"llvm/TargetParser/AArch64TargetParser.h\"\n\n"; parseFeaturesFunction(OS); +} - OS << "#endif // GET_SUBTARGETINFO_TARGET_DESC\n\n"; - +void SubtargetEmitter::emitHeader(raw_ostream &OS) { // Create a TargetSubtargetInfo subclass to hide the MC layer initialization. - OS << "\n#ifdef GET_SUBTARGETINFO_HEADER\n"; - OS << "#undef GET_SUBTARGETINFO_HEADER\n\n"; + IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_HEADER"); + NamespaceEmitter LLVMNS(OS, "llvm"); std::string ClassName = Target + "GenSubtargetInfo"; - OS << "namespace llvm {\n"; OS << "class DFAPacketizer;\n"; - OS << "namespace " << Target << "_MC {\n" - << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass," - << " const MCInst *MI, const MCInstrInfo *MCII, " - << "const MCSubtargetInfo &STI, unsigned CPUID);\n" - << "} // end namespace " << Target << "_MC\n\n"; + { + NamespaceEmitter MCNS(OS, (Target + Twine("_MC")).str()); + OS << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass," + << " const MCInst *MI, const MCInstrInfo *MCII, " + << "const MCSubtargetInfo &STI, unsigned CPUID);\n"; + } OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n" << " explicit " << ClassName << "(const Triple &TT, StringRef CPU, " << "StringRef TuneCPU, StringRef FS);\n" @@ -2140,17 +2131,15 @@ void SubtargetEmitter::run(raw_ostream &OS) { PE.setByRef(false); for (const STIPredicateFunction &Fn : SchedModels.getSTIPredicates()) PE.expandSTIPredicate(OS, Fn); + OS << "};\n"; +} - OS << "};\n" - << "} // end namespace llvm\n\n"; - - OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; - - OS << "\n#ifdef GET_SUBTARGETINFO_CTOR\n"; - OS << "#undef GET_SUBTARGETINFO_CTOR\n\n"; - +void SubtargetEmitter::emitCtor(raw_ostream &OS, unsigned NumNames, + unsigned NumFeatures, unsigned NumProcs) { + IfDefEmitter IfDef(OS, "GET_SUBTARGETINFO_CTOR"); OS << "#include \"llvm/CodeGen/TargetSchedule.h\"\n\n"; - OS << "namespace llvm {\n"; + + NamespaceEmitter LLVMNS(OS, "llvm"); OS << "extern const llvm::StringRef " << Target << "Names[];\n"; OS << "extern const llvm::SubtargetFeatureKV " << Target << "FeatureKV[];\n"; OS << "extern const llvm::SubtargetSubTypeKV " << Target << "SubTypeKV[];\n"; @@ -2167,6 +2156,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << "extern const unsigned " << Target << "ForwardingPaths[];\n"; } + std::string ClassName = Target + "GenSubtargetInfo"; OS << ClassName << "::" << ClassName << "(const Triple &TT, StringRef CPU, " << "StringRef TuneCPU, StringRef FS)\n"; @@ -2204,11 +2194,20 @@ void SubtargetEmitter::run(raw_ostream &OS) { emitSchedModelHelpers(ClassName, OS); emitHwModeCheck(ClassName, OS, /*IsMC=*/false); emitGetMacroFusions(ClassName, OS); +} - OS << "} // end namespace llvm\n\n"; - - OS << "#endif // GET_SUBTARGETINFO_CTOR\n\n"; +// +// SubtargetEmitter::run - Main subtarget enumeration emitter. +// +void SubtargetEmitter::run(raw_ostream &OS) { + emitSourceFileHeader("Subtarget Enumeration Source Fragment", OS); + auto FeatureMap = emitEnums(OS); + emitSubtargetInfoMacroCalls(OS); + auto [NumNames, NumFeatures, NumProcs] = emitMCDesc(OS, FeatureMap); + emitTargetDesc(OS); + emitHeader(OS); + emitCtor(OS, NumNames, NumFeatures, NumProcs); emitMcInstrAnalysisPredicateFunctions(OS); } diff --git a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp index 9abb194..3926807 100644 --- a/llvm/utils/TableGen/X86InstrMappingEmitter.cpp +++ b/llvm/utils/TableGen/X86InstrMappingEmitter.cpp @@ -189,13 +189,14 @@ void X86InstrMappingEmitter::emitCompressEVEXTable( RecognizableInstrBase RI(*Inst); bool IsND = RI.OpMap == X86Local::T_MAP4 && RI.HasEVEX_B && RI.HasVEX_4V; + bool IsSETZUCCm = Name == "SETZUCCm"; // Add VEX encoded instructions to one of CompressedInsts vectors according // to it's opcode. if (RI.Encoding == X86Local::VEX) CompressedInsts[RI.Opcode].push_back(Inst); // Add relevant EVEX encoded instructions to PreCompressionInsts else if (RI.Encoding == X86Local::EVEX && !RI.HasEVEX_K && !RI.HasEVEX_L2 && - (!RI.HasEVEX_B || IsND)) + (!RI.HasEVEX_B || IsND || IsSETZUCCm)) PreCompressionInsts.push_back(Inst); } diff --git a/llvm/utils/TableGen/X86ManualInstrMapping.def b/llvm/utils/TableGen/X86ManualInstrMapping.def index 662c13e..deff210 100644 --- a/llvm/utils/TableGen/X86ManualInstrMapping.def +++ b/llvm/utils/TableGen/X86ManualInstrMapping.def @@ -333,6 +333,7 @@ ENTRY(VBROADCASTSDZ256rm, VBROADCASTSDYrm) ENTRY(VBROADCASTSDZ256rr, VBROADCASTSDYrr) ENTRY(VPBROADCASTQZ256rm, VPBROADCASTQYrm) ENTRY(VPBROADCASTQZ256rr, VPBROADCASTQYrr) +ENTRY(SETZUCCm, SETCCm) #undef ENTRY #ifndef NOCOMP_ND diff --git a/llvm/utils/extract_symbols.py b/llvm/utils/extract_symbols.py index 0cbfd2e..5254d16 100755 --- a/llvm/utils/extract_symbols.py +++ b/llvm/utils/extract_symbols.py @@ -97,6 +97,16 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration): # don't elif symbol.startswith("??_G") or symbol.startswith("??_E"): return None + # Delete template instantiations. These start with ?$ and can be discarded + # because they will be instantiated in the importing translation unit if + # needed. + elif symbol.startswith("??$"): + return None + # Delete lambda object constructors and operator() functions. These start + # with ??R<lambda_ or ??0<lambda_ and can be discarded because lambdas are + # usually local to a function. + elif symbol.startswith("??R<lambda_") or symbol.startswith("??0<lambda_"): + return None # An anonymous namespace is mangled as ?A(maybe hex number)@. Any symbol # that mentions an anonymous namespace can be discarded, as the anonymous # namespace doesn't exist outside of that translation unit. @@ -131,7 +141,24 @@ def should_keep_microsoft_symbol(symbol, calling_convention_decoration): # ::= .+@ (list of types) # ::= .*Z (list of types, varargs) # <throw-spec> ::= exceptions are not allowed - elif re.search(r"(llvm|clang)@@[A-Z][A-Z0-9_]*[A-JQ].+(X|.+@|.*Z)$", symbol): + elif re.search(r"@(llvm|clang)@@[A-Z][A-Z0-9_]*[A-JQ].+(X|.+@|.*Z)$", symbol): + # Remove llvm::<Class>::dump and clang::<Class>::dump methods because + # they are used for debugging only. + if symbol.startswith("?dump@"): + return None + return symbol + # Keep mangled global variables and static class members in llvm:: namespace. + # These have a type mangling that looks like (this is derived from + # clang/lib/AST/MicrosoftMangle.cpp): + # <type-encoding> ::= <storage-class> <variable-type> + # <storage-class> ::= 0 # private static member + # ::= 1 # protected static member + # ::= 2 # public static member + # ::= 3 # global + # ::= 4 # static local + # <variable-type> ::= <type> <cvr-qualifiers> + # ::= <type> <pointee-cvr-qualifiers> # pointers, references + elif re.search(r"@llvm@@[0-3].*$", symbol): return symbol return None diff --git a/llvm/utils/git/code-lint-helper.py b/llvm/utils/git/code-lint-helper.py index 1232f3a..a53549f 100755..100644 --- a/llvm/utils/git/code-lint-helper.py +++ b/llvm/utils/git/code-lint-helper.py @@ -18,98 +18,65 @@ https://llvm.org/docs/CodingStandards.html """ import argparse +import github +import json import os import subprocess import sys -from typing import List, Optional +from typing import Any, Dict, Final, List, Sequence class LintArgs: - start_rev: str = None - end_rev: str = None - repo: str = None - changed_files: List[str] = [] - token: str = None + start_rev: str + end_rev: str + repo: str + changed_files: Sequence[str] + token: str verbose: bool = True issue_number: int = 0 build_path: str = "build" clang_tidy_binary: str = "clang-tidy" - def __init__(self, args: argparse.Namespace = None) -> None: - if not args is None: + def __init__(self, args: argparse.Namespace) -> None: + if args is not None: self.start_rev = args.start_rev self.end_rev = args.end_rev self.repo = args.repo self.token = args.token - self.changed_files = args.changed_files + self.changed_files = ( + args.changed_files.split(",") if args.changed_files else [] + ) self.issue_number = args.issue_number self.verbose = args.verbose self.build_path = args.build_path self.clang_tidy_binary = args.clang_tidy_binary -COMMENT_TAG = "<!--LLVM CODE LINT COMMENT: clang-tidy-->" - - -def get_instructions(cpp_files: List[str]) -> str: - files_str = " ".join(cpp_files) - return f""" -git diff -U0 origin/main...HEAD -- {files_str} | -python3 clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py \\ - -path build -p1 -quiet""" - - -def clean_clang_tidy_output(output: str) -> Optional[str]: - """ - - Remove 'Running clang-tidy in X threads...' line - - Remove 'N warnings generated.' line - - Strip leading workspace path from file paths - """ - if not output or output == "No relevant changes found.": - return None - - lines = output.split("\n") - cleaned_lines = [] - - for line in lines: - if line.startswith("Running clang-tidy in") or line.endswith("generated."): - continue - - # Remove everything up to rightmost "llvm-project/" for correct files names - idx = line.rfind("llvm-project/") - if idx != -1: - line = line[idx + len("llvm-project/") :] - - cleaned_lines.append(line) +class LintHelper: + COMMENT_TAG: Final = "<!--LLVM CODE LINT COMMENT: {linter}-->" + name: str + friendly_name: str + comment: Dict[str, Any] = {} - if cleaned_lines: - return "\n".join(cleaned_lines) - return None + @property + def comment_tag(self) -> str: + return self.COMMENT_TAG.format(linter=self.name) + def instructions(self, files_to_lint: Sequence[str], args: LintArgs) -> str: + raise NotImplementedError() -# TODO: Add more rules when enabling other projects to use clang-tidy in CI. -def should_lint_file(filepath: str) -> bool: - return filepath.startswith("clang-tools-extra/clang-tidy/") + def filter_changed_files(self, changed_files: Sequence[str]) -> Sequence[str]: + raise NotImplementedError() + def run_linter_tool(self, files_to_lint: Sequence[str], args: LintArgs) -> str: + raise NotImplementedError() -def filter_changed_files(changed_files: List[str]) -> List[str]: - filtered_files = [] - for filepath in changed_files: - _, ext = os.path.splitext(filepath) - if ext not in (".cpp", ".c", ".h", ".hpp", ".hxx", ".cxx"): - continue - if not should_lint_file(filepath): - continue - if os.path.exists(filepath): - filtered_files.append(filepath) - - return filtered_files - - -def create_comment_text(warning: str, cpp_files: List[str]) -> str: - instructions = get_instructions(cpp_files) - return f""" -:warning: C/C++ code linter clang-tidy found issues in your code. :warning: + def create_comment_text( + self, linter_output: str, files_to_lint: Sequence[str], args: LintArgs + ) -> str: + instructions = self.instructions(files_to_lint, args) + return f""" +:warning: {self.friendly_name}, {self.name} found issues in your code. :warning: <details> <summary> @@ -124,133 +91,206 @@ You can test this locally with the following command: <details> <summary> -View the output from clang-tidy here. +View the output from {self.name} here. </summary> ``` -{warning} +{linter_output} ``` </details> """ + def find_comment(self, pr: Any) -> Any: + for comment in pr.as_issue().get_comments(): + if comment.body.startswith(self.comment_tag): + return comment + return None -def find_comment(pr: any) -> any: - for comment in pr.as_issue().get_comments(): - if COMMENT_TAG in comment.body: - return comment - return None + def update_pr(self, comment_text: str, args: LintArgs, create_new: bool) -> None: + assert args.repo is not None + repo = github.Github(args.token).get_repo(args.repo) + pr = repo.get_issue(args.issue_number).as_pull_request() + comment_text = f"{self.comment_tag}\n\n{comment_text}" -def create_comment( - comment_text: str, args: LintArgs, create_new: bool -) -> Optional[dict]: - import github + existing_comment = self.find_comment(pr) - repo = github.Github(args.token).get_repo(args.repo) - pr = repo.get_issue(args.issue_number).as_pull_request() + if existing_comment: + self.comment = {"body": comment_text, "id": existing_comment.id} + elif create_new: + self.comment = {"body": comment_text} - comment_text = COMMENT_TAG + "\n\n" + comment_text - existing_comment = find_comment(pr) + def run(self, args: LintArgs) -> bool: + if args.verbose: + print(f"got changed files: {args.changed_files}") - comment = None - if create_new or existing_comment: - comment = {"body": comment_text} - if existing_comment: - comment["id"] = existing_comment.id - return comment + files_to_lint = self.filter_changed_files(args.changed_files) + if not files_to_lint and args.verbose: + print("no modified files found") -def run_clang_tidy(changed_files: List[str], args: LintArgs) -> Optional[str]: - if not changed_files: - print("no c/c++ files found") - return None + is_success = True + linter_output = "" - git_diff_cmd = [ - "git", - "diff", - "-U0", - f"{args.start_rev}...{args.end_rev}", - "--", - ] + changed_files - - diff_proc = subprocess.run( - git_diff_cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - check=False, - ) + if files_to_lint: + linter_output = self.run_linter_tool(files_to_lint, args) + if linter_output: + is_success = False - if diff_proc.returncode != 0: - print(f"Git diff failed: {diff_proc.stderr}") - return None + should_update_gh = args.token is not None and args.repo is not None - diff_content = diff_proc.stdout - if not diff_content.strip(): - print("No diff content found") - return None + if is_success: + if should_update_gh: + comment_text = ( + ":white_check_mark: With the latest revision " + f"this PR passed the {self.friendly_name}." + ) + self.update_pr(comment_text, args, create_new=False) + return True + else: + if should_update_gh: + if linter_output: + comment_text = self.create_comment_text( + linter_output, files_to_lint, args + ) + self.update_pr(comment_text, args, create_new=True) + else: + # The linter failed but didn't output a result (e.g. some sort of + # infrastructure failure). + comment_text = ( + f":warning: The {self.friendly_name} failed without printing " + "an output. Check the logs for output. :warning:" + ) + self.update_pr(comment_text, args, create_new=False) + else: + if linter_output: + print( + f"Warning: {self.friendly_name}, {self.name} detected " + "some issues with your code..." + ) + print(linter_output) + else: + print(f"Warning: {self.friendly_name}, {self.name} failed to run.") + return False + + +class ClangTidyLintHelper(LintHelper): + name: Final = "clang-tidy" + friendly_name: Final = "C/C++ code linter" + + def instructions(self, files_to_lint: Sequence[str], args: LintArgs) -> str: + files_str = " ".join(files_to_lint) + return f""" +git diff -U0 origin/main...HEAD -- {files_str} | +python3 clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py \ + -path {args.build_path} -p1 -quiet""" + + def filter_changed_files(self, changed_files: Sequence[str]) -> Sequence[str]: + clang_tidy_changed_files = [ + arg for arg in changed_files if "third-party" not in arg + ] + + filtered_files = [] + for filepath in clang_tidy_changed_files: + _, ext = os.path.splitext(filepath) + if ext not in (".c", ".cpp", ".cxx", ".h", ".hpp", ".hxx"): + continue + if not self._should_lint_file(filepath): + continue + if os.path.exists(filepath): + filtered_files.append(filepath) + return filtered_files + + def _should_lint_file(self, filepath: str) -> bool: + # TODO: Add more rules when enabling other projects to use clang-tidy in CI. + return filepath.startswith("clang-tools-extra/clang-tidy/") + + def run_linter_tool(self, files_to_lint: Sequence[str], args: LintArgs) -> str: + if not files_to_lint: + return "" + + git_diff_cmd = [ + "git", + "diff", + "-U0", + f"{args.start_rev}...{args.end_rev}", + "--", + ] + git_diff_cmd.extend(files_to_lint) + + diff_proc = subprocess.run( + git_diff_cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=False, + ) - tidy_diff_cmd = [ - "clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py", - "-path", - args.build_path, - "-p1", - "-quiet", - ] - - if args.verbose: - print(f"Running clang-tidy-diff: {' '.join(tidy_diff_cmd)}") - - proc = subprocess.run( - tidy_diff_cmd, - input=diff_content, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - check=False, - ) + if diff_proc.returncode != 0: + print(f"Git diff failed: {diff_proc.stderr}") + return "" - return clean_clang_tidy_output(proc.stdout.strip()) + diff_content = diff_proc.stdout + if not diff_content.strip(): + if args.verbose: + print("No diff content found") + return "" + tidy_diff_cmd = [ + "clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py", + "-path", + args.build_path, + "-p1", + "-quiet", + ] -def run_linter(changed_files: List[str], args: LintArgs) -> tuple[bool, Optional[dict]]: - changed_files = [arg for arg in changed_files if "third-party" not in arg] + if args.verbose: + print(f"Running clang-tidy-diff: {' '.join(tidy_diff_cmd)}") + + proc = subprocess.run( + tidy_diff_cmd, + input=diff_content, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=False, + ) - cpp_files = filter_changed_files(changed_files) + clean_output = self._clean_clang_tidy_output(proc.stdout.strip()) + return clean_output - tidy_result = run_clang_tidy(cpp_files, args) - should_update_gh = args.token is not None and args.repo is not None + def _clean_clang_tidy_output(self, output: str) -> str: + """ + - Remove 'Running clang-tidy in X threads...' line + - Remove 'N warnings generated.' line + - Strip leading workspace path from file paths + """ + if not output or output == "No relevant changes found.": + return "" - comment = None - if tidy_result is None: - if should_update_gh: - comment_text = ( - ":white_check_mark: With the latest revision " - "this PR passed the C/C++ code linter." - ) - comment = create_comment(comment_text, args, create_new=False) - return True, comment - elif len(tidy_result) > 0: - if should_update_gh: - comment_text = create_comment_text(tidy_result, cpp_files) - comment = create_comment(comment_text, args, create_new=True) - else: - print( - "Warning: C/C++ code linter, clang-tidy detected " - "some issues with your code..." - ) - return False, comment - else: - # The linter failed but didn't output a result (e.g. some sort of - # infrastructure failure). - comment_text = ( - ":warning: The C/C++ code linter failed without printing " - "an output. Check the logs for output. :warning:" - ) - comment = create_comment(comment_text, args, create_new=False) - return False, comment + lines = output.split("\n") + cleaned_lines = [] + + for line in lines: + if line.startswith("Running clang-tidy in") or line.endswith("generated."): + continue + + # Remove everything up to rightmost "llvm-project/" for correct files names + idx = line.rfind("llvm-project/") + if idx != -1: + line = line[idx + len("llvm-project/") :] + + cleaned_lines.append(line) + + if cleaned_lines: + return "\n".join(cleaned_lines) + return "" + + + +ALL_LINTERS = (ClangTidyLintHelper(),) if __name__ == "__main__": @@ -298,32 +338,28 @@ if __name__ == "__main__": parsed_args = parser.parse_args() args = LintArgs(parsed_args) - changed_files = [] - if args.changed_files: - changed_files = args.changed_files.split(",") - - if args.verbose: - print(f"got changed files: {changed_files}") + failed_linters: List[str] = [] + comments: List[Dict[str, Any]] = [] - if args.verbose: - print("running linter clang-tidy") - - success, comment = run_linter(changed_files, args) - - if not success: + for linter in ALL_LINTERS: if args.verbose: - print("linter clang-tidy failed") + print(f"running linter {linter.name}") - # Write comments file if we have a comment - if comment: - if args.verbose: - print(f"linter clang-tidy has comment: {comment}") + if not linter.run(args): + failed_linters.append(linter.name) + if args.verbose: + print(f"linter {linter.name} failed") - with open("comments", "w") as f: - import json + # Write comments file if we have a comment + if linter.comment: + comments.append(linter.comment) + if args.verbose: + print(f"linter {linter.name} has comment: {linter.comment}") - json.dump([comment], f) + if len(comments): + with open("comments", "w") as f: + json.dump(comments, f) - if not success: - print("error: some linters failed: clang-tidy") + if len(failed_linters) > 0: + print(f"error: some linters failed: {' '.join(failed_linters)}") sys.exit(1) diff --git a/llvm/utils/git/github-automation.py b/llvm/utils/git/github-automation.py index 948788d..6e4417e 100755 --- a/llvm/utils/git/github-automation.py +++ b/llvm/utils/git/github-automation.py @@ -305,6 +305,8 @@ class CommitRequestGreeter: * [{merged_prs} Merged Pull Requests]({merged_prs_url}) * Top 3 Committers: {get_user_values_str(get_top_values(merged_by))} * Top 3 Reviewers: {get_user_values_str(get_top_values(reviewed_by))} + + Reviewers should clearly state their reasoning for accepting or rejecting this request, and finish with a clear statement such as \"I approve of this request\", \"LGTM\", or \"I do not approve of this request\". Please review the instructions for [obtaining commit access](https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access). """ self.issue.create_comment(textwrap.dedent(comment)) diff --git a/llvm/utils/git/requirements_upload_release.txt b/llvm/utils/git/requirements_upload_release.txt new file mode 100644 index 0000000..bc0ca45 --- /dev/null +++ b/llvm/utils/git/requirements_upload_release.txt @@ -0,0 +1,326 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile --generate-hashes --python-platform linux --python-version 3.10 -o requirements_upload_release.txt requirements_upload_release.txt.in +certifi==2025.11.12 \ + --hash=sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b \ + --hash=sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316 + # via requests +cffi==2.0.0 \ + --hash=sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb \ + --hash=sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b \ + --hash=sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f \ + --hash=sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9 \ + --hash=sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44 \ + --hash=sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2 \ + --hash=sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c \ + --hash=sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75 \ + --hash=sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65 \ + --hash=sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e \ + --hash=sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a \ + --hash=sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e \ + --hash=sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25 \ + --hash=sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a \ + --hash=sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe \ + --hash=sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b \ + --hash=sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91 \ + --hash=sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592 \ + --hash=sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187 \ + --hash=sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c \ + --hash=sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1 \ + --hash=sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94 \ + --hash=sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba \ + --hash=sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb \ + --hash=sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165 \ + --hash=sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529 \ + --hash=sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca \ + --hash=sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c \ + --hash=sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6 \ + --hash=sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c \ + --hash=sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0 \ + --hash=sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743 \ + --hash=sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63 \ + --hash=sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5 \ + --hash=sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5 \ + --hash=sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4 \ + --hash=sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d \ + --hash=sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b \ + --hash=sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93 \ + --hash=sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205 \ + --hash=sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27 \ + --hash=sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512 \ + --hash=sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d \ + --hash=sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c \ + --hash=sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037 \ + --hash=sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26 \ + --hash=sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322 \ + --hash=sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb \ + --hash=sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c \ + --hash=sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8 \ + --hash=sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4 \ + --hash=sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414 \ + --hash=sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9 \ + --hash=sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664 \ + --hash=sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9 \ + --hash=sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775 \ + --hash=sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739 \ + --hash=sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc \ + --hash=sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062 \ + --hash=sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe \ + --hash=sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9 \ + --hash=sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92 \ + --hash=sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5 \ + --hash=sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13 \ + --hash=sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d \ + --hash=sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26 \ + --hash=sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f \ + --hash=sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495 \ + --hash=sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b \ + --hash=sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6 \ + --hash=sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c \ + --hash=sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef \ + --hash=sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5 \ + --hash=sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18 \ + --hash=sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad \ + --hash=sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3 \ + --hash=sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7 \ + --hash=sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5 \ + --hash=sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534 \ + --hash=sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49 \ + --hash=sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2 \ + --hash=sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5 \ + --hash=sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453 \ + --hash=sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf + # via + # cryptography + # pynacl +charset-normalizer==3.4.4 \ + --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ + --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ + --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ + --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ + --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ + --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ + --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ + --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ + --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ + --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ + --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ + --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ + --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ + --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ + --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ + --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ + --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ + --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ + --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ + --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ + --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ + --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ + --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ + --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ + --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ + --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ + --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ + --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ + --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ + --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ + --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ + --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ + --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ + --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ + --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ + --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ + --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ + --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ + --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ + --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ + --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ + --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ + --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ + --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ + --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ + --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ + --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ + --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ + --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ + --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ + --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ + --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ + --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ + --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ + --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ + --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ + --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ + --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ + --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ + --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ + --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ + --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ + --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ + --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ + --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ + --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ + --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ + --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ + --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ + --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ + --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ + --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ + --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ + --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ + --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ + --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ + --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ + --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ + --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ + --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ + --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ + --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ + --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ + --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ + --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ + --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ + --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ + --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ + --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ + --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ + --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ + --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ + --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ + --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ + --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ + --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ + --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ + --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ + --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ + --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ + --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ + --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ + --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ + --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ + --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ + --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ + --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ + --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ + --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ + --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ + --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ + --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ + --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 + # via requests +cryptography==46.0.3 \ + --hash=sha256:00a5e7e87938e5ff9ff5447ab086a5706a957137e6e433841e9d24f38a065217 \ + --hash=sha256:01ca9ff2885f3acc98c29f1860552e37f6d7c7d013d7334ff2a9de43a449315d \ + --hash=sha256:09859af8466b69bc3c27bdf4f5d84a665e0f7ab5088412e9e2ec49758eca5cbc \ + --hash=sha256:0abf1ffd6e57c67e92af68330d05760b7b7efb243aab8377e583284dbab72c71 \ + --hash=sha256:1000713389b75c449a6e979ffc7dcc8ac90b437048766cef052d4d30b8220971 \ + --hash=sha256:109d4ddfadf17e8e7779c39f9b18111a09efb969a301a31e987416a0191ed93a \ + --hash=sha256:10b01676fc208c3e6feeb25a8b83d81767e8059e1fe86e1dc62d10a3018fa926 \ + --hash=sha256:10ca84c4668d066a9878890047f03546f3ae0a6b8b39b697457b7757aaf18dbc \ + --hash=sha256:15ab9b093e8f09daab0f2159bb7e47532596075139dd74365da52ecc9cb46c5d \ + --hash=sha256:191bb60a7be5e6f54e30ba16fdfae78ad3a342a0599eb4193ba88e3f3d6e185b \ + --hash=sha256:22d7e97932f511d6b0b04f2bfd818d73dcd5928db509460aaf48384778eb6d20 \ + --hash=sha256:23b1a8f26e43f47ceb6d6a43115f33a5a37d57df4ea0ca295b780ae8546e8044 \ + --hash=sha256:36e627112085bb3b81b19fed209c05ce2a52ee8b15d161b7c643a7d5a88491f3 \ + --hash=sha256:39b6755623145ad5eff1dab323f4eae2a32a77a7abef2c5089a04a3d04366715 \ + --hash=sha256:3b51b8ca4f1c6453d8829e1eb7299499ca7f313900dd4d89a24b8b87c0a780d4 \ + --hash=sha256:402b58fc32614f00980b66d6e56a5b4118e6cb362ae8f3fda141ba4689bd4506 \ + --hash=sha256:416260257577718c05135c55958b674000baef9a1c7d9e8f306ec60d71db850f \ + --hash=sha256:46acf53b40ea38f9c6c229599a4a13f0d46a6c3fa9ef19fc1a124d62e338dfa0 \ + --hash=sha256:4b7387121ac7d15e550f5cb4a43aef2559ed759c35df7336c402bb8275ac9683 \ + --hash=sha256:50fc3343ac490c6b08c0cf0d704e881d0d660be923fd3076db3e932007e726e3 \ + --hash=sha256:516ea134e703e9fe26bcd1277a4b59ad30586ea90c365a87781d7887a646fe21 \ + --hash=sha256:549e234ff32571b1f4076ac269fcce7a808d3bf98b76c8dd560e42dbc66d7d91 \ + --hash=sha256:5d7f93296ee28f68447397bf5198428c9aeeab45705a55d53a6343455dcb2c3c \ + --hash=sha256:5ecfccd2329e37e9b7112a888e76d9feca2347f12f37918facbb893d7bb88ee8 \ + --hash=sha256:6276eb85ef938dc035d59b87c8a7dc559a232f954962520137529d77b18ff1df \ + --hash=sha256:6b5063083824e5509fdba180721d55909ffacccc8adbec85268b48439423d78c \ + --hash=sha256:6eae65d4c3d33da080cff9c4ab1f711b15c1d9760809dad6ea763f3812d254cb \ + --hash=sha256:6f61efb26e76c45c4a227835ddeae96d83624fb0d29eb5df5b96e14ed1a0afb7 \ + --hash=sha256:71e842ec9bc7abf543b47cf86b9a743baa95f4677d22baa4c7d5c69e49e9bc04 \ + --hash=sha256:760f83faa07f8b64e9c33fc963d790a2edb24efb479e3520c14a45741cd9b2db \ + --hash=sha256:78a97cf6a8839a48c49271cdcbd5cf37ca2c1d6b7fdd86cc864f302b5e9bf459 \ + --hash=sha256:7ce938a99998ed3c8aa7e7272dca1a610401ede816d36d0693907d863b10d9ea \ + --hash=sha256:8a6e050cb6164d3f830453754094c086ff2d0b2f3a897a1d9820f6139a1f0914 \ + --hash=sha256:9394673a9f4de09e28b5356e7fff97d778f8abad85c9d5ac4a4b7e25a0de7717 \ + --hash=sha256:94cd0549accc38d1494e1f8de71eca837d0509d0d44bf11d158524b0e12cebf9 \ + --hash=sha256:a04bee9ab6a4da801eb9b51f1b708a1b5b5c9eb48c03f74198464c66f0d344ac \ + --hash=sha256:a23582810fedb8c0bc47524558fb6c56aac3fc252cb306072fd2815da2a47c32 \ + --hash=sha256:a2c0cd47381a3229c403062f764160d57d4d175e022c1df84e168c6251a22eec \ + --hash=sha256:a8b17438104fed022ce745b362294d9ce35b4c2e45c1d958ad4a4b019285f4a1 \ + --hash=sha256:a9a3008438615669153eb86b26b61e09993921ebdd75385ddd748702c5adfddb \ + --hash=sha256:b02cf04496f6576afffef5ddd04a0cb7d49cf6be16a9059d793a30b035f6b6ac \ + --hash=sha256:b419ae593c86b87014b9be7396b385491ad7f320bde96826d0dd174459e54665 \ + --hash=sha256:c0a7bb1a68a5d3471880e264621346c48665b3bf1c3759d682fc0864c540bd9e \ + --hash=sha256:c70cc23f12726be8f8bc72e41d5065d77e4515efae3690326764ea1b07845cfb \ + --hash=sha256:c8daeb2d2174beb4575b77482320303f3d39b8e81153da4f0fb08eb5fe86a6c5 \ + --hash=sha256:cb3d760a6117f621261d662bccc8ef5bc32ca673e037c83fbe565324f5c46936 \ + --hash=sha256:d55f3dffadd674514ad19451161118fd010988540cee43d8bc20675e775925de \ + --hash=sha256:d89c3468de4cdc4f08a57e214384d0471911a3830fcdaf7a8cc587e42a866372 \ + --hash=sha256:db391fa7c66df6762ee3f00c95a89e6d428f4d60e7abc8328f4fe155b5ac6e54 \ + --hash=sha256:dfb781ff7eaa91a6f7fd41776ec37c5853c795d3b358d4896fdbb5df168af422 \ + --hash=sha256:e5bf0ed4490068a2e72ac03d786693adeb909981cc596425d09032d372bcc849 \ + --hash=sha256:e7aec276d68421f9574040c26e2a7c3771060bc0cff408bae1dcb19d3ab1e63c \ + --hash=sha256:ef639cb3372f69ec44915fafcd6698b6cc78fbe0c2ea41be867f6ed612811963 \ + --hash=sha256:f260d0d41e9b4da1ed1e0f1ce571f97fe370b152ab18778e9e8f67d6af432018 + # via pyjwt +idna==3.11 \ + --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ + --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 + # via requests +pycparser==2.23 \ + --hash=sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2 \ + --hash=sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934 + # via cffi +pygithub==2.8.1 \ + --hash=sha256:23a0a5bca93baef082e03411bf0ce27204c32be8bfa7abc92fe4a3e132936df0 \ + --hash=sha256:341b7c78521cb07324ff670afd1baa2bf5c286f8d9fd302c1798ba594a5400c9 + # via -r requirements_upload_release.txt.in +pyjwt==2.9.0 \ + --hash=sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850 \ + --hash=sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c + # via pygithub +pynacl==1.6.1 \ + --hash=sha256:262a8de6bba4aee8a66f5edf62c214b06647461c9b6b641f8cd0cb1e3b3196fe \ + --hash=sha256:2b12f1b97346f177affcdfdc78875ff42637cb40dcf79484a97dae3448083a78 \ + --hash=sha256:319de653ef84c4f04e045eb250e6101d23132372b0a61a7acf91bac0fda8e58c \ + --hash=sha256:3206fa98737fdc66d59b8782cecc3d37d30aeec4593d1c8c145825a345bba0f0 \ + --hash=sha256:3384a454adf5d716a9fadcb5eb2e3e72cd49302d1374a60edc531c9957a9b014 \ + --hash=sha256:3cd787ec1f5c155dc8ecf39b1333cfef41415dc96d392f1ce288b4fe970df489 \ + --hash=sha256:4ce50d19f1566c391fedc8dc2f2f5be265ae214112ebe55315e41d1f36a7f0a9 \ + --hash=sha256:53543b4f3d8acb344f75fd4d49f75e6572fce139f4bfb4815a9282296ff9f4c0 \ + --hash=sha256:543f869140f67d42b9b8d47f922552d7a967e6c116aad028c9bfc5f3f3b3a7b7 \ + --hash=sha256:5953e8b8cfadb10889a6e7bd0f53041a745d1b3d30111386a1bb37af171e6daf \ + --hash=sha256:5a3becafc1ee2e5ea7f9abc642f56b82dcf5be69b961e782a96ea52b55d8a9fc \ + --hash=sha256:5f5b35c1a266f8a9ad22525049280a600b19edd1f785bccd01ae838437dcf935 \ + --hash=sha256:6b35d93ab2df03ecb3aa506be0d3c73609a51449ae0855c2e89c7ed44abde40b \ + --hash=sha256:7713f8977b5d25f54a811ec9efa2738ac592e846dd6e8a4d3f7578346a841078 \ + --hash=sha256:7d7c09749450c385301a3c20dca967a525152ae4608c0a096fe8464bfc3df93d \ + --hash=sha256:8d361dac0309f2b6ad33b349a56cd163c98430d409fa503b10b70b3ad66eaa1d \ + --hash=sha256:9fd1a4eb03caf8a2fe27b515a998d26923adb9ddb68db78e35ca2875a3830dde \ + --hash=sha256:a2bb472458c7ca959aeeff8401b8efef329b0fc44a89d3775cffe8fad3398ad8 \ + --hash=sha256:a569a4069a7855f963940040f35e87d8bc084cb2d6347428d5ad20550a0a1a21 \ + --hash=sha256:a6f9fd6d6639b1e81115c7f8ff16b8dedba1e8098d2756275d63d208b0e32021 \ + --hash=sha256:c2228054f04bf32d558fb89bb99f163a8197d5a9bf4efa13069a7fa8d4b93fc3 \ + --hash=sha256:d8615ee34d01c8e0ab3f302dcdd7b32e2bcf698ba5f4809e7cc407c8cdea7717 \ + --hash=sha256:d984c91fe3494793b2a1fb1e91429539c6c28e9ec8209d26d25041ec599ccf63 \ + --hash=sha256:dece79aecbb8f4640a1adbb81e4aa3bfb0e98e99834884a80eb3f33c7c30e708 \ + --hash=sha256:e49a3f3d0da9f79c1bec2aa013261ab9fa651c7da045d376bd306cf7c1792993 \ + --hash=sha256:e735c3a1bdfde3834503baf1a6d74d4a143920281cb724ba29fb84c9f49b9c48 \ + --hash=sha256:fc734c1696ffd49b40f7c1779c89ba908157c57345cf626be2e0719488a076d3 + # via pygithub +requests==2.32.4 \ + --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \ + --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422 + # via pygithub +typing-extensions==4.13.2 \ + --hash=sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c \ + --hash=sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef + # via + # cryptography + # pygithub +urllib3==2.2.3 \ + --hash=sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac \ + --hash=sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9 + # via + # pygithub + # requests diff --git a/llvm/utils/git/requirements_upload_release.txt.in b/llvm/utils/git/requirements_upload_release.txt.in new file mode 100644 index 0000000..d795ecd --- /dev/null +++ b/llvm/utils/git/requirements_upload_release.txt.in @@ -0,0 +1,10 @@ +# Convert this file into a requirements.txt file by running: +# +# pip install pip-tools +# pip-compile --generate-hashes -o requirements_upload_release.txt requirements_upload_release.txt.in +# +# or with uv by running: +# +# uv pip compile --generate-hashes --python-platform linux --python-version 3.10 -o requirements_upload_release.txt requirements_upload_release.txt.in + +PyGithub==2.8.1 diff --git a/llvm/utils/gn/build/sync_source_lists_from_cmake.py b/llvm/utils/gn/build/sync_source_lists_from_cmake.py index 4cd30aa..d772c90 100755 --- a/llvm/utils/gn/build/sync_source_lists_from_cmake.py +++ b/llvm/utils/gn/build/sync_source_lists_from_cmake.py @@ -40,6 +40,7 @@ def patch_gn_file(gn_file, add, remove): gn_contents = gn_contents[:tokloc] + ('"%s",' % a) + gn_contents[tokloc:] for r in remove: gn_contents = gn_contents.replace('"%s",' % r, "") + gn_contents = gn_contents.replace('"%s"' % r, "") with open(gn_file, "w") as f: f.write(gn_contents) diff --git a/llvm/utils/gn/secondary/bolt/lib/Passes/BUILD.gn b/llvm/utils/gn/secondary/bolt/lib/Passes/BUILD.gn index a261f28..7664753 100644 --- a/llvm/utils/gn/secondary/bolt/lib/Passes/BUILD.gn +++ b/llvm/utils/gn/secondary/bolt/lib/Passes/BUILD.gn @@ -30,18 +30,18 @@ static_library("Passes") { "IdenticalCodeFolding.cpp", "IndirectCallPromotion.cpp", "Inliner.cpp", - "InsertNegateRAStatePass.cpp", "Instrumentation.cpp", "JTFootprintReduction.cpp", "LivenessAnalysis.cpp", "LongJmp.cpp", "LoopInversionPass.cpp", "MCF.cpp", - "MarkRAStates.cpp", "PAuthGadgetScanner.cpp", "PLTCall.cpp", "PatchEntries.cpp", "PettisAndHansen.cpp", + "PointerAuthCFIAnalyzer.cpp", + "PointerAuthCFIFixup.cpp", "ProfileQualityStats.cpp", "RegAnalysis.cpp", "RegReAssign.cpp", diff --git a/llvm/utils/gn/secondary/bolt/unittests/BUILD.gn b/llvm/utils/gn/secondary/bolt/unittests/BUILD.gn index 9c5be59..eded769 100644 --- a/llvm/utils/gn/secondary/bolt/unittests/BUILD.gn +++ b/llvm/utils/gn/secondary/bolt/unittests/BUILD.gn @@ -2,6 +2,7 @@ group("unittests") { deps = [ "Core:CoreTests", "Profile:ProfileTests", + "Passes:PassTests", ] testonly = true } diff --git a/llvm/utils/gn/secondary/bolt/unittests/Passes/BUILD.gn b/llvm/utils/gn/secondary/bolt/unittests/Passes/BUILD.gn new file mode 100644 index 0000000..a534b69 --- /dev/null +++ b/llvm/utils/gn/secondary/bolt/unittests/Passes/BUILD.gn @@ -0,0 +1,48 @@ +import("//llvm/lib/Target/targets.gni") +import("//third-party/unittest/unittest.gni") + +unittest("PassTests") { + configs += [ "//llvm/utils/gn/build:bolt_code" ] + deps = [ + "//bolt/include/bolt/Core:TargetConfig.def", + "//bolt/lib/Core", + "//bolt/lib/Passes", + "//bolt/lib/Profile", + "//bolt/lib/Rewrite", + "//bolt/lib/Utils", + "//llvm/lib/DebugInfo/DWARF", + "//llvm/lib/MC", + "//llvm/lib/Object", + "//llvm/lib/Target:TargetsToBuild", + ] + sources = [ "PointerAuthCFIFixup.cpp" ] + + defines = [] + include_dirs = [] + if (llvm_build_AArch64) { + defines += [ "AARCH64_AVAILABLE" ] + + # This target reaches into the internal headers of LLVM's AArch64 library. + # That target doesn't expect that, so it doesn't use public_deps for + # tblgen-generated headers used only in internal headers (...which this + # target here questionably includes). So depend on the target that generates + # those headers here. + include_dirs += [ "//llvm/lib/Target/AArch64" ] + deps += [ + "//llvm/lib/Target/AArch64:AArch64GenSDNodeInfo", + "//llvm/lib/Target/AArch64/MCTargetDesc", + "//llvm/lib/Target/AArch64/Utils", + ] + } + if (llvm_build_X86) { + defines += [ "X86_AVAILABLE" ] + + # This target reaches into the internal headers of LLVM's X86 library. + # That target doesn't expect that, so it doesn't use public_deps for + # tblgen-generated headers used only in internal headers (...which this + # target here questionably includes). So depend on the target that generates + # those headers here. + include_dirs += [ "//llvm/lib/Target/X86" ] + deps += [ "//llvm/lib/Target/X86/MCTargetDesc" ] + } +} diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-doc/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-doc/BUILD.gn index 5815537..280d72f 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-doc/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-doc/BUILD.gn @@ -22,7 +22,6 @@ static_library("clang-doc") { "ClangDoc.cpp", "Generators.cpp", "HTMLGenerator.cpp", - "HTMLMustacheGenerator.cpp", "JSONGenerator.cpp", "MDGenerator.cpp", "Mapper.cpp", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn index de812cd..5c5958a 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn @@ -73,6 +73,7 @@ static_library("bugprone") { "ParentVirtualCallCheck.cpp", "PointerArithmeticOnPolymorphicObjectCheck.cpp", "PosixReturnCheck.cpp", + "RandomGeneratorSeedCheck.cpp", "RawMemoryCallOnNonTrivialTypeCheck.cpp", "RedundantBranchConditionCheck.cpp", "ReservedIdentifierCheck.cpp", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/cert/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/cert/BUILD.gn index 65c149b..8893800 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/cert/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/cert/BUILD.gn @@ -14,9 +14,5 @@ static_library("cert") { "//clang/lib/Lex", "//llvm/lib/Support", ] - sources = [ - "CERTTidyModule.cpp", - "LimitedRandomnessCheck.cpp", - "ProperlySeededRandomGeneratorCheck.cpp", - ] + sources = [ "CERTTidyModule.cpp" ] } diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn index 2366055..02c04d1 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn @@ -12,7 +12,6 @@ static_library("google") { "//llvm/lib/Support", ] sources = [ - "AvoidCStyleCastsCheck.cpp", "AvoidNSObjectNewCheck.cpp", "AvoidThrowingObjCExceptionCheck.cpp", "AvoidUnderscoreInGoogletestNameCheck.cpp", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn index 72b6188..c58d132 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/misc/BUILD.gn @@ -47,6 +47,7 @@ static_library("misc") { "NonCopyableObjectsCheck.cpp", "NonPrivateMemberVariablesInClassesCheck.cpp", "OverrideWithDifferentVisibilityCheck.cpp", + "PredictableRandCheck.cpp", "RedundantExpressionCheck.cpp", "StaticAssertCheck.cpp", "ThrowByValueCatchByReferenceCheck.cpp", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/modernize/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/modernize/BUILD.gn index 3a3f554..81d1ca6 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/modernize/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/modernize/BUILD.gn @@ -15,6 +15,7 @@ static_library("modernize") { sources = [ "AvoidBindCheck.cpp", "AvoidCArraysCheck.cpp", + "AvoidCStyleCastCheck.cpp", "AvoidSetjmpLongjmpCheck.cpp", "AvoidVariadicFunctionsCheck.cpp", "ConcatNestedNamespacesCheck.cpp", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn index f8c4838..37a6b71 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn @@ -47,16 +47,17 @@ static_library("clangd") { "//clang/lib/AST", "//clang/lib/ASTMatchers", "//clang/lib/Basic", + "//clang/lib/DependencyScanning", "//clang/lib/Driver", "//clang/lib/Format", "//clang/lib/Frontend", "//clang/lib/Index", "//clang/lib/Lex", + "//clang/lib/Options", "//clang/lib/Sema", "//clang/lib/Serialization", "//clang/lib/Tooling", "//clang/lib/Tooling/Core", - "//clang/lib/Tooling/DependencyScanning", "//clang/lib/Tooling/Inclusions", "//clang/lib/Tooling/Inclusions/Stdlib", "//clang/lib/Tooling/Refactoring", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn index d40ce64..e1d02c0 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn @@ -39,6 +39,7 @@ write_lit_config("lit_site_cfg") { "CLANGD_ENABLE_REMOTE=0", "CLANGD_TIDY_CHECKS=1", "LLVM_HOST_TRIPLE=$llvm_current_triple", + "LLVM_INCLUDE_BENCHMARKS=", "LLVM_LIT_TOOLS_DIR=", # Intentionally empty, matches cmake build. "LLVM_TOOLS_DIR=" + rebase_path("$root_out_dir/bin"), "LLVM_TARGET_TRIPLE=$llvm_target_triple", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/modularize/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/modularize/BUILD.gn index 1d01bd8..8f1c1d8 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/modularize/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/modularize/BUILD.gn @@ -6,6 +6,7 @@ executable("modularize") { "//clang/lib/Driver", "//clang/lib/Frontend", "//clang/lib/Lex", + "//clang/lib/Options", "//clang/lib/Serialization", "//clang/lib/Tooling", "//llvm/lib/Option", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/pp-trace/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/pp-trace/BUILD.gn index 2c0eac0..5acee9d 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/pp-trace/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/pp-trace/BUILD.gn @@ -5,6 +5,7 @@ executable("pp-trace") { "//clang/lib/Basic", "//clang/lib/Frontend", "//clang/lib/Lex", + "//clang/lib/Options", "//clang/lib/Serialization", "//clang/lib/Tooling", "//llvm/lib/Support", diff --git a/llvm/utils/gn/secondary/clang-tools-extra/unittests/clang-doc/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/unittests/clang-doc/BUILD.gn index 4cbd3b9..427a64e 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/unittests/clang-doc/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/unittests/clang-doc/BUILD.gn @@ -40,7 +40,6 @@ unittest("ClangDocTests") { "ClangDocTest.cpp", "GeneratorTest.cpp", "HTMLGeneratorTest.cpp", - "HTMLMustacheGeneratorTest.cpp", "JSONGeneratorTest.cpp", "MDGeneratorTest.cpp", "MergeTest.cpp", diff --git a/llvm/utils/gn/secondary/clang/include/clang/Driver/BUILD.gn b/llvm/utils/gn/secondary/clang/include/clang/Options/BUILD.gn index 955e786..955e786 100644 --- a/llvm/utils/gn/secondary/clang/include/clang/Driver/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/include/clang/Options/BUILD.gn diff --git a/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn b/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn index f7757d0..1bdb86aa 100644 --- a/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn @@ -10,6 +10,11 @@ clang_tablegen("AttrParsedAttrKinds") { td_file = "../Basic/Attr.td" } +clang_tablegen("AttrIsTypeDependent") { + args = [ "-gen-clang-attr-is-type-dependent" ] + td_file = "../Basic/Attr.td" +} + clang_tablegen("AttrSpellingListIndex") { args = [ "-gen-clang-attr-spelling-index" ] td_file = "../Basic/Attr.td" diff --git a/llvm/utils/gn/secondary/clang/lib/Tooling/DependencyScanning/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/DependencyScanning/BUILD.gn index 6733cf4..e75f74a 100644 --- a/llvm/utils/gn/secondary/clang/lib/Tooling/DependencyScanning/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/DependencyScanning/BUILD.gn @@ -4,15 +4,11 @@ static_library("DependencyScanning") { deps = [ "//clang/lib/AST", "//clang/lib/Basic", - "//clang/lib/CodeGen", "//clang/lib/Driver", "//clang/lib/Frontend", - "//clang/lib/FrontendTool", "//clang/lib/Lex", - "//clang/lib/Parse", - "//clang/lib/Serialization", - "//clang/lib/Tooling", "//llvm/lib/IR", + "//llvm/lib/Option", "//llvm/lib/Support", "//llvm/lib/Target:TargetsToBuild", "//llvm/lib/TargetParser", @@ -21,7 +17,7 @@ static_library("DependencyScanning") { "DependencyScannerImpl.cpp", "DependencyScanningFilesystem.cpp", "DependencyScanningService.cpp", - "DependencyScanningTool.cpp", + "DependencyScanningUtils.cpp", "DependencyScanningWorker.cpp", "InProcessModuleCache.cpp", "ModuleDepCollector.cpp", diff --git a/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn index e1f3117..9b524e2 100644 --- a/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn @@ -14,6 +14,7 @@ static_library("Driver") { # See the review thread of r311958 for details. "//clang/include/clang/StaticAnalyzer/Checkers", "//clang/lib/Basic", + "//clang/lib/Options", "//llvm/include/llvm/Config:llvm-config", "//llvm/lib/BinaryFormat", "//llvm/lib/Option", @@ -21,10 +22,6 @@ static_library("Driver") { "//llvm/lib/TargetParser", "//llvm/lib/WindowsDriver", ] - public_deps = [ - # public_dep because public header Options.h includes generated Options.inc. - "//clang/include/clang/Driver:Options", - ] if (host_os == "win") { # MSVCToolChain.cpp uses version.dll. libs = [ "version.lib" ] @@ -32,14 +29,14 @@ static_library("Driver") { sources = [ "Action.cpp", "Compilation.cpp", + "CreateASTUnitFromArgs.cpp", + "CreateInvocationFromArgs.cpp", "Distro.cpp", "Driver.cpp", - "DriverOptions.cpp", "Job.cpp", "Multilib.cpp", "MultilibBuilder.cpp", "OffloadBundler.cpp", - "OptionUtils.cpp", "Phases.cpp", "SanitizerArgs.cpp", "Tool.cpp", diff --git a/llvm/utils/gn/secondary/clang/lib/Frontend/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Frontend/BUILD.gn index 948d140..cdf39d6 100644 --- a/llvm/utils/gn/secondary/clang/lib/Frontend/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Frontend/BUILD.gn @@ -9,6 +9,7 @@ static_library("Frontend") { "//clang/lib/Driver", "//clang/lib/Edit", "//clang/lib/Lex", + "//clang/lib/Options", "//clang/lib/Parse", "//clang/lib/Sema", "//clang/lib/Serialization", @@ -27,7 +28,6 @@ static_library("Frontend") { "ChainedIncludesSource.cpp", "CompilerInstance.cpp", "CompilerInvocation.cpp", - "CreateInvocationFromCommandLine.cpp", "DependencyFile.cpp", "DependencyGraph.cpp", "DiagnosticRenderer.cpp", @@ -47,6 +47,7 @@ static_library("Frontend") { "SARIFDiagnosticPrinter.cpp", "SerializedDiagnosticPrinter.cpp", "SerializedDiagnosticReader.cpp", + "StandaloneDiagnostic.cpp", "TestModuleFileExtension.cpp", "TextDiagnostic.cpp", "TextDiagnosticBuffer.cpp", diff --git a/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn index 9f7140e..707eabf 100644 --- a/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/FrontendTool/BUILD.gn @@ -11,6 +11,7 @@ static_library("FrontendTool") { "//clang/lib/ExtractAPI", "//clang/lib/Frontend", "//clang/lib/Frontend/Rewrite", + "//clang/lib/Options", "//llvm/lib/Option", "//llvm/lib/Support", ] diff --git a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn index 03e5294..37ee181 100644 --- a/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn @@ -131,6 +131,7 @@ copy("Headers") { "altivec.h", "amdgpuintrin.h", "ammintrin.h", + "amo.h", "amxavx512intrin.h", "amxcomplexintrin.h", "amxfp16intrin.h", diff --git a/llvm/utils/gn/secondary/clang/lib/Options/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Options/BUILD.gn new file mode 100644 index 0000000..3f022ed --- /dev/null +++ b/llvm/utils/gn/secondary/clang/lib/Options/BUILD.gn @@ -0,0 +1,19 @@ +static_library("Options") { + output_name = "clangOptions" + configs += [ "//llvm/utils/gn/build:clang_code" ] + include_dirs = [ "." ] + deps = [ + "//clang/include/clang/Config", + "//clang/lib/Basic", + "//llvm/lib/Option", + "//llvm/lib/Support", + ] + public_deps = [ + # public_dep because public header Options.h includes generated Options.inc. + "//clang/include/clang/Options:Options", + ] + sources = [ + "DriverOptions.cpp", + "OptionUtils.cpp", + ] +} diff --git a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn index 96ff481..b6818a2 100644 --- a/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn @@ -24,6 +24,7 @@ static_library("Sema") { "//clang/include/clang/Basic:riscv_vector_builtin_sema", "//clang/include/clang/Sema:AttrParsedAttrImpl", "//clang/include/clang/Sema:AttrParsedAttrKinds", + "//clang/include/clang/Sema:AttrIsTypeDependent", "//clang/include/clang/Sema:AttrSpellingListIndex", "//clang/include/clang/Sema:AttrTemplateInstantiate", "//clang/lib/APINotes", diff --git a/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn index 0087aad..653062d 100644 --- a/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn @@ -2,14 +2,16 @@ static_library("Tooling") { output_name = "clangTooling" configs += [ "//llvm/utils/gn/build:clang_code" ] deps = [ - "//clang/include/clang/Driver:Options", + "//clang/include/clang/Options:Options", "//clang/lib/AST", "//clang/lib/ASTMatchers", "//clang/lib/Basic", + "//clang/lib/DependencyScanning", "//clang/lib/Driver", "//clang/lib/Format", "//clang/lib/Frontend", "//clang/lib/Lex", + "//clang/lib/Options", "//clang/lib/Rewrite", "//clang/lib/Tooling/Core", "//llvm/lib/TargetParser", @@ -19,6 +21,7 @@ static_library("Tooling") { "ArgumentsAdjusters.cpp", "CommonOptionsParser.cpp", "CompilationDatabase.cpp", + "DependencyScanningTool.cpp", "Execution.cpp", "ExpandResponseFilesCompilationDatabase.cpp", "FileMatchTrie.cpp", diff --git a/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn index 39a92f6..dd796d4 100644 --- a/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn @@ -6,6 +6,7 @@ executable("clang-check") { "//clang/lib/Driver", "//clang/lib/Frontend", "//clang/lib/Frontend/Rewrite", + "//clang/lib/Options", "//clang/lib/StaticAnalyzer/Frontend", "//clang/lib/Tooling", "//clang/lib/Tooling/Syntax", diff --git a/llvm/utils/gn/secondary/clang/tools/clang-installapi/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/clang-installapi/BUILD.gn index 89f0107..774402a 100644 --- a/llvm/utils/gn/secondary/clang/tools/clang-installapi/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/tools/clang-installapi/BUILD.gn @@ -13,6 +13,7 @@ driver_executable("clang-installapi") { "//clang/lib/Driver", "//clang/lib/Frontend", "//clang/lib/InstallAPI", + "//clang/lib/Options", "//clang/lib/Tooling", "//llvm/lib/Support", "//llvm/lib/TargetParser", diff --git a/llvm/utils/gn/secondary/clang/tools/clang-scan-deps/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/clang-scan-deps/BUILD.gn index f29c8ab..4e36f64 100644 --- a/llvm/utils/gn/secondary/clang/tools/clang-scan-deps/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/tools/clang-scan-deps/BUILD.gn @@ -13,6 +13,7 @@ driver_executable("clang-scan-deps") { "//clang/lib/AST", "//clang/lib/Basic", "//clang/lib/CodeGen", + "//clang/lib/DependencyScanning", "//clang/lib/Driver", "//clang/lib/Frontend", "//clang/lib/FrontendTool", @@ -20,7 +21,6 @@ driver_executable("clang-scan-deps") { "//clang/lib/Parse", "//clang/lib/Serialization", "//clang/lib/Tooling", - "//clang/lib/Tooling/DependencyScanning", "//llvm/lib/IR", "//llvm/lib/Support", ] diff --git a/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn index 54fca3b..b402bbb 100644 --- a/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn @@ -57,6 +57,7 @@ driver_executable("clang") { "//clang/lib/Frontend", "//clang/lib/FrontendTool", "//clang/lib/Headers", + "//clang/lib/Options", "//clang/tools/clang-linker-wrapper", "//clang/tools/clang-nvlink-wrapper", "//clang/tools/clang-offload-bundler", diff --git a/llvm/utils/gn/secondary/clang/unittests/BUILD.gn b/llvm/utils/gn/secondary/clang/unittests/BUILD.gn index b1ebfce..d04a5db 100644 --- a/llvm/utils/gn/secondary/clang/unittests/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/unittests/BUILD.gn @@ -9,6 +9,7 @@ group("unittests") { "Basic:BasicTests", "CodeGen:ClangCodeGenTests", "CrossTU:CrossTUTests", + "DependencyScanning:ClangDependencyScanningTests", "Driver:ClangDriverTests", "Format:FormatTests", "Frontend:FrontendTests", diff --git a/llvm/utils/gn/secondary/clang/unittests/DependencyScanning/BUILD.gn b/llvm/utils/gn/secondary/clang/unittests/DependencyScanning/BUILD.gn new file mode 100644 index 0000000..4098694 --- /dev/null +++ b/llvm/utils/gn/secondary/clang/unittests/DependencyScanning/BUILD.gn @@ -0,0 +1,15 @@ +import("//third-party/unittest/unittest.gni") + +unittest("ClangDependencyScanningTests") { + configs += [ "//llvm/utils/gn/build:clang_code" ] + deps = [ + "//clang/lib/DependencyScanning", + "//clang/lib/Frontend", + "//llvm/lib/Option", + "//llvm/lib/Support", + ] + sources = [ + "DependencyScanningFilesystemTest.cpp", + "DependencyScanningWorkerTest.cpp", + ] +} diff --git a/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn b/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn index 8e1d09c..fd0a7ec 100644 --- a/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn @@ -7,6 +7,7 @@ unittest("ToolingTests") { "//clang/lib/AST", "//clang/lib/ASTMatchers", "//clang/lib/Basic", + "//clang/lib/DependencyScanning", "//clang/lib/Format", "//clang/lib/Frontend", "//clang/lib/Lex", @@ -14,7 +15,6 @@ unittest("ToolingTests") { "//clang/lib/Testing", "//clang/lib/Tooling", "//clang/lib/Tooling/Core", - "//clang/lib/Tooling/DependencyScanning", "//clang/lib/Tooling/Inclusions", "//clang/lib/Tooling/Inclusions/Stdlib", "//clang/lib/Tooling/Refactoring", @@ -30,8 +30,7 @@ unittest("ToolingTests") { "CastExprTest.cpp", "CommentHandlerTest.cpp", "CompilationDatabaseTest.cpp", - "DependencyScanning/DependencyScannerTest.cpp", - "DependencyScanning/DependencyScanningFilesystemTest.cpp", + "DependencyScannerTest.cpp", "DiagnosticsYamlTest.cpp", "ExecutionTest.cpp", "FixItTest.cpp", diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn index 1d24d04..483d56b 100644 --- a/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn +++ b/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn @@ -7,6 +7,7 @@ if (current_toolchain == host_toolchain) { } } else { asan_sources = [ + "asan_aix.cpp", "asan_activation.cpp", "asan_activation.h", "asan_activation_flags.inc", diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn index 2e7aa45..1bd8125 100644 --- a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn +++ b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn @@ -96,5 +96,11 @@ source_set("_unused") { "arm/comparesf2.S", "arm/divsi3.S", "arm/udivsi3.S", + "arm/fnan2.c", + "arm/fnorm2.c", + "arm/funder.c", + "arm/mulsf3.S", + "arm/divsf3.S", + "arm/thumb1/mulsf3.S", ] } diff --git a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni index 5d1fb02..e2f91ad 100644 --- a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni +++ b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni @@ -272,7 +272,10 @@ if (current_cpu == "x86") { ] } if (current_os == "win") { - builtins_sources += [ "i386/chkstk.S" ] + builtins_sources += [ + "i386/chkstk.S", + "i386/chkstk2.S", + ] } } else if (current_cpu == "x64") { builtins_sources -= [ diff --git a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn index 66531c7..9755fe3 100644 --- a/llvm/utils/gn/secondary/libcxx/include/BUILD.gn +++ b/llvm/utils/gn/secondary/libcxx/include/BUILD.gn @@ -19,6 +19,7 @@ if (current_toolchain == default_toolchain) { "_LIBCPP_ABI_FORCE_ITANIUM=", "_LIBCPP_ABI_FORCE_MICROSOFT=", "_LIBCPP_ABI_VERSION=$libcxx_abi_version", + "_LIBCPP_ASSERTION_SEMANTIC_DEFAULT=_LIBCPP_ASSERTION_SEMANTIC_HARDENING_DEPENDENT", "_LIBCPP_EXTRA_SITE_DEFINES=", "_LIBCPP_HAS_FILESYSTEM=1", "_LIBCPP_HAS_THREADS=1", @@ -39,6 +40,8 @@ if (current_toolchain == default_toolchain) { "_LIBCPP_INSTRUMENTED_WITH_ASAN=", "_LIBCPP_ABI_DEFINES=", "_LIBCPP_HARDENING_MODE_DEFAULT=_LIBCPP_HARDENING_MODE_NONE", + "_LIBCPP_LIBC_PICOLIBC=", + "_LIBCPP_LIBC_NEWLIB=", "_LIBCPP_PSTL_BACKEND_LIBDISPATCH=", "_LIBCPP_PSTL_BACKEND_SERIAL=", "_LIBCPP_PSTL_BACKEND_STD_THREAD=1", @@ -268,6 +271,7 @@ if (current_toolchain == default_toolchain) { "__algorithm/simd_utils.h", "__algorithm/sort.h", "__algorithm/sort_heap.h", + "__algorithm/specialized_algorithms.h", "__algorithm/stable_partition.h", "__algorithm/stable_sort.h", "__algorithm/swap_ranges.h", @@ -402,6 +406,8 @@ if (current_toolchain == default_toolchain) { "__configuration/abi.h", "__configuration/availability.h", "__configuration/compiler.h", + "__configuration/experimental.h", + "__configuration/hardening.h", "__configuration/language.h", "__configuration/platform.h", "__coroutine/coroutine_handle.h", @@ -1164,7 +1170,6 @@ if (current_toolchain == default_toolchain) { "__locale_dir/locale_base_api.h", "__locale_dir/locale_base_api/bsd_locale_fallbacks.h", "__locale_dir/locale_base_api/ibm.h", - "__locale_dir/locale_base_api/musl.h", "__locale_dir/locale_base_api/openbsd.h", "__locale_dir/messages.h", "__locale_dir/money.h", @@ -1177,6 +1182,7 @@ if (current_toolchain == default_toolchain) { "__locale_dir/support/fuchsia.h", "__locale_dir/support/linux.h", "__locale_dir/support/netbsd.h", + "__locale_dir/support/newlib.h", "__locale_dir/support/no_locale/characters.h", "__locale_dir/support/no_locale/strtonum.h", "__locale_dir/support/windows.h", @@ -1214,7 +1220,6 @@ if (current_toolchain == default_toolchain) { "__mdspan/mdspan.h", "__memory/addressof.h", "__memory/align.h", - "__memory/aligned_alloc.h", "__memory/allocate_at_least.h", "__memory/allocation_guard.h", "__memory/allocator.h", @@ -1466,7 +1471,6 @@ if (current_toolchain == default_toolchain) { "__type_traits/is_array.h", "__type_traits/is_assignable.h", "__type_traits/is_base_of.h", - "__type_traits/is_bounded_array.h", "__type_traits/is_callable.h", "__type_traits/is_char_like_type.h", "__type_traits/is_class.h", @@ -1503,7 +1507,6 @@ if (current_toolchain == default_toolchain) { "__type_traits/is_reference.h", "__type_traits/is_reference_wrapper.h", "__type_traits/is_referenceable.h", - "__type_traits/is_replaceable.h", "__type_traits/is_same.h", "__type_traits/is_scalar.h", "__type_traits/is_signed.h", @@ -1517,7 +1520,6 @@ if (current_toolchain == default_toolchain) { "__type_traits/is_trivially_destructible.h", "__type_traits/is_trivially_lexicographically_comparable.h", "__type_traits/is_trivially_relocatable.h", - "__type_traits/is_unbounded_array.h", "__type_traits/is_union.h", "__type_traits/is_unqualified.h", "__type_traits/is_unsigned.h", @@ -1711,7 +1713,6 @@ if (current_toolchain == default_toolchain) { "sstream", "stack", "stdatomic.h", - "stdbool.h", "stddef.h", "stdexcept", "stdio.h", diff --git a/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn index 10c5f95..af45332 100644 --- a/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/source/Host/BUILD.gn @@ -16,6 +16,7 @@ static_library("Host") { ] public_deps = [ "//llvm/utils/gn/build/libs/xml" ] sources = [ + "common/DiagnosticsRendering.cpp", "common/File.cpp", "common/FileAction.cpp", "common/FileCache.cpp", diff --git a/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn index 1612144..6d0e7c0 100644 --- a/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/source/Plugins/Language/CPlusPlus/BUILD.gn @@ -41,11 +41,11 @@ static_library("CPlusPlus") { "CxxStringTypes.cpp", "Generic.cpp", "GenericBitset.cpp", + "GenericInitializerList.cpp", "GenericList.cpp", "GenericOptional.cpp", "LibCxx.cpp", "LibCxxAtomic.cpp", - "LibCxxInitializerList.cpp", "LibCxxMap.cpp", "LibCxxProxyArray.cpp", "LibCxxQueue.cpp", @@ -58,6 +58,7 @@ static_library("CPlusPlus") { "LibCxxVariant.cpp", "LibCxxVector.cpp", "LibStdcpp.cpp", + "LibStdcppSpan.cpp", "LibStdcppTuple.cpp", "LibStdcppUniquePointer.cpp", "MSVCUndecoratedNameParser.cpp", diff --git a/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn index 679373d..ac63bbc 100644 --- a/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/source/Target/BUILD.gn @@ -35,6 +35,7 @@ static_library("Target") { sources = [ "ABI.cpp", "AssertFrameRecognizer.cpp", + "BorrowedStackFrame.cpp", "CoreFileMemoryRanges.cpp", "DynamicRegisterInfo.cpp", "ExecutionContext.cpp", diff --git a/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn b/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn index 4221fab..47143ea 100644 --- a/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/source/Utility/BUILD.gn @@ -21,7 +21,6 @@ static_library("Utility") { "DataEncoder.cpp", "DataExtractor.cpp", "Diagnostics.cpp", - "DiagnosticsRendering.cpp", "Environment.cpp", "ErrorMessages.cpp", "Event.cpp", @@ -61,6 +60,7 @@ static_library("Utility") { "UserIDResolver.cpp", "VASprintf.cpp", "VMRange.cpp", + "VirtualDataExtractor.cpp", "XcodeSDK.cpp", "ZipFile.cpp", ] diff --git a/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn b/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn index b6c2f46..9c1aa88 100644 --- a/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn @@ -26,6 +26,7 @@ static_library("lib") { "DAP.cpp", "DAPError.cpp", "DAPLog.cpp", + "DAPSessionManager.cpp", "EventHelper.cpp", "ExceptionBreakpoint.cpp", "FifoFiles.cpp", diff --git a/llvm/utils/gn/secondary/lldb/tools/lldb-server/BUILD.gn b/llvm/utils/gn/secondary/lldb/tools/lldb-server/BUILD.gn index 6551797..64804c7 100644 --- a/llvm/utils/gn/secondary/lldb/tools/lldb-server/BUILD.gn +++ b/llvm/utils/gn/secondary/lldb/tools/lldb-server/BUILD.gn @@ -6,6 +6,11 @@ tablegen("LLGSOptions") { args = [ "-gen-opt-parser-defs" ] } +tablegen("PlatformOptions") { + visibility = [ ":lldb-server" ] + args = [ "-gen-opt-parser-defs" ] +} + executable("lldb-server") { configs += [ "//llvm/utils/gn/build:clang_code", @@ -13,6 +18,7 @@ executable("lldb-server") { ] deps = [ ":LLGSOptions", + ":PlatformOptions", #"//lldb/include/lldb/Host:Config", "//lldb/source/Host", diff --git a/llvm/utils/gn/secondary/llvm/include/llvm/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/include/llvm/Analysis/BUILD.gn new file mode 100644 index 0000000..3807de7 --- /dev/null +++ b/llvm/utils/gn/secondary/llvm/include/llvm/Analysis/BUILD.gn @@ -0,0 +1,5 @@ +import("//llvm/utils/TableGen/tablegen.gni") + +tablegen("TargetLibraryInfo") { + args = [ "-gen-target-library-info" ] +} diff --git a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn index d6c75b9..9fe4f3e 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn @@ -1,6 +1,9 @@ static_library("Analysis") { output_name = "LLVMAnalysis" public_deps = [ + # Must be a public_dep because Analysis's headers include + # TargetLibraryInfo.inc. + "//llvm/include/llvm/Analysis:TargetLibraryInfo", # Must be a public_dep because Analysis's headers include llvm-config.h. "//llvm/include/llvm/Config:llvm-config", ] @@ -68,7 +71,6 @@ static_library("Analysis") { "InlineAdvisor.cpp", "InlineCost.cpp", "InlineOrder.cpp", - "InlineSizeEstimatorAnalysis.cpp", "InstCount.cpp", "InstructionPrecedenceTracking.cpp", "InstructionSimplify.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn index eb41df2..dedac7b 100644 --- a/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn @@ -27,6 +27,7 @@ static_library("CodeGen") { "Analysis.cpp", "AssignmentTrackingAnalysis.cpp", "AtomicExpandPass.cpp", + "BasicBlockMatchingAndInference.cpp", "BasicBlockPathCloning.cpp", "BasicBlockSections.cpp", "BasicBlockSectionsProfileReader.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn index d8dfcbd..854aa29 100644 --- a/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn @@ -32,6 +32,7 @@ static_library("JITLink") { "ELF_loongarch.cpp", "ELF_ppc64.cpp", "ELF_riscv.cpp", + "ELF_systemz.cpp", "ELF_x86.cpp", "ELF_x86_64.cpp", "JITLink.cpp", @@ -49,6 +50,7 @@ static_library("JITLink") { "loongarch.cpp", "ppc64.cpp", "riscv.cpp", + "systemz.cpp", "x86.cpp", "x86_64.cpp", ] diff --git a/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn index 8438421..106db83 100644 --- a/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn @@ -22,11 +22,9 @@ static_library("Orc") { "CompileOnDemandLayer.cpp", "CompileUtils.cpp", "Core.cpp", - "DebugObjectManagerPlugin.cpp", "DebugUtils.cpp", "EHFrameRegistrationPlugin.cpp", "ELFNixPlatform.cpp", - "EPCDebugObjectRegistrar.cpp", "EPCDynamicLibrarySearchGenerator.cpp", "EPCGenericDylibManager.cpp", "EPCGenericJITLinkMemoryManager.cpp", @@ -35,7 +33,6 @@ static_library("Orc") { "ExecutionUtils.cpp", "ExecutorProcessControl.cpp", "ExecutorResolutionGenerator.cpp", - "GetDylibInterface.cpp", "IRCompileLayer.cpp", "IRPartitionLayer.cpp", "IRTransformLayer.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Debugging/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Debugging/BUILD.gn index 5610679..a054e45 100644 --- a/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Debugging/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Debugging/BUILD.gn @@ -11,6 +11,7 @@ static_library("Debugging") { "DebugInfoSupport.cpp", "DebuggerSupport.cpp", "DebuggerSupportPlugin.cpp", + "ELFDebugObjectPlugin.cpp", "LLJITUtilsCBindings.cpp", "PerfSupportPlugin.cpp", "VTuneSupportPlugin.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn index 22aa0b6..f0afecc 100644 --- a/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn @@ -65,6 +65,7 @@ static_library("IR") { "Metadata.cpp", "Module.cpp", "ModuleSummaryIndex.cpp", + "NVVMIntrinsicUtils.cpp", "Operator.cpp", "OptBisect.cpp", "Pass.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn index df9ddf9..97780c2 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn @@ -97,6 +97,7 @@ static_library("Support") { "FormattedStream.cpp", "GlobPattern.cpp", "GraphWriter.cpp", + "Hash.cpp", "HexagonAttributeParser.cpp", "HexagonAttributes.cpp", "InitLLVM.cpp", @@ -190,6 +191,7 @@ static_library("Support") { "regfree.c", "regstrlcpy.c", "xxhash.cpp", + "zOSLibFunctions.cpp", # System "Atomic.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn index 6d85c7f..f91b071 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn @@ -76,6 +76,7 @@ tablegen("AArch64GenSDNodeInfo") { visibility = [ ":LLVMAArch64CodeGen", "//bolt/unittests/Core:CoreTests", + "//bolt/unittests/Passes:PassTests", "//llvm/unittests/Target/AArch64:AArch64Tests", ] args = [ "-gen-sd-node-info" ] @@ -153,10 +154,12 @@ static_library("LLVMAArch64CodeGen") { "AArch64PostCoalescerPass.cpp", "AArch64PrologueEpilogue.cpp", "AArch64PromoteConstant.cpp", + "AArch64RedundantCondBranchPass.cpp", "AArch64RedundantCopyElimination.cpp", "AArch64RegisterInfo.cpp", "AArch64SIMDInstrOpt.cpp", "AArch64SLSHardening.cpp", + "AArch64SMEAttributes.cpp", "AArch64SelectionDAGInfo.cpp", "AArch64SpeculationHardening.cpp", "AArch64StackTagging.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/Utils/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/Utils/BUILD.gn index 776bf96..af71879 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/Utils/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/Utils/BUILD.gn @@ -20,8 +20,5 @@ static_library("Utils") { # AArch64BaseInfo.h includes a header from MCTargetDesc :-/ include_dirs = [ ".." ] - sources = [ - "AArch64BaseInfo.cpp", - "AArch64SMEAttributes.cpp", - ] + sources = [ "AArch64BaseInfo.cpp" ] } diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn index e47ca1e..d078403 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn @@ -69,9 +69,10 @@ tablegen("AMDGPUGenRegisterBank") { td_file = "AMDGPU.td" } -tablegen("InstCombineTables") { +tablegen("AMDGPUGenSDNodeInfo") { visibility = [ ":LLVMAMDGPUCodeGen" ] - args = [ "-gen-searchable-tables" ] + args = [ "-gen-sd-node-info" ] + td_file = "AMDGPU.td" } tablegen("R600GenCallingConv") { @@ -103,7 +104,7 @@ static_library("LLVMAMDGPUCodeGen") { ":AMDGPUGenPreLegalizeGICombiner", ":AMDGPUGenRegBankGICombiner", ":AMDGPUGenRegisterBank", - ":InstCombineTables", + ":AMDGPUGenSDNodeInfo", ":R600GenCallingConv", ":R600GenDAGISel", ":R600GenDFAPacketizer", @@ -161,6 +162,7 @@ static_library("LLVMAMDGPUCodeGen") { "AMDGPULibCalls.cpp", "AMDGPULibFunc.cpp", "AMDGPULowerBufferFatPointers.cpp", + "AMDGPULowerExecSync.cpp", "AMDGPULowerIntrinsics.cpp", "AMDGPULowerKernelArguments.cpp", "AMDGPULowerKernelAttributes.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn index 84f079a..42c6163 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn @@ -36,6 +36,15 @@ tablegen("ARMGenRegisterBank") { td_file = "ARM.td" } +tablegen("ARMGenSDNodeInfo") { + visibility = [ + ":LLVMARMCodeGen", + "//llvm/unittests/Target/ARM:ARMTests", + ] + args = [ "-gen-sd-node-info" ] + td_file = "ARM.td" +} + static_library("LLVMARMCodeGen") { deps = [ ":ARMGenCallingConv", @@ -44,6 +53,7 @@ static_library("LLVMARMCodeGen") { ":ARMGenGlobalISel", ":ARMGenMCPseudoLowering", ":ARMGenRegisterBank", + ":ARMGenSDNodeInfo", "MCTargetDesc", "TargetInfo", "Utils", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/ARM/Disassembler/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/ARM/Disassembler/BUILD.gn index c08304d..12add51 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/ARM/Disassembler/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/ARM/Disassembler/BUILD.gn @@ -2,10 +2,7 @@ import("//llvm/utils/TableGen/tablegen.gni") tablegen("ARMGenDisassemblerTables") { visibility = [ ":Disassembler" ] - args = [ - "-gen-disassembler", - "-ignore-non-decodable-operands", - ] + args = [ "-gen-disassembler" ] td_file = "../ARM.td" } diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/Hexagon/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/Hexagon/BUILD.gn index 065d33d..b8974dd 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/Hexagon/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/Hexagon/BUILD.gn @@ -61,6 +61,8 @@ static_library("LLVMHexagonCodeGen") { "HexagonGenMemAbsolute.cpp", "HexagonGenMux.cpp", "HexagonGenPredicate.cpp", + "HexagonGenWideningVecFloatInstr.cpp", + "HexagonGenWideningVecInstr.cpp", "HexagonHardwareLoops.cpp", "HexagonHazardRecognizer.cpp", "HexagonISelDAGToDAG.cpp", @@ -77,6 +79,7 @@ static_library("LLVMHexagonCodeGen") { "HexagonMask.cpp", "HexagonNewValueJump.cpp", "HexagonOptAddrMode.cpp", + "HexagonOptShuffleVector.cpp", "HexagonOptimizeSZextends.cpp", "HexagonPeephole.cpp", "HexagonQFPOptimizer.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn index 09a5311..ca76f09 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/LoongArch/BUILD.gn @@ -12,10 +12,17 @@ tablegen("LoongArchGenMCPseudoLowering") { td_file = "LoongArch.td" } +tablegen("LoongArchGenSDNodeInfo") { + visibility = [ ":LLVMLoongArchCodeGen" ] + args = [ "-gen-sd-node-info" ] + td_file = "LoongArch.td" +} + static_library("LLVMLoongArchCodeGen") { deps = [ ":LoongArchGenDAGISel", ":LoongArchGenMCPseudoLowering", + ":LoongArchGenSDNodeInfo", # See https://reviews.llvm.org/D137532 "AsmParser:LoongArchGenAsmMatcher", @@ -45,6 +52,7 @@ static_library("LLVMLoongArchCodeGen") { "LoongArchMergeBaseOffset.cpp", "LoongArchOptWInstrs.cpp", "LoongArchRegisterInfo.cpp", + "LoongArchSelectionDAGInfo.cpp", "LoongArchSubtarget.cpp", "LoongArchTargetMachine.cpp", "LoongArchTargetTransformInfo.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/Mips/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/Mips/BUILD.gn index 9ea8bb4..bac31b2 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/Mips/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/Mips/BUILD.gn @@ -45,6 +45,12 @@ tablegen("MipsGenRegisterBank") { td_file = "Mips.td" } +tablegen("MipsGenSDNodeInfo") { + visibility = [ ":LLVMMipsCodeGen" ] + args = [ "-gen-sd-node-info" ] + td_file = "Mips.td" +} + static_library("LLVMMipsCodeGen") { deps = [ ":MipsGenCallingConv", @@ -54,6 +60,7 @@ static_library("LLVMMipsCodeGen") { ":MipsGenMCPseudoLowering", ":MipsGenPostLegalizeGICombiner", ":MipsGenRegisterBank", + ":MipsGenSDNodeInfo", "MCTargetDesc", "TargetInfo", "//llvm/include/llvm/Config:llvm-config", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn index 0ec7016..a6590e8 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn @@ -6,9 +6,16 @@ tablegen("NVPTXGenDAGISel") { td_file = "NVPTX.td" } +tablegen("NVPTXGenSDNodeInfo") { + visibility = [ ":LLVMNVPTXCodeGen" ] + args = [ "-gen-sd-node-info" ] + td_file = "NVPTX.td" +} + static_library("LLVMNVPTXCodeGen") { deps = [ ":NVPTXGenDAGISel", + ":NVPTXGenSDNodeInfo", "MCTargetDesc", "TargetInfo", "//llvm/include/llvm/Config:llvm-config", @@ -37,6 +44,7 @@ static_library("LLVMNVPTXCodeGen") { "NVPTXForwardParams.cpp", "NVPTXFrameLowering.cpp", "NVPTXGenericToNVVM.cpp", + "NVPTXIRPeephole.cpp", "NVPTXISelDAGToDAG.cpp", "NVPTXISelLowering.cpp", "NVPTXImageOptimizer.cpp", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn index 2bce968..c368cfe 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn @@ -30,6 +30,12 @@ tablegen("PPCGenRegisterBank") { td_file = "PPC.td" } +tablegen("PPCGenSDNodeInfo") { + visibility = [ ":LLVMPowerPCCodeGen" ] + args = [ "-gen-sd-node-info" ] + td_file = "PPC.td" +} + static_library("LLVMPowerPCCodeGen") { deps = [ ":PPCGenCallingConv", @@ -37,6 +43,7 @@ static_library("LLVMPowerPCCodeGen") { ":PPCGenFastISel", ":PPCGenGlobalISel", ":PPCGenRegisterBank", + ":PPCGenSDNodeInfo", "AsmParser:PPCGenAsmMatcher", "MCTargetDesc", "TargetInfo", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn index ad72c00..e54797e 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn @@ -165,6 +165,7 @@ static_library("LLVMRISCVCodeGen") { "RISCVVectorMaskDAGMutation.cpp", "RISCVVectorPeephole.cpp", "RISCVZacasABIFix.cpp", + "RISCVZilsdOptimizer.cpp", ] } diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn index a5718e0..f360b01 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/SystemZ/BUILD.gn @@ -12,10 +12,17 @@ tablegen("SystemZGenDAGISel") { td_file = "SystemZ.td" } +tablegen("SystemZGenSDNodeInfo") { + visibility = [ ":LLVMSystemZCodeGen" ] + args = [ "-gen-sd-node-info" ] + td_file = "SystemZ.td" +} + static_library("LLVMSystemZCodeGen") { deps = [ ":SystemZGenCallingConv", ":SystemZGenDAGISel", + ":SystemZGenSDNodeInfo", "MCTargetDesc", "TargetInfo", "//llvm/include/llvm/Config:llvm-config", diff --git a/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn index f22ee4f..2a1348ff 100644 --- a/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn @@ -90,7 +90,6 @@ static_library("LLVMX86CodeGen") { "X86CmovConversion.cpp", "X86CodeGenPassBuilder.cpp", "X86CompressEVEX.cpp", - "X86DiscriminateMemOps.cpp", "X86DomainReassignment.cpp", "X86DynAllocaExpander.cpp", "X86ExpandPseudo.cpp", @@ -110,7 +109,6 @@ static_library("LLVMX86CodeGen") { "X86ISelLoweringCall.cpp", "X86IndirectBranchTracking.cpp", "X86IndirectThunks.cpp", - "X86InsertPrefetch.cpp", "X86InsertWait.cpp", "X86InstCombineIntrinsic.cpp", "X86InstrFMA3Info.cpp", diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn index 0c7affb..5d5d9f0 100644 --- a/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn @@ -48,6 +48,7 @@ executable("llvm-reduce") { "deltas/ReduceRegisterDefs.cpp", "deltas/ReduceRegisterMasks.cpp", "deltas/ReduceRegisterUses.cpp", + "deltas/ReduceSinkDefsToUses.cpp", "deltas/ReduceSpecialGlobals.cpp", "deltas/ReduceTargetFeaturesAttr.cpp", "deltas/ReduceUsingSimplifyCFG.cpp", diff --git a/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn index e40a8ee..61dedc1 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn @@ -32,7 +32,6 @@ unittest("CodeGenTests") { "LexicalScopesTest.cpp", "LowLevelTypeTest.cpp", "MIR2VecTest.cpp", - "MLRegAllocDevelopmentFeatures.cpp", "MachineBasicBlockTest.cpp", "MachineDomTreeUpdaterTest.cpp", "MachineInstrBundleIteratorTest.cpp", diff --git a/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn index 111e4c9..ad9aa44 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn @@ -15,6 +15,8 @@ unittest("OrcJITTests") { "//llvm/lib/Testing/Support", ] sources = [ + "CallSPSViaEPCTest.cpp", + "CallableTraitsHelperTest.cpp", "CoreAPIsTest.cpp", "EPCGenericJITLinkMemoryManagerTest.cpp", "EPCGenericMemoryAccessTest.cpp", diff --git a/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn index 354b03a..9097c10 100644 --- a/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Target/ARM/BUILD.gn @@ -6,6 +6,7 @@ unittest("ARMTests") { "//llvm/lib/MC", "//llvm/lib/Support", "//llvm/lib/Target", + "//llvm/lib/Target/ARM:ARMGenSDNodeInfo", "//llvm/lib/Target/ARM:LLVMARMCodeGen", "//llvm/lib/Target/ARM/MCTargetDesc", "//llvm/lib/Target/ARM/TargetInfo", diff --git a/llvm/utils/gn/secondary/llvm/utils/TableGen/Basic/BUILD.gn b/llvm/utils/gn/secondary/llvm/utils/TableGen/Basic/BUILD.gn index 918132b..45b8950 100644 --- a/llvm/utils/gn/secondary/llvm/utils/TableGen/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/utils/TableGen/Basic/BUILD.gn @@ -15,6 +15,7 @@ source_set("Basic") { "SDNodeProperties.cpp", "TableGen.cpp", "TargetFeaturesEmitter.cpp", + "TargetLibraryInfoEmitter.cpp", "VTEmitter.cpp", ] } diff --git a/llvm/utils/gn/secondary/llvm/utils/TableGen/tablegen.gni b/llvm/utils/gn/secondary/llvm/utils/TableGen/tablegen.gni index 2143364..47f5f4e 100644 --- a/llvm/utils/gn/secondary/llvm/utils/TableGen/tablegen.gni +++ b/llvm/utils/gn/secondary/llvm/utils/TableGen/tablegen.gni @@ -32,7 +32,10 @@ template("tablegen") { config_name = "${target_name}_config" config(config_name) { visibility = [ ":$target_name" ] - include_dirs = [ target_gen_dir ] + include_dirs = [ + target_gen_dir, + root_build_dir, + ] } compiled_action(target_name) { diff --git a/llvm/utils/lit/examples/many-tests/ManyTests.py b/llvm/utils/lit/examples/many-tests/ManyTests.py index 89e818a..ffdbbad 100644 --- a/llvm/utils/lit/examples/many-tests/ManyTests.py +++ b/llvm/utils/lit/examples/many-tests/ManyTests.py @@ -1,4 +1,5 @@ -from lit import Test, TestFormat +from lit import Test +from lit.formats import TestFormat class ManyTests(TestFormat): diff --git a/llvm/utils/lit/lit/DiffUpdater.py b/llvm/utils/lit/lit/DiffUpdater.py index a29c46f..9e75e4b 100644 --- a/llvm/utils/lit/lit/DiffUpdater.py +++ b/llvm/utils/lit/lit/DiffUpdater.py @@ -117,27 +117,32 @@ def get_source_and_target(a, b, test_path, commands): Try to figure out which file is the test output and which is the reference. """ split_target_dir = SplitFileTarget.get_target_dir(commands, test_path) + a_target = None + b_target = None if split_target_dir: a_target = SplitFileTarget.create(a, commands, test_path, split_target_dir) b_target = SplitFileTarget.create(b, commands, test_path, split_target_dir) - if a_target and b_target: - return None - if a_target: + if a_target and not b_target: return b, a_target - if b_target: + if b_target and not a_target: return a, b_target + if not a_target: + a_target = NormalFileTarget(a) + if not b_target: + b_target = NormalFileTarget(b) + expected_suffix = ".expected" if a.endswith(expected_suffix) and not b.endswith(expected_suffix): - return b, NormalFileTarget(a) + return b, a_target if b.endswith(expected_suffix) and not a.endswith(expected_suffix): - return a, NormalFileTarget(b) + return a, b_target tmp_substr = ".tmp" if tmp_substr in a and not tmp_substr in b: - return a, NormalFileTarget(b) + return a, b_target if tmp_substr in b and not tmp_substr in a: - return b, NormalFileTarget(a) + return b, a_target return None diff --git a/llvm/utils/lit/lit/LitConfig.py b/llvm/utils/lit/lit/LitConfig.py index 8cef3c1..71dad85 100644 --- a/llvm/utils/lit/lit/LitConfig.py +++ b/llvm/utils/lit/lit/LitConfig.py @@ -1,6 +1,7 @@ from __future__ import absolute_import import inspect import os +import enum import platform import sys @@ -25,7 +26,7 @@ class LitConfig(object): self, progname, path, - quiet, + diagnostic_level, useValgrind, valgrindLeakCheck, valgrindArgs, @@ -46,7 +47,7 @@ class LitConfig(object): self.progname = progname # The items to add to the PATH environment variable. self.path = [str(p) for p in path] - self.quiet = bool(quiet) + self.diagnostic_level = diagnostic_level self.useValgrind = bool(useValgrind) self.valgrindLeakCheck = bool(valgrindLeakCheck) self.valgrindUserArgs = list(valgrindArgs) @@ -155,8 +156,7 @@ class LitConfig(object): def load_config(self, config, path): """load_config(config, path) - Load a config object from an alternate path.""" - if self.debug: - self.note("load_config from %r" % path) + self.dbg("load_config from %r" % path) config.load_from_path(path, self) return config @@ -209,6 +209,8 @@ class LitConfig(object): return dir def _write_message(self, kind, message): + if not self.diagnostic_level_enabled(kind): + return # Get the file/line where this message was generated. f = inspect.currentframe() # Step out of _write_message, and then out of wrapper. @@ -234,13 +236,21 @@ class LitConfig(object): "unable to find %r parameter, use '--param=%s=VALUE'" % (key, key) ) + def diagnostic_level_enabled(self, kind): + if kind == "debug": + return self.debug + return DiagnosticLevel.create(self.diagnostic_level) >= DiagnosticLevel.create( + kind + ) + + def dbg(self, message): + self._write_message("debug", message) + def note(self, message): - if not self.quiet: - self._write_message("note", message) + self._write_message("note", message) def warning(self, message): - if not self.quiet: - self._write_message("warning", message) + self._write_message("warning", message) self.numWarnings += 1 def error(self, message): @@ -250,3 +260,25 @@ class LitConfig(object): def fatal(self, message): self._write_message("fatal", message) sys.exit(2) + + +@enum.unique +class DiagnosticLevel(enum.IntEnum): + FATAL = 0 + ERROR = 1 + WARNING = 2 + NOTE = 3 + + @classmethod + def create(cls, value): + if value == "fatal": + return cls.FATAL + if value == "error": + return cls.ERROR + if value == "warning": + return cls.WARNING + if value == "note": + return cls.NOTE + raise ValueError( + f"invalid diagnostic level {repr(value)} of type {type(value)}" + ) diff --git a/llvm/utils/lit/lit/LitTestCase.py b/llvm/utils/lit/lit/LitTestCase.py index 566d068..690b7cb 100644 --- a/llvm/utils/lit/lit/LitTestCase.py +++ b/llvm/utils/lit/lit/LitTestCase.py @@ -46,7 +46,7 @@ def load_test_suite(inputs): lit_config = lit.LitConfig.LitConfig( progname="lit", path=[], - quiet=False, + diagnostic_level="note", useValgrind=False, valgrindLeakCheck=False, valgrindArgs=[], diff --git a/llvm/utils/lit/lit/TestRunner.py b/llvm/utils/lit/lit/TestRunner.py index 64148c6..7a233b2 100644 --- a/llvm/utils/lit/lit/TestRunner.py +++ b/llvm/utils/lit/lit/TestRunner.py @@ -21,7 +21,6 @@ from lit.ShCommands import GlobItem, Command import lit.ShUtil as ShUtil import lit.Test as Test import lit.util -from lit.util import to_bytes, to_string, to_unicode from lit.BooleanExpression import BooleanExpression @@ -391,18 +390,14 @@ def executeBuiltinEcho(cmd, shenv): # Some tests have un-redirected echo commands to help debug test failures. # Buffer our output and return it to the caller. is_redirected = True - encode = lambda x: x if stdout == subprocess.PIPE: is_redirected = False stdout = StringIO() elif kIsWindows: - # Reopen stdout in binary mode to avoid CRLF translation. The versions - # of echo we are replacing on Windows all emit plain LF, and the LLVM - # tests now depend on this. - # When we open as binary, however, this also means that we have to write - # 'bytes' objects to stdout instead of 'str' objects. - encode = lit.util.to_bytes - stdout = open(stdout.name, stdout.mode + "b") + # Reopen stdout with `newline=""` to avoid CRLF translation. + # The versions of echo we are replacing on Windows all emit plain LF, + # and the LLVM tests now depend on this. + stdout = open(stdout.name, stdout.mode, encoding="utf-8", newline="") opened_files.append((None, None, stdout, None)) # Implement echo flags. We only support -e and -n, and not yet in @@ -423,16 +418,15 @@ def executeBuiltinEcho(cmd, shenv): if not interpret_escapes: return arg - arg = lit.util.to_bytes(arg) - return arg.decode("unicode_escape") + return arg.encode("utf-8").decode("unicode_escape") if args: for arg in args[:-1]: - stdout.write(encode(maybeUnescape(arg))) - stdout.write(encode(" ")) - stdout.write(encode(maybeUnescape(args[-1]))) + stdout.write(maybeUnescape(arg)) + stdout.write(" ") + stdout.write(maybeUnescape(args[-1])) if write_newline: - stdout.write(encode("\n")) + stdout.write("\n") for (name, mode, f, path) in opened_files: f.close() @@ -463,7 +457,7 @@ def executeBuiltinMkdir(cmd, cmd_shenv): exitCode = 0 for dir in args: dir = pathlib.Path(dir) - cwd = pathlib.Path(to_unicode(cmd_shenv.cwd)) + cwd = pathlib.Path(cmd_shenv.cwd) if not dir.is_absolute(): dir = lit.util.abs_path_preserve_drive(cwd / dir) if parent: @@ -508,8 +502,6 @@ def executeBuiltinRm(cmd, cmd_shenv): exitCode = 0 for path in args: cwd = cmd_shenv.cwd - path = to_unicode(path) if kIsWindows else to_bytes(path) - cwd = to_unicode(cwd) if kIsWindows else to_bytes(cwd) if not os.path.isabs(path): path = lit.util.abs_path_preserve_drive(os.path.join(cwd, path)) if force and not os.path.exists(path): @@ -718,10 +710,7 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files): else: # Make sure relative paths are relative to the cwd. redir_filename = os.path.join(cmd_shenv.cwd, name) - redir_filename = ( - to_unicode(redir_filename) if kIsWindows else to_bytes(redir_filename) - ) - fd = open(redir_filename, mode) + fd = open(redir_filename, mode, encoding="utf-8") # Workaround a Win32 and/or subprocess bug when appending. # # FIXME: Actually, this is probably an instance of PR6753. @@ -1083,14 +1072,14 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper): if out is None: out = "" else: - out = to_string(out.decode("utf-8", errors="replace")) + out = out.decode("utf-8", errors="replace") except: out = str(out) try: if err is None: err = "" else: - err = to_string(err.decode("utf-8", errors="replace")) + err = err.decode("utf-8", errors="replace") except: err = str(err) @@ -1226,6 +1215,8 @@ def executeScriptInternal( results = [] timeoutInfo = None shenv = ShellEnvironment(cwd, test.config.environment) + shenv.env["LIT_CURRENT_TESTCASE"] = test.getFullName() + exitCode, timeoutInfo = executeShCmd( cmd, shenv, results, timeout=litConfig.maxIndividualTestTime ) @@ -1282,7 +1273,7 @@ def executeScriptInternal( # Add the command output, if redirected. for (name, path, data) in result.outputFiles: - data = to_string(data.decode("utf-8", errors="replace")) + data = data.decode("utf-8", errors="replace") out += formatOutput(f"redirected output from '{name}'", data, limit=1024) if result.stdout.strip(): out += formatOutput("command stdout", result.stdout) @@ -1338,13 +1329,6 @@ def executeScript(test, litConfig, tmpBase, commands, cwd): script += ".bat" # Write script file - mode = "w" - open_kwargs = {} - if litConfig.isWindows and not isWin32CMDEXE: - mode += "b" # Avoid CRLFs when writing bash scripts. - else: - open_kwargs["encoding"] = "utf-8" - f = open(script, mode, **open_kwargs) if isWin32CMDEXE: for i, ln in enumerate(commands): match = re.fullmatch(kPdbgRegex, ln) @@ -1353,8 +1337,9 @@ def executeScript(test, litConfig, tmpBase, commands, cwd): commands[i] = match.expand( "echo '\\1' > nul && " if command else "echo '\\1' > nul" ) - f.write("@echo on\n") - f.write("\n@if %ERRORLEVEL% NEQ 0 EXIT\n".join(commands)) + with open(script, "w", encoding="utf-8") as f: + f.write("@echo on\n") + f.write("\n@if %ERRORLEVEL% NEQ 0 EXIT\n".join(commands)) else: for i, ln in enumerate(commands): match = re.fullmatch(kPdbgRegex, ln) @@ -1393,8 +1378,6 @@ def executeScript(test, litConfig, tmpBase, commands, cwd): # seen the latter manage to terminate the shell running lit. if command: commands[i] += f" && {{ {command}; }}" - if test.config.pipefail: - f.write(b"set -o pipefail;" if mode == "wb" else "set -o pipefail;") # Manually export any DYLD_* variables used by dyld on macOS because # otherwise they are lost when the shell executable is run, before the @@ -1404,14 +1387,14 @@ def executeScript(test, litConfig, tmpBase, commands, cwd): for k, v in test.config.environment.items() if k.startswith("DYLD_") ) - f.write(bytes(env_str, "utf-8") if mode == "wb" else env_str) - f.write(b"set -x;" if mode == "wb" else "set -x;") - if mode == "wb": - f.write(bytes("{ " + "; } &&\n{ ".join(commands) + "; }", "utf-8")) - else: + + with open(script, "w", encoding="utf-8", newline="") as f: + if test.config.pipefail: + f.write("set -o pipefail;") + f.write(env_str) + f.write("set -x;") f.write("{ " + "; } &&\n{ ".join(commands) + "; }") - f.write(b"\n" if mode == "wb" else "\n") - f.close() + f.write("\n") if isWin32CMDEXE: command = ["cmd", "/c", script] @@ -1425,11 +1408,13 @@ def executeScript(test, litConfig, tmpBase, commands, cwd): # run on clang with no real loss. command = litConfig.valgrindArgs + command + env = dict(test.config.environment) + env["LIT_CURRENT_TESTCASE"] = test.getFullName() try: out, err, exitCode = lit.util.executeCommand( command, cwd=cwd, - env=test.config.environment, + env=env, timeout=litConfig.maxIndividualTestTime, ) return (out, err, exitCode, None) @@ -1445,19 +1430,11 @@ def parseIntegratedTestScriptCommands(source_path, keywords): (line_number, command_type, line). """ - # This code is carefully written to be dual compatible with Python 2.5+ and - # Python 3 without requiring input files to always have valid codings. The - # trick we use is to open the file in binary mode and use the regular - # expression library to find the commands, with it scanning strings in - # Python2 and bytes in Python3. - # - # Once we find a match, we do require each script line to be decodable to - # UTF-8, so we convert the outputs to UTF-8 before returning. This way the - # remaining code can work with "strings" agnostic of the executing Python - # version. + # We use `bytes` for scanning input files to avoid requiring them to always + # have valid codings. keywords_re = re.compile( - to_bytes("(%s)(.*)\n" % ("|".join(re.escape(k) for k in keywords),)) + b"(%s)(.*)\n" % (b"|".join(re.escape(k.encode("utf-8")) for k in keywords),) ) f = open(source_path, "rb") @@ -1466,8 +1443,8 @@ def parseIntegratedTestScriptCommands(source_path, keywords): data = f.read() # Ensure the data ends with a newline. - if not data.endswith(to_bytes("\n")): - data = data + to_bytes("\n") + if not data.endswith(b"\n"): + data = data + b"\n" # Iterate over the matches. line_number = 1 @@ -1476,15 +1453,11 @@ def parseIntegratedTestScriptCommands(source_path, keywords): # Compute the updated line number by counting the intervening # newlines. match_position = match.start() - line_number += data.count( - to_bytes("\n"), last_match_position, match_position - ) + line_number += data.count(b"\n", last_match_position, match_position) last_match_position = match_position # Convert the keyword and line to UTF-8 strings and yield the - # command. Note that we take care to return regular strings in - # Python 2, to avoid other code having to differentiate between the - # str and unicode types. + # command. # # Opening the file in binary mode prevented Windows \r newline # characters from being converted to Unix \n newlines, so manually @@ -1492,8 +1465,8 @@ def parseIntegratedTestScriptCommands(source_path, keywords): keyword, ln = match.groups() yield ( line_number, - to_string(keyword.decode("utf-8")), - to_string(ln.decode("utf-8").rstrip("\r")), + keyword.decode("utf-8"), + ln.decode("utf-8").rstrip("\r"), ) finally: f.close() diff --git a/llvm/utils/lit/lit/TestingConfig.py b/llvm/utils/lit/lit/TestingConfig.py index c250838..e7e545c 100644 --- a/llvm/utils/lit/lit/TestingConfig.py +++ b/llvm/utils/lit/lit/TestingConfig.py @@ -143,8 +143,7 @@ class TestingConfig(object): cfg_globals["__file__"] = path try: exec(compile(data, path, "exec"), cfg_globals, None) - if litConfig.debug: - litConfig.note("... loaded config %r" % path) + litConfig.dbg("... loaded config %r" % path) except SystemExit: e = sys.exc_info()[1] # We allow normal system exit inside a config file to just diff --git a/llvm/utils/lit/lit/builtin_commands/diff.py b/llvm/utils/lit/lit/builtin_commands/diff.py index f2b5869..a32a31d 100644 --- a/llvm/utils/lit/lit/builtin_commands/diff.py +++ b/llvm/utils/lit/lit/builtin_commands/diff.py @@ -8,7 +8,6 @@ import re import sys import util -from util import to_string class DiffFlags: @@ -67,10 +66,9 @@ def compareTwoBinaryFiles(flags, filepaths, filelines): filepaths[1].encode(), n=flags.num_context_lines, ) - diffs = [diff.decode(errors="backslashreplace") for diff in diffs] for diff in diffs: - sys.stdout.write(to_string(diff)) + sys.stdout.write(diff.decode(errors="backslashreplace")) exitCode = 1 return exitCode @@ -117,7 +115,7 @@ def compareTwoTextFiles(flags, filepaths, filelines_bin, encoding): filepaths[1], n=flags.num_context_lines, ): - sys.stdout.write(to_string(diff)) + sys.stdout.write(diff) exitCode = 1 return exitCode diff --git a/llvm/utils/lit/lit/cl_arguments.py b/llvm/utils/lit/lit/cl_arguments.py index 8238bc4..5c2ff4e 100644 --- a/llvm/utils/lit/lit/cl_arguments.py +++ b/llvm/utils/lit/lit/cl_arguments.py @@ -15,6 +15,59 @@ class TestOrder(enum.Enum): SMART = "smart" +@enum.unique +class TestOutputLevel(enum.IntEnum): + OFF = 0 + FAILED = 1 + ALL = 2 + + @classmethod + def create(cls, value): + if value == "off": + return cls.OFF + if value == "failed": + return cls.FAILED + if value == "all": + return cls.ALL + raise ValueError(f"invalid output level {repr(value)} of type {type(value)}") + + +class TestOutputAction(argparse.Action): + def __init__(self, option_strings, dest, **kwargs): + super().__init__(option_strings, dest, nargs=None, **kwargs) + + def __call__(self, parser, namespace, value, option_string=None): + TestOutputAction.setOutputLevel(namespace, self.dest, value) + + @classmethod + def setOutputLevel(cls, namespace, dest, value): + setattr(namespace, dest, value) + if dest == "test_output" and TestOutputLevel.create( + namespace.print_result_after + ) < TestOutputLevel.create(value): + setattr(namespace, "print_result_after", value) + elif dest == "print_result_after" and TestOutputLevel.create( + namespace.test_output + ) > TestOutputLevel.create(value): + setattr(namespace, "test_output", value) + + +class AliasAction(argparse.Action): + def __init__(self, option_strings, dest, nargs=None, **kwargs): + self.expansion = kwargs.pop("alias", None) + if not self.expansion: + raise ValueError("no aliases expansion provided") + super().__init__(option_strings, dest, nargs=0, **kwargs) + + def __call__(self, parser, namespace, value, option_string=None): + for e in self.expansion: + if callable(e): + e(namespace) + else: + dest, val = e + setattr(namespace, dest, val) + + def parse_args(): parser = argparse.ArgumentParser(prog="lit", fromfile_prefix_chars="@") parser.add_argument( @@ -55,41 +108,103 @@ def parse_args(): ) format_group = parser.add_argument_group("Output Format") - # FIXME: I find these names very confusing, although I like the - # functionality. format_group.add_argument( - "-q", "--quiet", help="Suppress no error output", action="store_true" + "--test-output", + help="Control whether the executed commands and their outputs are printed after each test has executed (default off). " + "If --print-result-after is set lower than the level given to --test-output, --print-result-after is raised to match.", + choices=["off", "failed", "all"], + default="off", + action=TestOutputAction, + ) + format_group.add_argument( + "--print-result-after", + help="Control which the executed test names and results are printed after each test has executed (default all). " + "If --test-output is set higher than the level given to --print-result-after, --test-output is lowered to match.", + choices=["off", "failed", "all"], + default="all", + action=TestOutputAction, + ) + format_group.add_argument( + "--diagnostic-level", + help="Control how verbose lit diagnostics should be (default note)", + choices=["error", "warning", "note"], + default="note", + ) + format_group.add_argument( + "--terse-summary", + help="Print the elapsed time and the number of passed tests after all tests have finished (default on)", + action="store_true", + dest="terse_summary", + ) + format_group.add_argument( + "--no-terse-summary", + help="Don't show the elapsed time after all tests have finished, and only show the number of failed tests.", + action="store_false", + dest="terse_summary", + ) + parser.set_defaults(terse_summary=False) + format_group.add_argument( + "-q", + "--quiet", + help="Alias for '--diagnostic-level=error --test-output=off --terse-summary'", + action=AliasAction, + alias=[ + lambda namespace: TestOutputAction.setOutputLevel( + namespace, "print_result_after", "failed" + ), + lambda namespace: TestOutputAction.setOutputLevel( + namespace, "test_output", "off" + ), + ("diagnostic_level", "error"), + ("terse_summary", True), + ], ) format_group.add_argument( "-s", "--succinct", - help="Reduce amount of output." - " Additionally, show a progress bar," - " unless --no-progress-bar is specified.", - action="store_true", + help="Alias for '--progress-bar --print-result-after=failed'", + action=AliasAction, + alias=[ + ("useProgressBar", True), + lambda namespace: TestOutputAction.setOutputLevel( + namespace, "print_result_after", "failed" + ), + ], ) format_group.add_argument( "-v", "--verbose", - dest="showOutput", help="For failed tests, show all output. For example, each command is" " printed before it is executed, so the last printed command is the one" - " that failed.", - action="store_true", + " that failed. Alias for '--test-output=failed'", + action=AliasAction, + alias=[ + lambda namespace: TestOutputAction.setOutputLevel( + namespace, "test_output", "failed" + ), + ], ) format_group.add_argument( "-vv", "--echo-all-commands", - dest="showOutput", help="Deprecated alias for -v.", - action="store_true", + action=AliasAction, + alias=[ + lambda namespace: TestOutputAction.setOutputLevel( + namespace, "test_output", "failed" + ), + ], ) format_group.add_argument( "-a", "--show-all", - dest="showAllOutput", - help="Enable -v, but for all tests not just failed tests.", - action="store_true", + help="Enable -v, but for all tests not just failed tests. Alias for '--test-output=all'", + action=AliasAction, + alias=[ + lambda namespace: TestOutputAction.setOutputLevel( + namespace, "test_output", "all" + ), + ], ) format_group.add_argument( "-r", @@ -106,9 +221,15 @@ def parse_args(): metavar="PATH", ) format_group.add_argument( + "--progress-bar", + dest="useProgressBar", + help="Show curses based progress bar", + action="store_true", + ) + format_group.add_argument( "--no-progress-bar", dest="useProgressBar", - help="Do not use curses based progress bar", + help="Do not use curses based progress bar (default)", action="store_false", ) diff --git a/llvm/utils/lit/lit/discovery.py b/llvm/utils/lit/lit/discovery.py index 2e7f90c..ac06223 100644 --- a/llvm/utils/lit/lit/discovery.py +++ b/llvm/utils/lit/lit/discovery.py @@ -62,8 +62,7 @@ def getTestSuite(item, litConfig, cache): cfgpath = target # We found a test suite, create a new config for it and load it. - if litConfig.debug: - litConfig.note("loading suite config %r" % cfgpath) + litConfig.dbg("loading suite config %r" % cfgpath) cfg = TestingConfig.fromdefaults(litConfig) cfg.load_from_path(cfgpath, litConfig) @@ -115,8 +114,7 @@ def getLocalConfig(ts, path_in_suite, litConfig, cache): # Otherwise, copy the current config and load the local configuration # file into it. config = copy.deepcopy(parent) - if litConfig.debug: - litConfig.note("loading local config %r" % cfgpath) + litConfig.dbg("loading local config %r" % cfgpath) config.load_from_path(cfgpath, litConfig) return config @@ -137,8 +135,7 @@ def getTests(path, litConfig, testSuiteCache, localConfigCache): litConfig.warning("unable to find test suite for %r" % path) return (), () - if litConfig.debug: - litConfig.note("resolved input %r to %r::%r" % (path, ts.name, path_in_suite)) + litConfig.dbg("resolved input %r to %r::%r" % (path, ts.name, path_in_suite)) return ts, getTestsInSuite( ts, diff --git a/llvm/utils/lit/lit/display.py b/llvm/utils/lit/lit/display.py index b565bbc..4dc04d9 100644 --- a/llvm/utils/lit/lit/display.py +++ b/llvm/utils/lit/lit/display.py @@ -2,7 +2,7 @@ import sys def create_display(opts, tests, total_tests, workers): - if opts.quiet: + if opts.print_result_after == "off" and not opts.useProgressBar: return NopDisplay() num_tests = len(tests) @@ -10,7 +10,7 @@ def create_display(opts, tests, total_tests, workers): header = "-- Testing: %d%s tests, %d workers --" % (num_tests, of_total, workers) progress_bar = None - if opts.succinct and opts.useProgressBar: + if opts.useProgressBar: import lit.ProgressBar try: @@ -96,8 +96,8 @@ class Display(object): show_result = ( test.isFailure() - or self.opts.showAllOutput - or (not self.opts.quiet and not self.opts.succinct) + and self.opts.print_result_after == "failed" + or self.opts.print_result_after == "all" ) if show_result: if self.progress_bar: @@ -134,7 +134,9 @@ class Display(object): ) # Show the test failure output, if requested. - if (test.isFailure() and self.opts.showOutput) or self.opts.showAllOutput: + if ( + test.isFailure() and self.opts.test_output == "failed" + ) or self.opts.test_output == "all": if test.isFailure(): print("%s TEST '%s' FAILED %s" % ("*" * 20, test_name, "*" * 20)) out = test.result.output diff --git a/llvm/utils/lit/lit/formats/googletest.py b/llvm/utils/lit/lit/formats/googletest.py index 172cd0b..01820da3 100644 --- a/llvm/utils/lit/lit/formats/googletest.py +++ b/llvm/utils/lit/lit/formats/googletest.py @@ -43,7 +43,7 @@ class GoogleTest(TestFormat): return None return sum( map( - lambda line: lit.util.to_string(line).startswith(" "), + lambda line: line.startswith(b" "), out.splitlines(False), ) ) diff --git a/llvm/utils/lit/lit/llvm/config.py b/llvm/utils/lit/lit/llvm/config.py index 913ba69..28a7ab2 100644 --- a/llvm/utils/lit/lit/llvm/config.py +++ b/llvm/utils/lit/lit/llvm/config.py @@ -53,7 +53,10 @@ class LLVMConfig(object): self.use_lit_shell = True global lit_path_displayed - if not self.lit_config.quiet and lit_path_displayed is False: + if ( + self.lit_config.diagnostic_level_enabled("note") + and lit_path_displayed is False + ): self.lit_config.note("using lit tools: {}".format(path)) lit_path_displayed = True @@ -223,7 +226,7 @@ class LLVMConfig(object): continue # We found it, stop enumerating. - return lit.util.to_string(candidate_path) + return candidate_path except: continue @@ -284,12 +287,23 @@ class LLVMConfig(object): env=self.config.environment, ) stdout, stderr = cmd.communicate() - stdout = lit.util.to_string(stdout) - stderr = lit.util.to_string(stderr) + stdout = stdout.decode("utf-8", errors="replace") + stderr = stderr.decode("utf-8", errors="replace") return (stdout, stderr) except OSError: self.lit_config.fatal("Could not run process %s" % command) + def check_process_success(self, command): + cp = subprocess.run( + command, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + env=self.config.environment, + ) + if cp.returncode == 0: + return True + return False + def feature_config(self, features): # Ask llvm-config about the specified feature. arguments = [x for (x, _) in features] @@ -331,6 +345,25 @@ class LLVMConfig(object): # Ensure the result is an ascii string, across Python2.5+ - Python3. return clang_dir + def clang_has_bounds_safety(self, additional_flags=None): + """ + Return True iff `self.config.clang` supports -fbounds-safety + """ + if not self.config.clang: + return False + if not os.path.exists(self.config.clang): + return False + if additional_flags is None: + additional_flags = [] + # Invoke the clang driver to see if it supports the `-fbounds-safety` + # flag. Only the downstream implementation has this flag so this is + # a simple way to check if the full implementation is available or not. + cmd = [self.config.clang] + additional_flags + cmd += ["-fbounds-safety", "-###"] + if self.check_process_success(cmd): + return True + return False + # On macOS, LSan is only supported on clang versions 5 and higher def get_clang_has_lsan(self, clang, triple): if not clang: @@ -527,7 +560,7 @@ class LLVMConfig(object): if tool: tool = os.path.normpath(tool) - if not self.lit_config.quiet and not quiet: + if not quiet: self.lit_config.note("using {}: {}".format(name, tool)) return tool @@ -637,10 +670,9 @@ class LLVMConfig(object): ("%ms_abi_triple", self.make_msabi_triple(self.config.target_triple)) ) else: - if not self.lit_config.quiet: - self.lit_config.note( - "No default target triple was found, some tests may fail as a result." - ) + self.lit_config.note( + "No default target triple was found, some tests may fail as a result." + ) self.config.substitutions.append(("%itanium_abi_triple", "")) self.config.substitutions.append(("%ms_abi_triple", "")) diff --git a/llvm/utils/lit/lit/main.py b/llvm/utils/lit/lit/main.py index a585cc0..07e809b1 100755 --- a/llvm/utils/lit/lit/main.py +++ b/llvm/utils/lit/lit/main.py @@ -30,7 +30,7 @@ def main(builtin_params={}): lit_config = lit.LitConfig.LitConfig( progname=os.path.basename(sys.argv[0]), path=opts.path, - quiet=opts.quiet, + diagnostic_level=opts.diagnostic_level, useValgrind=opts.useValgrind, valgrindLeakCheck=opts.valgrindLeakCheck, valgrindArgs=opts.valgrindArgs, @@ -332,7 +332,7 @@ def print_results(tests, elapsed, opts): opts.printPathRelativeCWD, ) - print_summary(total_tests, tests_by_code, opts.quiet, elapsed) + print_summary(total_tests, tests_by_code, opts.terse_summary, elapsed) def print_group(tests, code, shown_codes, printPathRelativeCWD): diff --git a/llvm/utils/lit/lit/reports.py b/llvm/utils/lit/lit/reports.py index 1b43ab9..6f8a782 100755 --- a/llvm/utils/lit/lit/reports.py +++ b/llvm/utils/lit/lit/reports.py @@ -29,10 +29,10 @@ class Report(object): fd, _ = tempfile.mkstemp( suffix=ext, prefix=f"{filename}.", dir=os.path.dirname(self.output_file) ) - report_file = os.fdopen(fd, "w") + report_file = os.fdopen(fd, "w", encoding="utf-8") else: # Overwrite if the results already exist. - report_file = open(self.output_file, "w") + report_file = open(self.output_file, "w", encoding="utf-8") with report_file: self._write_results_to_file(tests, elapsed, report_file) diff --git a/llvm/utils/lit/lit/run.py b/llvm/utils/lit/lit/run.py index 55de914..9c54511 100644 --- a/llvm/utils/lit/lit/run.py +++ b/llvm/utils/lit/lit/run.py @@ -7,6 +7,14 @@ import lit.Test import lit.util import lit.worker +# Windows has a limit of 60 workers per pool. +# This is defined in the multiprocessing module implementation. +# See: https://github.com/python/cpython/blob/6bc65c30ff1fd0b581a2c93416496fc720bc442c/Lib/concurrent/futures/process.py#L669-L672 +WINDOWS_MAX_WORKERS_PER_POOL = 60 + + +def _ceilDiv(a, b): + return (a + b - 1) // b class MaxFailuresError(Exception): pass @@ -72,25 +80,65 @@ class Run(object): if v is not None } - pool = multiprocessing.Pool( - self.workers, lit.worker.initialize, (self.lit_config, semaphores) + # Windows has a limit of 60 workers per pool, so we need to use multiple pools + # if we have more workers requested than the limit. + # Also, allow to override the limit with the LIT_WINDOWS_MAX_WORKERS_PER_POOL environment variable. + max_workers_per_pool = ( + WINDOWS_MAX_WORKERS_PER_POOL if os.name == "nt" else self.workers + ) + max_workers_per_pool = int( + os.getenv("LIT_WINDOWS_MAX_WORKERS_PER_POOL", max_workers_per_pool) ) - async_results = [ - pool.apply_async( - lit.worker.execute, args=[test], callback=self.progress_callback + num_pools = max(1, _ceilDiv(self.workers, max_workers_per_pool)) + + # Distribute self.workers across num_pools as evenly as possible + workers_per_pool_list = [self.workers // num_pools] * num_pools + for pool_idx in range(self.workers % num_pools): + workers_per_pool_list[pool_idx] += 1 + + if num_pools > 1: + self.lit_config.note( + "Using %d pools balancing %d workers total distributed as %s (Windows worker limit workaround)" + % (num_pools, self.workers, workers_per_pool_list) ) - for test in self.tests - ] - pool.close() + + # Create multiple pools + pools = [] + for pool_size in workers_per_pool_list: + pool = multiprocessing.Pool( + pool_size, lit.worker.initialize, (self.lit_config, semaphores) + ) + pools.append(pool) + + # Distribute tests across pools + tests_per_pool = _ceilDiv(len(self.tests), num_pools) + async_results = [] + + for pool_idx, pool in enumerate(pools): + start_idx = pool_idx * tests_per_pool + end_idx = min(start_idx + tests_per_pool, len(self.tests)) + for test in self.tests[start_idx:end_idx]: + ar = pool.apply_async( + lit.worker.execute, args=[test], callback=self.progress_callback + ) + async_results.append(ar) + + # Close all pools + for pool in pools: + pool.close() try: self._wait_for(async_results, deadline) except: - pool.terminate() + # Terminate all pools on exception + for pool in pools: + pool.terminate() raise finally: - pool.join() + # Join all pools + for pool in pools: + pool.join() def _wait_for(self, async_results, deadline): timeout = deadline - time.time() @@ -137,10 +185,11 @@ class Run(object): "Raised process limit from %d to %d" % (soft_limit, desired_limit) ) except Exception as ex: - # Warn, unless this is Windows, z/OS, or Cygwin in which case this is expected. + # Warn, unless this is Windows, z/OS, Solaris or Cygwin in which case this is expected. if ( os.name != "nt" and platform.system() != "OS/390" + and platform.system() != "SunOS" and platform.sys.platform != "cygwin" ): self.lit_config.warning("Failed to raise process limit: %s" % ex) diff --git a/llvm/utils/lit/lit/util.py b/llvm/utils/lit/lit/util.py index e4e031b..a800f1f 100644 --- a/llvm/utils/lit/lit/util.py +++ b/llvm/utils/lit/lit/util.py @@ -33,76 +33,6 @@ def make_word_regex(word): return r"\b" + word + r"\b" -def to_bytes(s): - """Return the parameter as type 'bytes', possibly encoding it. - - In Python2, the 'bytes' type is the same as 'str'. In Python3, they - are distinct. - - """ - if isinstance(s, bytes): - # In Python2, this branch is taken for both 'str' and 'bytes'. - # In Python3, this branch is taken only for 'bytes'. - return s - # In Python2, 's' is a 'unicode' object. - # In Python3, 's' is a 'str' object. - # Encode to UTF-8 to get 'bytes' data. - return s.encode("utf-8") - - -def to_string(b): - """Return the parameter as type 'str', possibly encoding it. - - In Python2, the 'str' type is the same as 'bytes'. In Python3, the - 'str' type is (essentially) Python2's 'unicode' type, and 'bytes' is - distinct. - - """ - if isinstance(b, str): - # In Python2, this branch is taken for types 'str' and 'bytes'. - # In Python3, this branch is taken only for 'str'. - return b - if isinstance(b, bytes): - # In Python2, this branch is never taken ('bytes' is handled as 'str'). - # In Python3, this is true only for 'bytes'. - try: - return b.decode("utf-8") - except UnicodeDecodeError: - # If the value is not valid Unicode, return the default - # repr-line encoding. - return str(b) - - # By this point, here's what we *don't* have: - # - # - In Python2: - # - 'str' or 'bytes' (1st branch above) - # - In Python3: - # - 'str' (1st branch above) - # - 'bytes' (2nd branch above) - # - # The last type we might expect is the Python2 'unicode' type. There is no - # 'unicode' type in Python3 (all the Python3 cases were already handled). In - # order to get a 'str' object, we need to encode the 'unicode' object. - try: - return b.encode("utf-8") - except AttributeError: - raise TypeError("not sure how to convert %s to %s" % (type(b), str)) - - -def to_unicode(s): - """Return the parameter as type which supports unicode, possibly decoding - it. - - In Python2, this is the unicode type. In Python3 it's the str type. - - """ - if isinstance(s, bytes): - # In Python2, this branch is taken for both 'str' and 'bytes'. - # In Python3, this branch is taken only for 'bytes'. - return s.decode("utf-8") - return s - - def usable_core_count(): """Return the number of cores the current process can use, if supported. Otherwise, return the total number of cores (like `os.cpu_count()`). @@ -114,11 +44,6 @@ def usable_core_count(): except AttributeError: n = os.cpu_count() or 1 - # On Windows with more than 60 processes, multiprocessing's call to - # _winapi.WaitForMultipleObjects() prints an error and lit hangs. - if platform.system() == "Windows": - return min(n, 60) - return n def abs_path_preserve_drive(path): @@ -341,7 +266,7 @@ def executeCommand( """ if input is not None: - input = to_bytes(input) + input = input.encode("utf-8") err_out = subprocess.STDOUT if redirect_stderr else subprocess.PIPE p = subprocess.Popen( command, @@ -377,8 +302,8 @@ def executeCommand( timerObject.cancel() # Ensure the resulting output is always of string type. - out = to_string(out) - err = "" if redirect_stderr else to_string(err) + out = out.decode("utf-8", errors="replace") + err = "" if redirect_stderr else err.decode("utf-8", errors="replace") if hitTimeOut[0]: raise ExecuteCommandTimeoutException( diff --git a/llvm/utils/lit/tests/Inputs/diff-test-update/.gitignore b/llvm/utils/lit/tests/Inputs/diff-test-update/.gitignore index aea8ee3..5a7c177 100644 --- a/llvm/utils/lit/tests/Inputs/diff-test-update/.gitignore +++ b/llvm/utils/lit/tests/Inputs/diff-test-update/.gitignore @@ -8,3 +8,4 @@ multiple-split-file-populated.test single-split-file-no-expected.test split-c-comments.test split whitespace.test +split-both.test diff --git a/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.test b/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.in index f564f44..df767f7 100644 --- a/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.test +++ b/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.in @@ -1,9 +1,7 @@ # RUN: split-file %s %t +# RUN: echo baz > %t/split-both.out # RUN: diff %t/split-both.expected %t/split-both.out -# ignore the fact that it's called ".expected" -# when comparing two files originating in split-file - #--- split-both.expected FOO #--- split-both.out diff --git a/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.out b/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.out new file mode 100644 index 0000000..a2f74d4 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/diff-test-update/split-both.out @@ -0,0 +1,9 @@ +# RUN: split-file %s %t +# RUN: echo baz > %t/split-both.out +# RUN: diff %t/split-both.expected %t/split-both.out + +#--- split-both.expected +baz +#--- split-both.out +BAR + diff --git a/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-current-testcase.txt b/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-current-testcase.txt new file mode 100644 index 0000000..37c3681 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-current-testcase.txt @@ -0,0 +1,6 @@ +## Tests that the LIT_CURRENT_TESTCASE variable is set to the name of the currently executing testcase + +## Check default environment. +# RUN: bash -c 'echo $LIT_CURRENT_TESTCASE' | FileCheck --match-full-lines %s +# +# CHECK: shtest-env :: env-current-testcase.txt diff --git a/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-no-subcommand.txt b/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-no-subcommand.txt index 761a806..dded906 100644 --- a/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-no-subcommand.txt +++ b/llvm/utils/lit/tests/Inputs/shtest-env-positive/env-no-subcommand.txt @@ -1,4 +1,5 @@ ## Tests the env command in various scenarios: without arguments, setting, unsetting, and mixing envrionment variables. +# FIXME: All of these tests are broken and will not even call FileCheck. ## Check default environment. # RUN: env | FileCheck -check-prefix=NO-ARGS %s diff --git a/llvm/utils/lit/tests/Inputs/verbosity/fail.txt b/llvm/utils/lit/tests/Inputs/verbosity/fail.txt new file mode 100644 index 0000000..2bcca02 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/verbosity/fail.txt @@ -0,0 +1,2 @@ +RUN: echo "fail test output" +RUN: fail
\ No newline at end of file diff --git a/llvm/utils/lit/tests/Inputs/verbosity/lit.cfg b/llvm/utils/lit/tests/Inputs/verbosity/lit.cfg new file mode 100644 index 0000000..c3a1f4f --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/verbosity/lit.cfg @@ -0,0 +1,11 @@ +import lit.formats + +config.name = "verbosity" +config.suffixes = [".txt"] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None + +lit_config.dbg("this is a debug log") +lit_config.note("this is a note") +lit_config.warning("this is a warning") diff --git a/llvm/utils/lit/tests/Inputs/verbosity/pass.txt b/llvm/utils/lit/tests/Inputs/verbosity/pass.txt new file mode 100644 index 0000000..f648438 --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/verbosity/pass.txt @@ -0,0 +1 @@ +RUN: echo "pass test output"
\ No newline at end of file diff --git a/llvm/utils/lit/tests/Inputs/verbosity/unsupported.txt b/llvm/utils/lit/tests/Inputs/verbosity/unsupported.txt new file mode 100644 index 0000000..f5ebd4d --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/verbosity/unsupported.txt @@ -0,0 +1,2 @@ +REQUIRES: asdf +RUN: not echo "unsupported test output" diff --git a/llvm/utils/lit/tests/Inputs/verbosity/xfail.txt b/llvm/utils/lit/tests/Inputs/verbosity/xfail.txt new file mode 100644 index 0000000..85001cc --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/verbosity/xfail.txt @@ -0,0 +1,2 @@ +XFAIL: * +RUN: not echo "xfail test output"
\ No newline at end of file diff --git a/llvm/utils/lit/tests/Inputs/verbosity/xpass.txt b/llvm/utils/lit/tests/Inputs/verbosity/xpass.txt new file mode 100644 index 0000000..87c95ec --- /dev/null +++ b/llvm/utils/lit/tests/Inputs/verbosity/xpass.txt @@ -0,0 +1,2 @@ +XFAIL: * +RUN: echo "xpass test output" diff --git a/llvm/utils/lit/tests/diff-test-update.py b/llvm/utils/lit/tests/diff-test-update.py index 8b9f461..e23d387 100644 --- a/llvm/utils/lit/tests/diff-test-update.py +++ b/llvm/utils/lit/tests/diff-test-update.py @@ -5,6 +5,7 @@ # RUN: cp %S/Inputs/diff-test-update/single-split-file-no-expected.in %S/Inputs/diff-test-update/single-split-file-no-expected.test # RUN: cp %S/Inputs/diff-test-update/split-c-comments.in %S/Inputs/diff-test-update/split-c-comments.test # RUN: cp %S/Inputs/diff-test-update/split-whitespace.in "%S/Inputs/diff-test-update/split whitespace.test" +# RUN: cp %S/Inputs/diff-test-update/split-both.in %S/Inputs/diff-test-update/split-both.test # RUN: not %{lit} --update-tests -v %S/Inputs/diff-test-update | FileCheck %s @@ -15,6 +16,7 @@ # RUN: diff --strip-trailing-cr %S/Inputs/diff-test-update/single-split-file-no-expected.out %S/Inputs/diff-test-update/single-split-file-no-expected.test # RUN: diff --strip-trailing-cr %S/Inputs/diff-test-update/split-c-comments.out %S/Inputs/diff-test-update/split-c-comments.test # RUN: diff --strip-trailing-cr %S/Inputs/diff-test-update/split-whitespace.out "%S/Inputs/diff-test-update/split whitespace.test" +# RUN: diff --strip-trailing-cr %S/Inputs/diff-test-update/split-both.out %S/Inputs/diff-test-update/split-both.test # CHECK: # update-diff-test: could not deduce source and target from {{.*}}1.in and {{.*}}2.in @@ -22,7 +24,6 @@ # CHECK: # update-diff-test: copied {{.*}}my-file.txt to {{.*}}my-file.expected # CHECK: # update-diff-test: copied {{.*}}1.txt to {{.*}}empty.txt # CHECK: # update-diff-test: copied {{.*}}diff-tmp.test.tmp.txt to {{.*}}diff-t-out.txt -# CHECK: # update-diff-test: could not deduce source and target from {{.*}}split-both.expected and {{.*}}split-both.out # CHECK: # update-diff-test: copied {{.*}}unrelated-split.txt to {{.*}}unrelated-split.expected diff --git a/llvm/utils/lit/tests/lit-opts.py b/llvm/utils/lit/tests/lit-opts.py index a533a59..0759c1d 100644 --- a/llvm/utils/lit/tests/lit-opts.py +++ b/llvm/utils/lit/tests/lit-opts.py @@ -12,13 +12,13 @@ # Check that LIT_OPTS understands multiple options with arbitrary spacing. # -# RUN: env LIT_OPTS='-a -v -Dvar=foobar' \ +# RUN: env LIT_OPTS='-v -a -Dvar=foobar' \ # RUN: %{lit} -s %{inputs}/lit-opts \ # RUN: | FileCheck -check-prefix=SHOW-ALL -DVAR=foobar %s # Check that LIT_OPTS parses shell-like quotes and escapes. # -# RUN: env LIT_OPTS='-a -v -Dvar="foo bar"\ baz' \ +# RUN: env LIT_OPTS='-v -a -Dvar="foo bar"\ baz' \ # RUN: %{lit} -s %{inputs}/lit-opts \ # RUN: | FileCheck -check-prefix=SHOW-ALL -DVAR="foo bar baz" %s diff --git a/llvm/utils/lit/tests/lit.cfg b/llvm/utils/lit/tests/lit.cfg index 1382f7e..922fbd6 100644 --- a/llvm/utils/lit/tests/lit.cfg +++ b/llvm/utils/lit/tests/lit.cfg @@ -9,6 +9,10 @@ import lit.formats from lit.llvm import llvm_config # Configuration file for the 'lit' test runner. +# Note that lit can be tested in a "standalone" mode, where it is run +# without using the LLVM build directory. +# In this case the llvm_config object is not available, and we expect +# tools like FileCheck to be available in the PATH. # name: The name of this test suite. config.name = "lit" diff --git a/llvm/utils/lit/tests/per-test-coverage-by-lit-cfg.py b/llvm/utils/lit/tests/per-test-coverage-by-lit-cfg.py index 189c1ce..b3af606 100644 --- a/llvm/utils/lit/tests/per-test-coverage-by-lit-cfg.py +++ b/llvm/utils/lit/tests/per-test-coverage-by-lit-cfg.py @@ -1,10 +1,10 @@ # Test if lit_config.per_test_coverage in lit.cfg sets individual test case coverage. -# RUN: %{lit} -a -vv -Dexecute_external=False \ +# RUN: %{lit} -a -Dexecute_external=False \ # RUN: %{inputs}/per-test-coverage-by-lit-cfg/per-test-coverage-by-lit-cfg.py | \ # RUN: FileCheck -DOUT=stdout %s -# RUN: %{lit} -a -vv -Dexecute_external=True \ +# RUN: %{lit} -a -Dexecute_external=True \ # RUN: %{inputs}/per-test-coverage-by-lit-cfg/per-test-coverage-by-lit-cfg.py | \ # RUN: FileCheck -DOUT=stderr %s diff --git a/llvm/utils/lit/tests/per-test-coverage.py b/llvm/utils/lit/tests/per-test-coverage.py index cf5e82c..ba51355 100644 --- a/llvm/utils/lit/tests/per-test-coverage.py +++ b/llvm/utils/lit/tests/per-test-coverage.py @@ -1,10 +1,10 @@ # Test LLVM_PROFILE_FILE is set when --per-test-coverage is passed to command line. -# RUN: %{lit} -a -vv --per-test-coverage -Dexecute_external=False \ +# RUN: %{lit} -a --per-test-coverage -Dexecute_external=False \ # RUN: %{inputs}/per-test-coverage/per-test-coverage.py | \ # RUN: FileCheck -DOUT=stdout %s -# RUN: %{lit} -a -vv --per-test-coverage -Dexecute_external=True \ +# RUN: %{lit} -a --per-test-coverage -Dexecute_external=True \ # RUN: %{inputs}/per-test-coverage/per-test-coverage.py | \ # RUN: FileCheck -DOUT=stderr %s diff --git a/llvm/utils/lit/tests/shtest-cat.py b/llvm/utils/lit/tests/shtest-cat.py index 5efe25c4..9763f9f 100644 --- a/llvm/utils/lit/tests/shtest-cat.py +++ b/llvm/utils/lit/tests/shtest-cat.py @@ -1,6 +1,6 @@ ## Test the cat command. # -# RUN: not %{lit} -a -v %{inputs}/shtest-cat \ +# RUN: not %{lit} -v %{inputs}/shtest-cat \ # RUN: | FileCheck -match-full-lines %s # END. diff --git a/llvm/utils/lit/tests/shtest-env-negative.py b/llvm/utils/lit/tests/shtest-env-negative.py index c8b59b2..236c6a1 100644 --- a/llvm/utils/lit/tests/shtest-env-negative.py +++ b/llvm/utils/lit/tests/shtest-env-negative.py @@ -1,6 +1,6 @@ ## Test the env command (failing tests). -# RUN: not %{lit} -a -v %{inputs}/shtest-env-negative \ +# RUN: not %{lit} -v %{inputs}/shtest-env-negative \ # RUN: | FileCheck -match-full-lines %s # # END. diff --git a/llvm/utils/lit/tests/shtest-env-path.py b/llvm/utils/lit/tests/shtest-env-path.py index bf459ae..7f04756 100644 --- a/llvm/utils/lit/tests/shtest-env-path.py +++ b/llvm/utils/lit/tests/shtest-env-path.py @@ -1,9 +1,9 @@ ## Tests env command for setting the PATH variable. # The test is using /bin/sh. Limit to system known to have /bin/sh. -# REQUIRES: system-linux +# REQUIRES: system-linux || system-darwin -# RUN: %{lit} -a -v %{inputs}/shtest-env-path/path.txt \ +# RUN: %{lit} -a %{inputs}/shtest-env-path/path.txt \ # RUN: | FileCheck -match-full-lines %s # # END. diff --git a/llvm/utils/lit/tests/shtest-env-positive.py b/llvm/utils/lit/tests/shtest-env-positive.py index 4f07b69..62e15dd 100644 --- a/llvm/utils/lit/tests/shtest-env-positive.py +++ b/llvm/utils/lit/tests/shtest-env-positive.py @@ -1,13 +1,13 @@ ## Test the env command (passing tests). -# RUN: %{lit} -a -v %{inputs}/shtest-env-positive \ +# RUN: %{lit} -a %{inputs}/shtest-env-positive \ # RUN: | FileCheck -match-full-lines %s # # END. ## Test the env command's successful executions. -# CHECK: -- Testing: 10 tests{{.*}} +# CHECK: -- Testing: 11 tests{{.*}} # CHECK: PASS: shtest-env :: env-args-last-is-assign.txt ({{[^)]*}}) # CHECK: env FOO=1 @@ -39,6 +39,11 @@ # CHECK-NOT: # error: # CHECK: -- +# CHECK: PASS: shtest-env :: env-current-testcase.txt ({{[^)]*}}) +# CHECK: # executed command: bash -c 'echo $LIT_CURRENT_TESTCASE' +# CHECK-NOT: # error: +# CHECK: -- + # CHECK: PASS: shtest-env :: env-i.txt ({{[^)]*}}) # CHECK: env -i | {{.*}} # CHECK: # executed command: env -i @@ -71,6 +76,6 @@ # CHECK-NOT: # error: # CHECK: -- -# CHECK: Total Discovered Tests: 10 -# CHECK: Passed: 10 {{\([0-9]*\.[0-9]*%\)}} +# CHECK: Total Discovered Tests: 11 +# CHECK: Passed: 11 {{\([0-9]*\.[0-9]*%\)}} # CHECK-NOT: {{.}} diff --git a/llvm/utils/lit/tests/shtest-export.py b/llvm/utils/lit/tests/shtest-export.py index f2de8e8..d45a94a 100644 --- a/llvm/utils/lit/tests/shtest-export.py +++ b/llvm/utils/lit/tests/shtest-export.py @@ -1,6 +1,6 @@ ## Test the export command. -# RUN: not %{lit} -a -v %{inputs}/shtest-export \ +# RUN: not %{lit} -v %{inputs}/shtest-export \ # RUN: | FileCheck -match-full-lines %s # # END. diff --git a/llvm/utils/lit/tests/shtest-glob.py b/llvm/utils/lit/tests/shtest-glob.py index aa4705b..ba609e0 100644 --- a/llvm/utils/lit/tests/shtest-glob.py +++ b/llvm/utils/lit/tests/shtest-glob.py @@ -1,6 +1,6 @@ ## Tests glob pattern handling in echo command. -# RUN: not %{lit} -a -v %{inputs}/shtest-glob \ +# RUN: not %{lit} -v %{inputs}/shtest-glob \ # RUN: | FileCheck -dump-input=fail -match-full-lines --implicit-check-not=Error: %s # END. diff --git a/llvm/utils/lit/tests/shtest-not.py b/llvm/utils/lit/tests/shtest-not.py index b42769f..e735d38 100644 --- a/llvm/utils/lit/tests/shtest-not.py +++ b/llvm/utils/lit/tests/shtest-not.py @@ -1,6 +1,6 @@ # Check the not command -# RUN: not %{lit} -a -v %{inputs}/shtest-not \ +# RUN: not %{lit} -a %{inputs}/shtest-not \ # RUN: | FileCheck -match-full-lines %s # # END. diff --git a/llvm/utils/lit/tests/shtest-pushd-popd.py b/llvm/utils/lit/tests/shtest-pushd-popd.py index f917c1a..799e9d6 100644 --- a/llvm/utils/lit/tests/shtest-pushd-popd.py +++ b/llvm/utils/lit/tests/shtest-pushd-popd.py @@ -1,6 +1,6 @@ # Check the pushd and popd commands -# RUN: not %{lit} -a -v %{inputs}/shtest-pushd-popd \ +# RUN: not %{lit} -v %{inputs}/shtest-pushd-popd \ # RUN: | FileCheck -match-full-lines %s # # END. diff --git a/llvm/utils/lit/tests/shtest-readfile-external.py b/llvm/utils/lit/tests/shtest-readfile-external.py index 6fe1088..0d8e3ad 100644 --- a/llvm/utils/lit/tests/shtest-readfile-external.py +++ b/llvm/utils/lit/tests/shtest-readfile-external.py @@ -4,7 +4,7 @@ # ALLOW_RETRIES: 2 # UNSUPPORTED: system-windows -# RUN: env LIT_USE_INTERNAL_SHELL=0 not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S/Inputs/shtest-readfile/Output %s +# RUN: env LIT_USE_INTERNAL_SHELL=0 not %{lit} -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S/Inputs/shtest-readfile/Output %s # CHECK: -- Testing: 5 tests{{.*}} diff --git a/llvm/utils/lit/tests/shtest-readfile.py b/llvm/utils/lit/tests/shtest-readfile.py index 218da22..ca57db8 100644 --- a/llvm/utils/lit/tests/shtest-readfile.py +++ b/llvm/utils/lit/tests/shtest-readfile.py @@ -3,7 +3,7 @@ # TODO(boomanaiden154): This sometimes fails, possibly due to buffers not being flushed. # ALLOW_RETRIES: 2 -# RUN: env LIT_USE_INTERNAL_SHELL=1 not %{lit} -a -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S%{fs-sep}Inputs%{fs-sep}shtest-readfile%{fs-sep}Output %s +# RUN: env LIT_USE_INTERNAL_SHELL=1 not %{lit} -v %{inputs}/shtest-readfile | FileCheck -match-full-lines -DTEMP_PATH=%S%{fs-sep}Inputs%{fs-sep}shtest-readfile%{fs-sep}Output %s # CHECK: -- Testing: 5 tests{{.*}} diff --git a/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py b/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py index d81cde0..d5340a7 100644 --- a/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py +++ b/llvm/utils/lit/tests/shtest-ulimit-nondarwin.py @@ -4,7 +4,7 @@ # These tests are specific to options that Darwin does not support. # UNSUPPORTED: system-windows, system-cygwin, system-darwin, system-aix, system-solaris -# RUN: not %{lit} -a -v %{inputs}/shtest-ulimit-nondarwin | FileCheck %s +# RUN: not %{lit} -v %{inputs}/shtest-ulimit-nondarwin | FileCheck %s # CHECK: -- Testing: 2 tests{{.*}} diff --git a/llvm/utils/lit/tests/shtest-ulimit.py b/llvm/utils/lit/tests/shtest-ulimit.py index 21e5a5e..582477b 100644 --- a/llvm/utils/lit/tests/shtest-ulimit.py +++ b/llvm/utils/lit/tests/shtest-ulimit.py @@ -8,7 +8,7 @@ # RUN: %{python} %S/Inputs/shtest-ulimit/print_limits.py | grep RLIMIT_NOFILE \ # RUN: | sed -n -e 's/.*=//p' | tr -d '\n' > %t.nofile_limit -# RUN: not %{lit} -a -v %{inputs}/shtest-ulimit --order=lexical \ +# RUN: not %{lit} -v %{inputs}/shtest-ulimit --order=lexical \ # RUN: | FileCheck -DBASE_NOFILE_LIMIT=%{readfile:%t.nofile_limit} %s # CHECK: -- Testing: 3 tests{{.*}} diff --git a/llvm/utils/lit/tests/shtest-umask.py b/llvm/utils/lit/tests/shtest-umask.py index e67f030..8af81ec 100644 --- a/llvm/utils/lit/tests/shtest-umask.py +++ b/llvm/utils/lit/tests/shtest-umask.py @@ -1,6 +1,6 @@ # Check the umask command -# RUN: not %{lit} -a -v %{inputs}/shtest-umask | FileCheck -match-full-lines %s +# RUN: not %{lit} -v %{inputs}/shtest-umask | FileCheck -match-full-lines %s # TODO(boomanaiden154): We should be asserting that we get expected behavior # on Windows rather than just listing this as unsupported. # UNSUPPORTED: system-windows diff --git a/llvm/utils/lit/tests/unit/TestRunner.py b/llvm/utils/lit/tests/unit/TestRunner.py index 09470c7..a3fa62e 100644 --- a/llvm/utils/lit/tests/unit/TestRunner.py +++ b/llvm/utils/lit/tests/unit/TestRunner.py @@ -30,7 +30,7 @@ class TestIntegratedTestKeywordParser(unittest.TestCase): lit_config = lit.LitConfig.LitConfig( progname="lit", path=[], - quiet=False, + diagnostic_level="note", useValgrind=False, valgrindLeakCheck=False, valgrindArgs=[], diff --git a/llvm/utils/lit/tests/verbosity.py b/llvm/utils/lit/tests/verbosity.py new file mode 100644 index 0000000..62baf61 --- /dev/null +++ b/llvm/utils/lit/tests/verbosity.py @@ -0,0 +1,1130 @@ +# Test various combinations of options controlling lit stdout and stderr output + +# RUN: mkdir -p %t + +### Test default + +# RUN: not %{lit} %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# NO-ARGS: -- Testing: 5 tests, 1 workers -- +# NO-ARGS-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# NO-ARGS-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# NO-ARGS-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# NO-ARGS-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# NO-ARGS-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# NO-ARGS-NEXT: ******************** +# NO-ARGS-NEXT: Failed Tests (1): +# NO-ARGS-NEXT: verbosity :: fail.txt +# NO-ARGS-EMPTY: +# NO-ARGS-NEXT: ******************** +# NO-ARGS-NEXT: Unexpectedly Passed Tests (1): +# NO-ARGS-NEXT: verbosity :: xpass.txt +# NO-ARGS-EMPTY: +# NO-ARGS-EMPTY: +# NO-ARGS-NEXT: Testing Time: {{.*}}s +# NO-ARGS-EMPTY: +# NO-ARGS-NEXT: Total Discovered Tests: 5 +# NO-ARGS-NEXT: Unsupported : 1 (20.00%) +# NO-ARGS-NEXT: Passed : 1 (20.00%) +# NO-ARGS-NEXT: Expectedly Failed : 1 (20.00%) +# NO-ARGS-NEXT: Failed : 1 (20.00%) +# NO-ARGS-NEXT: Unexpectedly Passed: 1 (20.00%) + +# NO-ARGS-ERR: lit.py: {{.*}}lit.cfg:{{[0-9]+}}: note: this is a note +# NO-ARGS-ERR-NEXT: lit.py: {{.*}}lit.cfg:{{[0-9]+}}: warning: this is a warning +# NO-ARGS-ERR-EMPTY: +# NO-ARGS-ERR-NEXT: 1 warning(s) in tests + + +### Test aliases + +# RUN: not %{lit} --succinct %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SUCCINCT < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# SUCCINCT: -- Testing: 5 tests, 1 workers -- +# SUCCINCT-NEXT: Testing: +# SUCCINCT-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# SUCCINCT-NEXT: Testing: +# SUCCINCT-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# SUCCINCT-NEXT: Testing: +# SUCCINCT-NEXT: ******************** +# SUCCINCT-NEXT: Failed Tests (1): +# SUCCINCT-NEXT: verbosity :: fail.txt +# SUCCINCT-EMPTY: +# SUCCINCT-NEXT: ******************** +# SUCCINCT-NEXT: Unexpectedly Passed Tests (1): +# SUCCINCT-NEXT: verbosity :: xpass.txt +# SUCCINCT-EMPTY: +# SUCCINCT-EMPTY: +# SUCCINCT-NEXT: Testing Time: {{.*}}s +# SUCCINCT-EMPTY: +# SUCCINCT-NEXT: Total Discovered Tests: 5 +# SUCCINCT-NEXT: Unsupported : 1 (20.00%) +# SUCCINCT-NEXT: Passed : 1 (20.00%) +# SUCCINCT-NEXT: Expectedly Failed : 1 (20.00%) +# SUCCINCT-NEXT: Failed : 1 (20.00%) +# SUCCINCT-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --verbose %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix VERBOSE < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# VERBOSE: -- Testing: 5 tests, 1 workers -- +# VERBOSE-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# VERBOSE-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# VERBOSE-NEXT: Exit Code: 127 +# VERBOSE-EMPTY: +# VERBOSE-NEXT: Command Output (stdout): +# VERBOSE-NEXT: -- +# VERBOSE-NEXT: # {{R}}UN: at line 1 +# VERBOSE-NEXT: echo "fail test output" +# VERBOSE-NEXT: # executed command: echo 'fail test output' +# VERBOSE-NEXT: # .---command stdout------------ +# VERBOSE-NEXT: # | fail test output +# VERBOSE-NEXT: # `----------------------------- +# VERBOSE-NEXT: # {{R}}UN: at line 2 +# VERBOSE-NEXT: fail +# VERBOSE-NEXT: # executed command: fail +# VERBOSE-NEXT: # .---command stderr------------ +# VERBOSE-NEXT: # | 'fail': command not found +# VERBOSE-NEXT: # `----------------------------- +# VERBOSE-NEXT: # error: command failed with exit status: 127 +# VERBOSE-EMPTY: +# VERBOSE-NEXT: -- +# VERBOSE-EMPTY: +# VERBOSE-NEXT: ******************** +# VERBOSE-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# VERBOSE-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# VERBOSE-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# VERBOSE-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# VERBOSE-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# VERBOSE-NEXT: Exit Code: 0 +# VERBOSE-EMPTY: +# VERBOSE-NEXT: Command Output (stdout): +# VERBOSE-NEXT: -- +# VERBOSE-NEXT: # {{R}}UN: at line 2 +# VERBOSE-NEXT: echo "xpass test output" +# VERBOSE-NEXT: # executed command: echo 'xpass test output' +# VERBOSE-NEXT: # .---command stdout------------ +# VERBOSE-NEXT: # | xpass test output +# VERBOSE-NEXT: # `----------------------------- +# VERBOSE-EMPTY: +# VERBOSE-NEXT: -- +# VERBOSE-EMPTY: +# VERBOSE-NEXT: ******************** +# VERBOSE-NEXT: ******************** +# VERBOSE-NEXT: Failed Tests (1): +# VERBOSE-NEXT: verbosity :: fail.txt +# VERBOSE-EMPTY: +# VERBOSE-NEXT: ******************** +# VERBOSE-NEXT: Unexpectedly Passed Tests (1): +# VERBOSE-NEXT: verbosity :: xpass.txt +# VERBOSE-EMPTY: +# VERBOSE-EMPTY: +# VERBOSE-NEXT: Testing Time: {{.*}}s +# VERBOSE-EMPTY: +# VERBOSE-NEXT: Total Discovered Tests: 5 +# VERBOSE-NEXT: Unsupported : 1 (20.00%) +# VERBOSE-NEXT: Passed : 1 (20.00%) +# VERBOSE-NEXT: Expectedly Failed : 1 (20.00%) +# VERBOSE-NEXT: Failed : 1 (20.00%) +# VERBOSE-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --show-all %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SHOW-ALL < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# SHOW-ALL: -- Testing: 5 tests, 1 workers -- +# SHOW-ALL-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# SHOW-ALL-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# SHOW-ALL-NEXT: Exit Code: 127 +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: Command Output (stdout): +# SHOW-ALL-NEXT: -- +# SHOW-ALL-NEXT: # {{R}}UN: at line 1 +# SHOW-ALL-NEXT: echo "fail test output" +# SHOW-ALL-NEXT: # executed command: echo 'fail test output' +# SHOW-ALL-NEXT: # .---command stdout------------ +# SHOW-ALL-NEXT: # | fail test output +# SHOW-ALL-NEXT: # `----------------------------- +# SHOW-ALL-NEXT: # {{R}}UN: at line 2 +# SHOW-ALL-NEXT: fail +# SHOW-ALL-NEXT: # executed command: fail +# SHOW-ALL-NEXT: # .---command stderr------------ +# SHOW-ALL-NEXT: # | 'fail': command not found +# SHOW-ALL-NEXT: # `----------------------------- +# SHOW-ALL-NEXT: # error: command failed with exit status: 127 +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: -- +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# SHOW-ALL-NEXT: Exit Code: 0 +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: Command Output (stdout): +# SHOW-ALL-NEXT: -- +# SHOW-ALL-NEXT: # {{R}}UN: at line 1 +# SHOW-ALL-NEXT: echo "pass test output" +# SHOW-ALL-NEXT: # executed command: echo 'pass test output' +# SHOW-ALL-NEXT: # .---command stdout------------ +# SHOW-ALL-NEXT: # | pass test output +# SHOW-ALL-NEXT: # `----------------------------- +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: -- +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# SHOW-ALL-NEXT: Test requires the following unavailable features: asdf +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# SHOW-ALL-NEXT: Exit Code: 1 +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: Command Output (stdout): +# SHOW-ALL-NEXT: -- +# SHOW-ALL-NEXT: # {{R}}UN: at line 2 +# SHOW-ALL-NEXT: not echo "xfail test output" +# SHOW-ALL-NEXT: # executed command: not echo 'xfail test output' +# SHOW-ALL-NEXT: # .---command stdout------------ +# SHOW-ALL-NEXT: # | xfail test output +# SHOW-ALL-NEXT: # `----------------------------- +# SHOW-ALL-NEXT: # error: command failed with exit status: 1 +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: -- +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# SHOW-ALL-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# SHOW-ALL-NEXT: Exit Code: 0 +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: Command Output (stdout): +# SHOW-ALL-NEXT: -- +# SHOW-ALL-NEXT: # {{R}}UN: at line 2 +# SHOW-ALL-NEXT: echo "xpass test output" +# SHOW-ALL-NEXT: # executed command: echo 'xpass test output' +# SHOW-ALL-NEXT: # .---command stdout------------ +# SHOW-ALL-NEXT: # | xpass test output +# SHOW-ALL-NEXT: # `----------------------------- +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: -- +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: Failed Tests (1): +# SHOW-ALL-NEXT: verbosity :: fail.txt +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: ******************** +# SHOW-ALL-NEXT: Unexpectedly Passed Tests (1): +# SHOW-ALL-NEXT: verbosity :: xpass.txt +# SHOW-ALL-EMPTY: +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: Testing Time: {{.*}}s +# SHOW-ALL-EMPTY: +# SHOW-ALL-NEXT: Total Discovered Tests: 5 +# SHOW-ALL-NEXT: Unsupported : 1 (20.00%) +# SHOW-ALL-NEXT: Passed : 1 (20.00%) +# SHOW-ALL-NEXT: Expectedly Failed : 1 (20.00%) +# SHOW-ALL-NEXT: Failed : 1 (20.00%) +# SHOW-ALL-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --quiet %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# QUIET: -- Testing: 5 tests, 1 workers -- +# QUIET-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# QUIET-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# QUIET-NEXT: ******************** +# QUIET-NEXT: Failed Tests (1): +# QUIET-NEXT: verbosity :: fail.txt +# QUIET-EMPTY: +# QUIET-NEXT: ******************** +# QUIET-NEXT: Unexpectedly Passed Tests (1): +# QUIET-NEXT: verbosity :: xpass.txt +# QUIET-EMPTY: +# QUIET-EMPTY: +# QUIET-NEXT: Total Discovered Tests: 5 +# QUIET-NEXT: Failed : 1 (20.00%) +# QUIET-NEXT: Unexpectedly Passed: 1 (20.00%) + +# QUIET-ERR: 1 warning(s) in tests + + +### Test log output + +# RUN: not %{lit} --debug %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix DEBUG < %t/stdout.txt +# RUN: FileCheck %s --check-prefix DEBUG-ERR --implicit-check-not lit < %t/stderr.txt + +# DEBUG: -- Testing: 5 tests, 1 workers -- +# DEBUG-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# DEBUG-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# DEBUG-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# DEBUG-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# DEBUG-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# DEBUG-NEXT: ******************** +# DEBUG-NEXT: Failed Tests (1): +# DEBUG-NEXT: verbosity :: fail.txt +# DEBUG-EMPTY: +# DEBUG-NEXT: ******************** +# DEBUG-NEXT: Unexpectedly Passed Tests (1): +# DEBUG-NEXT: verbosity :: xpass.txt +# DEBUG-EMPTY: +# DEBUG-EMPTY: +# DEBUG-NEXT: Testing Time: {{.*}}s +# DEBUG-EMPTY: +# DEBUG-NEXT: Total Discovered Tests: 5 +# DEBUG-NEXT: Unsupported : 1 (20.00%) +# DEBUG-NEXT: Passed : 1 (20.00%) +# DEBUG-NEXT: Expectedly Failed : 1 (20.00%) +# DEBUG-NEXT: Failed : 1 (20.00%) +# DEBUG-NEXT: Unexpectedly Passed: 1 (20.00%) + +# DEBUG-ERR: lit.py: {{.*}}discovery.py:{{[0-9]+}}: debug: loading suite config '{{.*}}lit.cfg' +# DEBUG-ERR-NEXT: lit.py: {{.*}}lit.cfg:{{[0-9]+}}: debug: this is a debug log +# DEBUG-ERR-NEXT: lit.py: {{.*}}lit.cfg:{{[0-9]+}}: note: this is a note +# DEBUG-ERR-NEXT: lit.py: {{.*}}lit.cfg:{{[0-9]+}}: warning: this is a warning +# DEBUG-ERR-NEXT: lit.py: {{.*}}TestingConfig.py:{{[0-9]+}}: debug: ... loaded config '{{.*}}lit.cfg' +# DEBUG-ERR-NEXT: lit.py: {{.*}}discovery.py:{{[0-9]+}}: debug: resolved input '{{.*}}verbosity' to 'verbosity'::() +# DEBUG-ERR-EMPTY: +# DEBUG-ERR-NEXT: 1 warning(s) in tests + + +# RUN: not %{lit} --diagnostic-level note %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --diagnostic-level warning %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix WARNING-ERR --implicit-check-not lit < %t/stderr.txt + +# WARNING-ERR: lit.py: {{.*}}lit.cfg:{{[0-9]+}}: warning: this is a warning +# WARNING-ERR-EMPTY: +# WARNING-ERR-NEXT: 1 warning(s) in tests + +# RUN: not %{lit} --diagnostic-level error %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix ERROR-ERR --implicit-check-not lit < %t/stderr.txt + +# ERROR-ERR: 1 warning(s) in tests + + +### Test --test-output + +# RUN: not %{lit} --test-output off %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --test-output failed %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix VERBOSE < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# TEST-OUTPUT-OFF: -- Testing: 5 tests, 1 workers -- +# TEST-OUTPUT-OFF-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# TEST-OUTPUT-OFF-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# TEST-OUTPUT-OFF-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# TEST-OUTPUT-OFF-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# TEST-OUTPUT-OFF-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# TEST-OUTPUT-OFF-NEXT: ******************** +# TEST-OUTPUT-OFF-NEXT: Failed Tests (1): +# TEST-OUTPUT-OFF-NEXT: verbosity :: fail.txt +# TEST-OUTPUT-OFF-EMPTY: +# TEST-OUTPUT-OFF-NEXT: ******************** +# TEST-OUTPUT-OFF-NEXT: Unexpectedly Passed Tests (1): +# TEST-OUTPUT-OFF-NEXT: verbosity :: xpass.txt +# TEST-OUTPUT-OFF-EMPTY: +# TEST-OUTPUT-OFF-EMPTY: +# TEST-OUTPUT-OFF-NEXT: Testing Time: {{.*}}s +# TEST-OUTPUT-OFF-EMPTY: +# TEST-OUTPUT-OFF-NEXT: Total Discovered Tests: 5 +# TEST-OUTPUT-OFF-NEXT: Unsupported : 1 (20.00%) +# TEST-OUTPUT-OFF-NEXT: Passed : 1 (20.00%) +# TEST-OUTPUT-OFF-NEXT: Expectedly Failed : 1 (20.00%) +# TEST-OUTPUT-OFF-NEXT: Failed : 1 (20.00%) +# TEST-OUTPUT-OFF-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --test-output all %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SHOW-ALL < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + + +### Test --print-result-after + +# RUN: not %{lit} --print-result-after off %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix RESULT-OFF < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RESULT-OFF: ******************** +# RESULT-OFF-NEXT: Failed Tests (1): +# RESULT-OFF-NEXT: verbosity :: fail.txt +# RESULT-OFF-EMPTY: +# RESULT-OFF-NEXT: ******************** +# RESULT-OFF-NEXT: Unexpectedly Passed Tests (1): +# RESULT-OFF-NEXT: verbosity :: xpass.txt +# RESULT-OFF-EMPTY: +# RESULT-OFF-EMPTY: +# RESULT-OFF-NEXT: Testing Time: {{.*}}s +# RESULT-OFF-EMPTY: +# RESULT-OFF-NEXT: Total Discovered Tests: 5 +# RESULT-OFF-NEXT: Unsupported : 1 (20.00%) +# RESULT-OFF-NEXT: Passed : 1 (20.00%) +# RESULT-OFF-NEXT: Expectedly Failed : 1 (20.00%) +# RESULT-OFF-NEXT: Failed : 1 (20.00%) +# RESULT-OFF-NEXT: Unexpectedly Passed: 1 (20.00%) + + +# RUN: not %{lit} --print-result-after failed %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix RESULT-FAILED < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RESULT-FAILED: -- Testing: 5 tests, 1 workers -- +# RESULT-FAILED-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# RESULT-FAILED-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# RESULT-FAILED-NEXT: ******************** +# RESULT-FAILED-NEXT: Failed Tests (1): +# RESULT-FAILED-NEXT: verbosity :: fail.txt +# RESULT-FAILED-EMPTY: +# RESULT-FAILED-NEXT: ******************** +# RESULT-FAILED-NEXT: Unexpectedly Passed Tests (1): +# RESULT-FAILED-NEXT: verbosity :: xpass.txt +# RESULT-FAILED-EMPTY: +# RESULT-FAILED-EMPTY: +# RESULT-FAILED-NEXT: Testing Time: {{.*}}s +# RESULT-FAILED-EMPTY: +# RESULT-FAILED-NEXT: Total Discovered Tests: 5 +# RESULT-FAILED-NEXT: Unsupported : 1 (20.00%) +# RESULT-FAILED-NEXT: Passed : 1 (20.00%) +# RESULT-FAILED-NEXT: Expectedly Failed : 1 (20.00%) +# RESULT-FAILED-NEXT: Failed : 1 (20.00%) +# RESULT-FAILED-NEXT: Unexpectedly Passed: 1 (20.00%) + + +# RUN: not %{lit} --print-result-after all %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + + +### Test combinations of --print-result-after followed by --test-output + +# RUN: not %{lit} --print-result-after off --test-output failed %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix RESULT-OFF-OUTPUT-FAILED < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RESULT-OFF-OUTPUT-FAILED: -- Testing: 5 tests, 1 workers -- +# RESULT-OFF-OUTPUT-FAILED-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# RESULT-OFF-OUTPUT-FAILED-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# RESULT-OFF-OUTPUT-FAILED-NEXT: Exit Code: 127 +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: Command Output (stdout): +# RESULT-OFF-OUTPUT-FAILED-NEXT: -- +# RESULT-OFF-OUTPUT-FAILED-NEXT: # {{R}}UN: at line 1 +# RESULT-OFF-OUTPUT-FAILED-NEXT: echo "fail test output" +# RESULT-OFF-OUTPUT-FAILED-NEXT: # executed command: echo 'fail test output' +# RESULT-OFF-OUTPUT-FAILED-NEXT: # .---command stdout------------ +# RESULT-OFF-OUTPUT-FAILED-NEXT: # | fail test output +# RESULT-OFF-OUTPUT-FAILED-NEXT: # `----------------------------- +# RESULT-OFF-OUTPUT-FAILED-NEXT: # {{R}}UN: at line 2 +# RESULT-OFF-OUTPUT-FAILED-NEXT: fail +# RESULT-OFF-OUTPUT-FAILED-NEXT: # executed command: fail +# RESULT-OFF-OUTPUT-FAILED-NEXT: # .---command stderr------------ +# RESULT-OFF-OUTPUT-FAILED-NEXT: # | 'fail': command not found +# RESULT-OFF-OUTPUT-FAILED-NEXT: # `----------------------------- +# RESULT-OFF-OUTPUT-FAILED-NEXT: # error: command failed with exit status: 127 +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: -- +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: ******************** +# RESULT-OFF-OUTPUT-FAILED-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# RESULT-OFF-OUTPUT-FAILED-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# RESULT-OFF-OUTPUT-FAILED-NEXT: Exit Code: 0 +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: Command Output (stdout): +# RESULT-OFF-OUTPUT-FAILED-NEXT: -- +# RESULT-OFF-OUTPUT-FAILED-NEXT: # {{R}}UN: at line 2 +# RESULT-OFF-OUTPUT-FAILED-NEXT: echo "xpass test output" +# RESULT-OFF-OUTPUT-FAILED-NEXT: # executed command: echo 'xpass test output' +# RESULT-OFF-OUTPUT-FAILED-NEXT: # .---command stdout------------ +# RESULT-OFF-OUTPUT-FAILED-NEXT: # | xpass test output +# RESULT-OFF-OUTPUT-FAILED-NEXT: # `----------------------------- +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: -- +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: ******************** +# RESULT-OFF-OUTPUT-FAILED-NEXT: ******************** +# RESULT-OFF-OUTPUT-FAILED-NEXT: Failed Tests (1): +# RESULT-OFF-OUTPUT-FAILED-NEXT: verbosity :: fail.txt +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: ******************** +# RESULT-OFF-OUTPUT-FAILED-NEXT: Unexpectedly Passed Tests (1): +# RESULT-OFF-OUTPUT-FAILED-NEXT: verbosity :: xpass.txt +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: Testing Time: {{.*}}s +# RESULT-OFF-OUTPUT-FAILED-EMPTY: +# RESULT-OFF-OUTPUT-FAILED-NEXT: Total Discovered Tests: 5 +# RESULT-OFF-OUTPUT-FAILED-NEXT: Unsupported : 1 (20.00%) +# RESULT-OFF-OUTPUT-FAILED-NEXT: Passed : 1 (20.00%) +# RESULT-OFF-OUTPUT-FAILED-NEXT: Expectedly Failed : 1 (20.00%) +# RESULT-OFF-OUTPUT-FAILED-NEXT: Failed : 1 (20.00%) +# RESULT-OFF-OUTPUT-FAILED-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --print-result-after all --test-output off %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --print-result-after failed --test-output all %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SHOW-ALL < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + + +### Test combinations of --test-output followed by --print-result-after + +# RUN: not %{lit} --test-output failed --print-result-after off %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix RESULT-OFF < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --test-output off --print-result-after all %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --test-output all --print-result-after failed %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix OUTPUT-ALL-RESULT-FAILED < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# OUTPUT-ALL-RESULT-FAILED: -- Testing: 5 tests, 1 workers -- +# OUTPUT-ALL-RESULT-FAILED-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# OUTPUT-ALL-RESULT-FAILED-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# OUTPUT-ALL-RESULT-FAILED-NEXT: Exit Code: 127 +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: Command Output (stdout): +# OUTPUT-ALL-RESULT-FAILED-NEXT: -- +# OUTPUT-ALL-RESULT-FAILED-NEXT: # {{R}}UN: at line 1 +# OUTPUT-ALL-RESULT-FAILED-NEXT: echo "fail test output" +# OUTPUT-ALL-RESULT-FAILED-NEXT: # executed command: echo 'fail test output' +# OUTPUT-ALL-RESULT-FAILED-NEXT: # .---command stdout------------ +# OUTPUT-ALL-RESULT-FAILED-NEXT: # | fail test output +# OUTPUT-ALL-RESULT-FAILED-NEXT: # `----------------------------- +# OUTPUT-ALL-RESULT-FAILED-NEXT: # {{R}}UN: at line 2 +# OUTPUT-ALL-RESULT-FAILED-NEXT: fail +# OUTPUT-ALL-RESULT-FAILED-NEXT: # executed command: fail +# OUTPUT-ALL-RESULT-FAILED-NEXT: # .---command stderr------------ +# OUTPUT-ALL-RESULT-FAILED-NEXT: # | 'fail': command not found +# OUTPUT-ALL-RESULT-FAILED-NEXT: # `----------------------------- +# OUTPUT-ALL-RESULT-FAILED-NEXT: # error: command failed with exit status: 127 +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: -- +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: ******************** +# OUTPUT-ALL-RESULT-FAILED-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# OUTPUT-ALL-RESULT-FAILED-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# OUTPUT-ALL-RESULT-FAILED-NEXT: Exit Code: 0 +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: Command Output (stdout): +# OUTPUT-ALL-RESULT-FAILED-NEXT: -- +# OUTPUT-ALL-RESULT-FAILED-NEXT: # {{R}}UN: at line 2 +# OUTPUT-ALL-RESULT-FAILED-NEXT: echo "xpass test output" +# OUTPUT-ALL-RESULT-FAILED-NEXT: # executed command: echo 'xpass test output' +# OUTPUT-ALL-RESULT-FAILED-NEXT: # .---command stdout------------ +# OUTPUT-ALL-RESULT-FAILED-NEXT: # | xpass test output +# OUTPUT-ALL-RESULT-FAILED-NEXT: # `----------------------------- +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: -- +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: ******************** +# OUTPUT-ALL-RESULT-FAILED-NEXT: ******************** +# OUTPUT-ALL-RESULT-FAILED-NEXT: Failed Tests (1): +# OUTPUT-ALL-RESULT-FAILED-NEXT: verbosity :: fail.txt +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: ******************** +# OUTPUT-ALL-RESULT-FAILED-NEXT: Unexpectedly Passed Tests (1): +# OUTPUT-ALL-RESULT-FAILED-NEXT: verbosity :: xpass.txt +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: Testing Time: {{.*}} +# OUTPUT-ALL-RESULT-FAILED-EMPTY: +# OUTPUT-ALL-RESULT-FAILED-NEXT: Total Discovered Tests: 5 +# OUTPUT-ALL-RESULT-FAILED-NEXT: Unsupported : 1 (20.00%) +# OUTPUT-ALL-RESULT-FAILED-NEXT: Passed : 1 (20.00%) +# OUTPUT-ALL-RESULT-FAILED-NEXT: Expectedly Failed : 1 (20.00%) +# OUTPUT-ALL-RESULT-FAILED-NEXT: Failed : 1 (20.00%) +# OUTPUT-ALL-RESULT-FAILED-NEXT: Unexpectedly Passed: 1 (20.00%) + + +### Test progress bar and terse summary in isolation + +# RUN: not %{lit} --progress-bar %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix PROGRESS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# PROGRESS: -- Testing: 5 tests, 1 workers -- +# PROGRESS-NEXT: Testing: +# PROGRESS-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# PROGRESS-NEXT: Testing: +# PROGRESS-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# PROGRESS-NEXT: Testing: +# PROGRESS-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# PROGRESS-NEXT: Testing: +# PROGRESS-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# PROGRESS-NEXT: Testing: +# PROGRESS-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# PROGRESS-NEXT: Testing: +# PROGRESS-NEXT: ******************** +# PROGRESS-NEXT: Failed Tests (1): +# PROGRESS-NEXT: verbosity :: fail.txt +# PROGRESS-EMPTY: +# PROGRESS-NEXT: ******************** +# PROGRESS-NEXT: Unexpectedly Passed Tests (1): +# PROGRESS-NEXT: verbosity :: xpass.txt +# PROGRESS-EMPTY: +# PROGRESS-EMPTY: +# PROGRESS-NEXT: Testing Time: {{.*}}s +# PROGRESS-EMPTY: +# PROGRESS-NEXT: Total Discovered Tests: 5 +# PROGRESS-NEXT: Unsupported : 1 (20.00%) +# PROGRESS-NEXT: Passed : 1 (20.00%) +# PROGRESS-NEXT: Expectedly Failed : 1 (20.00%) +# PROGRESS-NEXT: Failed : 1 (20.00%) +# PROGRESS-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --terse-summary %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix TERSE < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# TERSE: -- Testing: 5 tests, 1 workers -- +# TERSE-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# TERSE-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# TERSE-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# TERSE-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# TERSE-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# TERSE-NEXT: ******************** +# TERSE-NEXT: Failed Tests (1): +# TERSE-NEXT: verbosity :: fail.txt +# TERSE-EMPTY: +# TERSE-NEXT: ******************** +# TERSE-NEXT: Unexpectedly Passed Tests (1): +# TERSE-NEXT: verbosity :: xpass.txt +# TERSE-EMPTY: +# TERSE-EMPTY: +# TERSE-NEXT: Total Discovered Tests: 5 +# TERSE-NEXT: Failed : 1 (20.00%) +# TERSE-NEXT: Unexpectedly Passed: 1 (20.00%) + + +### Aliases in combination + +# RUN: not %{lit} -a -s %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix AS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# AS: -- Testing: 5 tests, 1 workers -- +# AS-NEXT: Testing: +# AS-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# AS-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# AS-NEXT: Exit Code: 127 +# AS-EMPTY: +# AS-NEXT: Command Output (stdout): +# AS-NEXT: -- +# AS-NEXT: # {{R}}UN: at line 1 +# AS-NEXT: echo "fail test output" +# AS-NEXT: # executed command: echo 'fail test output' +# AS-NEXT: # .---command stdout------------ +# AS-NEXT: # | fail test output +# AS-NEXT: # `----------------------------- +# AS-NEXT: # {{R}}UN: at line 2 +# AS-NEXT: fail +# AS-NEXT: # executed command: fail +# AS-NEXT: # .---command stderr------------ +# AS-NEXT: # | 'fail': command not found +# AS-NEXT: # `----------------------------- +# AS-NEXT: # error: command failed with exit status: 127 +# AS-EMPTY: +# AS-NEXT: -- +# AS-EMPTY: +# AS-NEXT: ******************** +# AS-NEXT: Testing: +# AS-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# AS-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# AS-NEXT: Exit Code: 0 +# AS-EMPTY: +# AS-NEXT: Command Output (stdout): +# AS-NEXT: -- +# AS-NEXT: # {{R}}UN: at line 2 +# AS-NEXT: echo "xpass test output" +# AS-NEXT: # executed command: echo 'xpass test output' +# AS-NEXT: # .---command stdout------------ +# AS-NEXT: # | xpass test output +# AS-NEXT: # `----------------------------- +# AS-EMPTY: +# AS-NEXT: -- +# AS-EMPTY: +# AS-NEXT: ******************** +# AS-NEXT: Testing: +# AS-NEXT: ******************** +# AS-NEXT: Failed Tests (1): +# AS-NEXT: verbosity :: fail.txt +# AS-EMPTY: +# AS-NEXT: ******************** +# AS-NEXT: Unexpectedly Passed Tests (1): +# AS-NEXT: verbosity :: xpass.txt +# AS-EMPTY: +# AS-EMPTY: +# AS-NEXT: Testing Time: {{.*}}s +# AS-EMPTY: +# AS-NEXT: Total Discovered Tests: 5 +# AS-NEXT: Unsupported : 1 (20.00%) +# AS-NEXT: Passed : 1 (20.00%) +# AS-NEXT: Expectedly Failed : 1 (20.00%) +# AS-NEXT: Failed : 1 (20.00%) +# AS-NEXT: Unexpectedly Passed: 1 (20.00%) + + +# RUN: not %{lit} -s -a %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SA < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# SA: -- Testing: 5 tests, 1 workers -- +# SA-NEXT: Testing: +# SA-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# SA-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# SA-NEXT: Exit Code: 127 +# SA-EMPTY: +# SA-NEXT: Command Output (stdout): +# SA-NEXT: -- +# SA-NEXT: # {{R}}UN: at line 1 +# SA-NEXT: echo "fail test output" +# SA-NEXT: # executed command: echo 'fail test output' +# SA-NEXT: # .---command stdout------------ +# SA-NEXT: # | fail test output +# SA-NEXT: # `----------------------------- +# SA-NEXT: # {{R}}UN: at line 2 +# SA-NEXT: fail +# SA-NEXT: # executed command: fail +# SA-NEXT: # .---command stderr------------ +# SA-NEXT: # | 'fail': command not found +# SA-NEXT: # `----------------------------- +# SA-NEXT: # error: command failed with exit status: 127 +# SA-EMPTY: +# SA-NEXT: -- +# SA-EMPTY: +# SA-NEXT: ******************** +# SA-NEXT: Testing: +# SA-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# SA-NEXT: Exit Code: 0 +# SA-EMPTY: +# SA-NEXT: Command Output (stdout): +# SA-NEXT: -- +# SA-NEXT: # {{R}}UN: at line 1 +# SA-NEXT: echo "pass test output" +# SA-NEXT: # executed command: echo 'pass test output' +# SA-NEXT: # .---command stdout------------ +# SA-NEXT: # | pass test output +# SA-NEXT: # `----------------------------- +# SA-EMPTY: +# SA-NEXT: -- +# SA-EMPTY: +# SA-NEXT: ******************** +# SA-NEXT: Testing: +# SA-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# SA-NEXT: Test requires the following unavailable features: asdf +# SA-NEXT: ******************** +# SA-NEXT: Testing: +# SA-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# SA-NEXT: Exit Code: 1 +# SA-EMPTY: +# SA-NEXT: Command Output (stdout): +# SA-NEXT: -- +# SA-NEXT: # {{R}}UN: at line 2 +# SA-NEXT: not echo "xfail test output" +# SA-NEXT: # executed command: not echo 'xfail test output' +# SA-NEXT: # .---command stdout------------ +# SA-NEXT: # | xfail test output +# SA-NEXT: # `----------------------------- +# SA-NEXT: # error: command failed with exit status: 1 +# SA-EMPTY: +# SA-NEXT: -- +# SA-EMPTY: +# SA-NEXT: ******************** +# SA-NEXT: Testing: +# SA-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# SA-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# SA-NEXT: Exit Code: 0 +# SA-EMPTY: +# SA-NEXT: Command Output (stdout): +# SA-NEXT: -- +# SA-NEXT: # {{R}}UN: at line 2 +# SA-NEXT: echo "xpass test output" +# SA-NEXT: # executed command: echo 'xpass test output' +# SA-NEXT: # .---command stdout------------ +# SA-NEXT: # | xpass test output +# SA-NEXT: # `----------------------------- +# SA-EMPTY: +# SA-NEXT: -- +# SA-EMPTY: +# SA-NEXT: ******************** +# SA-NEXT: Testing: +# SA-NEXT: ******************** +# SA-NEXT: Failed Tests (1): +# SA-NEXT: verbosity :: fail.txt +# SA-EMPTY: +# SA-NEXT: ******************** +# SA-NEXT: Unexpectedly Passed Tests (1): +# SA-NEXT: verbosity :: xpass.txt +# SA-EMPTY: +# SA-EMPTY: +# SA-NEXT: Testing Time: {{.*}}s +# SA-EMPTY: +# SA-NEXT: Total Discovered Tests: 5 +# SA-NEXT: Unsupported : 1 (20.00%) +# SA-NEXT: Passed : 1 (20.00%) +# SA-NEXT: Expectedly Failed : 1 (20.00%) +# SA-NEXT: Failed : 1 (20.00%) +# SA-NEXT: Unexpectedly Passed: 1 (20.00%) + + +# RUN: not %{lit} -q -a %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix QA < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# QA: -- Testing: 5 tests, 1 workers -- +# QA-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# QA-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# QA-NEXT: Exit Code: 127 +# QA-EMPTY: +# QA-NEXT: Command Output (stdout): +# QA-NEXT: -- +# QA-NEXT: # {{R}}UN: at line 1 +# QA-NEXT: echo "fail test output" +# QA-NEXT: # executed command: echo 'fail test output' +# QA-NEXT: # .---command stdout------------ +# QA-NEXT: # | fail test output +# QA-NEXT: # `----------------------------- +# QA-NEXT: # {{R}}UN: at line 2 +# QA-NEXT: fail +# QA-NEXT: # executed command: fail +# QA-NEXT: # .---command stderr------------ +# QA-NEXT: # | 'fail': command not found +# QA-NEXT: # `----------------------------- +# QA-NEXT: # error: command failed with exit status: 127 +# QA-EMPTY: +# QA-NEXT: -- +# QA-EMPTY: +# QA-NEXT: ******************** +# QA-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# QA-NEXT: Exit Code: 0 +# QA-EMPTY: +# QA-NEXT: Command Output (stdout): +# QA-NEXT: -- +# QA-NEXT: # {{R}}UN: at line 1 +# QA-NEXT: echo "pass test output" +# QA-NEXT: # executed command: echo 'pass test output' +# QA-NEXT: # .---command stdout------------ +# QA-NEXT: # | pass test output +# QA-NEXT: # `----------------------------- +# QA-EMPTY: +# QA-NEXT: -- +# QA-EMPTY: +# QA-NEXT: ******************** +# QA-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# QA-NEXT: Test requires the following unavailable features: asdf +# QA-NEXT: ******************** +# QA-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# QA-NEXT: Exit Code: 1 +# QA-EMPTY: +# QA-NEXT: Command Output (stdout): +# QA-NEXT: -- +# QA-NEXT: # {{R}}UN: at line 2 +# QA-NEXT: not echo "xfail test output" +# QA-NEXT: # executed command: not echo 'xfail test output' +# QA-NEXT: # .---command stdout------------ +# QA-NEXT: # | xfail test output +# QA-NEXT: # `----------------------------- +# QA-NEXT: # error: command failed with exit status: 1 +# QA-EMPTY: +# QA-NEXT: -- +# QA-EMPTY: +# QA-NEXT: ******************** +# QA-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# QA-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# QA-NEXT: Exit Code: 0 +# QA-EMPTY: +# QA-NEXT: Command Output (stdout): +# QA-NEXT: -- +# QA-NEXT: # {{R}}UN: at line 2 +# QA-NEXT: echo "xpass test output" +# QA-NEXT: # executed command: echo 'xpass test output' +# QA-NEXT: # .---command stdout------------ +# QA-NEXT: # | xpass test output +# QA-NEXT: # `----------------------------- +# QA-EMPTY: +# QA-NEXT: -- +# QA-EMPTY: +# QA-NEXT: ******************** +# QA-NEXT: ******************** +# QA-NEXT: Failed Tests (1): +# QA-NEXT: verbosity :: fail.txt +# QA-EMPTY: +# QA-NEXT: ******************** +# QA-NEXT: Unexpectedly Passed Tests (1): +# QA-NEXT: verbosity :: xpass.txt +# QA-EMPTY: +# QA-EMPTY: +# QA-NEXT: Total Discovered Tests: 5 +# QA-NEXT: Failed : 1 (20.00%) +# QA-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} -a -q %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} -sqav %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SQAV < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# SQAV: -- Testing: 5 tests, 1 workers -- +# SQAV-NEXT: Testing: +# SQAV-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# SQAV-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# SQAV-NEXT: Exit Code: 127 +# SQAV-EMPTY: +# SQAV-NEXT: Command Output (stdout): +# SQAV-NEXT: -- +# SQAV-NEXT: # {{R}}UN: at line 1 +# SQAV-NEXT: echo "fail test output" +# SQAV-NEXT: # executed command: echo 'fail test output' +# SQAV-NEXT: # .---command stdout------------ +# SQAV-NEXT: # | fail test output +# SQAV-NEXT: # `----------------------------- +# SQAV-NEXT: # {{R}}UN: at line 2 +# SQAV-NEXT: fail +# SQAV-NEXT: # executed command: fail +# SQAV-NEXT: # .---command stderr------------ +# SQAV-NEXT: # | 'fail': command not found +# SQAV-NEXT: # `----------------------------- +# SQAV-NEXT: # error: command failed with exit status: 127 +# SQAV-EMPTY: +# SQAV-NEXT: -- +# SQAV-EMPTY: +# SQAV-NEXT: ******************** +# SQAV-NEXT: Testing: +# SQAV-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# SQAV-NEXT: Testing: +# SQAV-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# SQAV-NEXT: Testing: +# SQAV-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# SQAV-NEXT: Testing: +# SQAV-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# SQAV-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# SQAV-NEXT: Exit Code: 0 +# SQAV-EMPTY: +# SQAV-NEXT: Command Output (stdout): +# SQAV-NEXT: -- +# SQAV-NEXT: # {{R}}UN: at line 2 +# SQAV-NEXT: echo "xpass test output" +# SQAV-NEXT: # executed command: echo 'xpass test output' +# SQAV-NEXT: # .---command stdout------------ +# SQAV-NEXT: # | xpass test output +# SQAV-NEXT: # `----------------------------- +# SQAV-EMPTY: +# SQAV-NEXT: -- +# SQAV-EMPTY: +# SQAV-NEXT: ******************** +# SQAV-NEXT: Testing: +# SQAV-NEXT: ******************** +# SQAV-NEXT: Failed Tests (1): +# SQAV-NEXT: verbosity :: fail.txt +# SQAV-EMPTY: +# SQAV-NEXT: ******************** +# SQAV-NEXT: Unexpectedly Passed Tests (1): +# SQAV-NEXT: verbosity :: xpass.txt +# SQAV-EMPTY: +# SQAV-EMPTY: +# SQAV-NEXT: Total Discovered Tests: 5 +# SQAV-NEXT: Failed : 1 (20.00%) +# SQAV-NEXT: Unexpectedly Passed: 1 (20.00%) + + +### Aliases with specific overrides + +# RUN: not %{lit} --quiet --no-terse-summary %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-W-SUMMARY < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# QUIET-W-SUMMARY: -- Testing: 5 tests, 1 workers -- +# QUIET-W-SUMMARY-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# QUIET-W-SUMMARY-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# QUIET-W-SUMMARY-NEXT: ******************** +# QUIET-W-SUMMARY-NEXT: Failed Tests (1): +# QUIET-W-SUMMARY-NEXT: verbosity :: fail.txt +# QUIET-W-SUMMARY-EMPTY: +# QUIET-W-SUMMARY-NEXT: ******************** +# QUIET-W-SUMMARY-NEXT: Unexpectedly Passed Tests (1): +# QUIET-W-SUMMARY-NEXT: verbosity :: xpass.txt +# QUIET-W-SUMMARY-EMPTY: +# QUIET-W-SUMMARY-EMPTY: +# QUIET-W-SUMMARY-NEXT: Testing Time: {{.*}}s +# QUIET-W-SUMMARY-EMPTY: +# QUIET-W-SUMMARY-NEXT: Total Discovered Tests: 5 +# QUIET-W-SUMMARY-NEXT: Unsupported : 1 (20.00%) +# QUIET-W-SUMMARY-NEXT: Passed : 1 (20.00%) +# QUIET-W-SUMMARY-NEXT: Expectedly Failed : 1 (20.00%) +# QUIET-W-SUMMARY-NEXT: Failed : 1 (20.00%) +# QUIET-W-SUMMARY-NEXT: Unexpectedly Passed: 1 (20.00%) + + +# RUN: not %{lit} --quiet --progress-bar %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-W-PROGRESS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# QUIET-W-PROGRESS: -- Testing: 5 tests, 1 workers -- +# QUIET-W-PROGRESS-NEXT: Testing: +# QUIET-W-PROGRESS-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# QUIET-W-PROGRESS-NEXT: Testing: +# QUIET-W-PROGRESS-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# QUIET-W-PROGRESS-NEXT: Testing: +# QUIET-W-PROGRESS-NEXT: ******************** +# QUIET-W-PROGRESS-NEXT: Failed Tests (1): +# QUIET-W-PROGRESS-NEXT: verbosity :: fail.txt +# QUIET-W-PROGRESS-EMPTY: +# QUIET-W-PROGRESS-NEXT: ******************** +# QUIET-W-PROGRESS-NEXT: Unexpectedly Passed Tests (1): +# QUIET-W-PROGRESS-NEXT: verbosity :: xpass.txt +# QUIET-W-PROGRESS-EMPTY: +# QUIET-W-PROGRESS-EMPTY: +# QUIET-W-PROGRESS-NEXT: Total Discovered Tests: 5 +# QUIET-W-PROGRESS-NEXT: Failed : 1 (20.00%) +# QUIET-W-PROGRESS-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --show-all --terse-summary %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix ALL-TERSE < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# ALL-TERSE: -- Testing: 5 tests, 1 workers -- +# ALL-TERSE-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# ALL-TERSE-NEXT: ******************** TEST 'verbosity :: fail.txt' FAILED ******************** +# ALL-TERSE-NEXT: Exit Code: 127 +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: Command Output (stdout): +# ALL-TERSE-NEXT: -- +# ALL-TERSE-NEXT: # {{R}}UN: at line 1 +# ALL-TERSE-NEXT: echo "fail test output" +# ALL-TERSE-NEXT: # executed command: echo 'fail test output' +# ALL-TERSE-NEXT: # .---command stdout------------ +# ALL-TERSE-NEXT: # | fail test output +# ALL-TERSE-NEXT: # `----------------------------- +# ALL-TERSE-NEXT: # {{R}}UN: at line 2 +# ALL-TERSE-NEXT: fail +# ALL-TERSE-NEXT: # executed command: fail +# ALL-TERSE-NEXT: # .---command stderr------------ +# ALL-TERSE-NEXT: # | 'fail': command not found +# ALL-TERSE-NEXT: # `----------------------------- +# ALL-TERSE-NEXT: # error: command failed with exit status: 127 +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: -- +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# ALL-TERSE-NEXT: Exit Code: 0 +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: Command Output (stdout): +# ALL-TERSE-NEXT: -- +# ALL-TERSE-NEXT: # {{R}}UN: at line 1 +# ALL-TERSE-NEXT: echo "pass test output" +# ALL-TERSE-NEXT: # executed command: echo 'pass test output' +# ALL-TERSE-NEXT: # .---command stdout------------ +# ALL-TERSE-NEXT: # | pass test output +# ALL-TERSE-NEXT: # `----------------------------- +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: -- +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# ALL-TERSE-NEXT: Test requires the following unavailable features: asdf +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# ALL-TERSE-NEXT: Exit Code: 1 +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: Command Output (stdout): +# ALL-TERSE-NEXT: -- +# ALL-TERSE-NEXT: # {{R}}UN: at line 2 +# ALL-TERSE-NEXT: not echo "xfail test output" +# ALL-TERSE-NEXT: # executed command: not echo 'xfail test output' +# ALL-TERSE-NEXT: # .---command stdout------------ +# ALL-TERSE-NEXT: # | xfail test output +# ALL-TERSE-NEXT: # `----------------------------- +# ALL-TERSE-NEXT: # error: command failed with exit status: 1 +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: -- +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# ALL-TERSE-NEXT: ******************** TEST 'verbosity :: xpass.txt' FAILED ******************** +# ALL-TERSE-NEXT: Exit Code: 0 +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: Command Output (stdout): +# ALL-TERSE-NEXT: -- +# ALL-TERSE-NEXT: # {{R}}UN: at line 2 +# ALL-TERSE-NEXT: echo "xpass test output" +# ALL-TERSE-NEXT: # executed command: echo 'xpass test output' +# ALL-TERSE-NEXT: # .---command stdout------------ +# ALL-TERSE-NEXT: # | xpass test output +# ALL-TERSE-NEXT: # `----------------------------- +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: -- +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: Failed Tests (1): +# ALL-TERSE-NEXT: verbosity :: fail.txt +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: ******************** +# ALL-TERSE-NEXT: Unexpectedly Passed Tests (1): +# ALL-TERSE-NEXT: verbosity :: xpass.txt +# ALL-TERSE-EMPTY: +# ALL-TERSE-EMPTY: +# ALL-TERSE-NEXT: Total Discovered Tests: 5 +# ALL-TERSE-NEXT: Failed : 1 (20.00%) +# ALL-TERSE-NEXT: Unexpectedly Passed: 1 (20.00%) + +# RUN: not %{lit} --show-all --diagnostic-level error %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SHOW-ALL < %t/stdout.txt +# RUN: FileCheck %s --check-prefix QUIET-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --show-all --test-output off %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# RUN: not %{lit} --succinct --print-result-after all %{inputs}/verbosity 2> %t/stderr.txt > %t/stdout.txt +# RUN: FileCheck %s --check-prefix SUCCINCT-RESULT-ALL < %t/stdout.txt +# RUN: FileCheck %s --check-prefix NO-ARGS-ERR --implicit-check-not lit < %t/stderr.txt + +# SUCCINCT-RESULT-ALL: -- Testing: 5 tests, 1 workers -- +# SUCCINCT-RESULT-ALL-NEXT: Testing: +# SUCCINCT-RESULT-ALL-NEXT: FAIL: verbosity :: fail.txt (1 of 5) +# SUCCINCT-RESULT-ALL-NEXT: Testing: +# SUCCINCT-RESULT-ALL-NEXT: PASS: verbosity :: pass.txt (2 of 5) +# SUCCINCT-RESULT-ALL-NEXT: Testing: +# SUCCINCT-RESULT-ALL-NEXT: {{UN}}SUPPORTED: verbosity :: unsupported.txt (3 of 5) +# SUCCINCT-RESULT-ALL-NEXT: Testing: +# SUCCINCT-RESULT-ALL-NEXT: {{X}}FAIL: verbosity :: xfail.txt (4 of 5) +# SUCCINCT-RESULT-ALL-NEXT: Testing: +# SUCCINCT-RESULT-ALL-NEXT: XPASS: verbosity :: xpass.txt (5 of 5) +# SUCCINCT-RESULT-ALL-NEXT: Testing: +# SUCCINCT-RESULT-ALL-NEXT: ******************** +# SUCCINCT-RESULT-ALL-NEXT: Failed Tests (1): +# SUCCINCT-RESULT-ALL-NEXT: verbosity :: fail.txt +# SUCCINCT-RESULT-ALL-EMPTY: +# SUCCINCT-RESULT-ALL-NEXT: ******************** +# SUCCINCT-RESULT-ALL-NEXT: Unexpectedly Passed Tests (1): +# SUCCINCT-RESULT-ALL-NEXT: verbosity :: xpass.txt +# SUCCINCT-RESULT-ALL-EMPTY: +# SUCCINCT-RESULT-ALL-EMPTY: +# SUCCINCT-RESULT-ALL-NEXT: Testing Time: {{.*}}s +# SUCCINCT-RESULT-ALL-EMPTY: +# SUCCINCT-RESULT-ALL-NEXT: Total Discovered Tests: 5 +# SUCCINCT-RESULT-ALL-NEXT: Unsupported : 1 (20.00%) +# SUCCINCT-RESULT-ALL-NEXT: Passed : 1 (20.00%) +# SUCCINCT-RESULT-ALL-NEXT: Expectedly Failed : 1 (20.00%) +# SUCCINCT-RESULT-ALL-NEXT: Failed : 1 (20.00%) +# SUCCINCT-RESULT-ALL-NEXT: Unexpectedly Passed: 1 (20.00%) diff --git a/llvm/utils/lit/tests/windows-pools.py b/llvm/utils/lit/tests/windows-pools.py new file mode 100644 index 0000000..6ba43ec --- /dev/null +++ b/llvm/utils/lit/tests/windows-pools.py @@ -0,0 +1,27 @@ +# Create a directory with 20 files and check the number of pools and workers per pool that lit will use. + +# RUN: rm -Rf %t.dir && mkdir -p %t.dir +# RUN: %{python} -c "for i in range(20): open(rf'%t.dir/file{i}.txt', 'w').write('RUN:')" + +# RUN: echo "import lit.formats" > %t.dir/lit.cfg +# RUN: echo "config.name = \"top-level-suite\"" >> %t.dir/lit.cfg +# RUN: echo "config.suffixes = [\".txt\"]" >> %t.dir/lit.cfg +# RUN: echo "config.test_format = lit.formats.ShTest()" >> %t.dir/lit.cfg + + +# 15 workers per pool max, 100 workers total max: we expect lit to cap the workers to the number of files +# RUN: env "LIT_WINDOWS_MAX_WORKERS_PER_POOL=15" %{lit} -s %t.dir/ -j100 > %t.out 2>&1 +# CHECK: Using 2 pools balancing 20 workers total distributed as [10, 10] +# CHECK: Passed: 20 + +# 5 workers per pool max, 17 workers total max +# RUN: env "LIT_WINDOWS_MAX_WORKERS_PER_POOL=5" %{lit} -s %t.dir/ -j17 >> %t.out 2>&1 +# CHECK: Using 4 pools balancing 17 workers total distributed as [5, 4, 4, 4] +# CHECK: Passed: 20 + +# 19 workers per pool max, 19 workers total max +# RUN: env "LIT_WINDOWS_MAX_WORKERS_PER_POOL=19" %{lit} -s %t.dir/ -j19 >> %t.out 2>&1 +# CHECK-NOT: workers total distributed as +# CHECK: Passed: 20 + +# RUN: cat %t.out | FileCheck %s diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt index b1f20a7..959d227 100644 --- a/llvm/utils/profcheck-xfail.txt +++ b/llvm/utils/profcheck-xfail.txt @@ -17,14 +17,11 @@ CodeGen/RISCV/zmmul.ll CodeGen/WebAssembly/memory-interleave.ll CodeGen/X86/AMX/amx-low-intrinsics.ll CodeGen/X86/masked_gather_scatter.ll -CodeGen/X86/nocfivalue.ll DebugInfo/AArch64/ir-outliner.ll DebugInfo/assignment-tracking/X86/hotcoldsplit.ll DebugInfo/Generic/block-asan.ll -DebugInfo/X86/asan_debug_info.ll LTO/X86/diagnostic-handler-remarks-with-hotness.ll Other/optimization-remarks-auto.ll -Other/X86/debugcounter-partiallyinlinelibcalls.ll Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll Transforms/AtomicExpand/SPARC/partword.ll Transforms/Attributor/align.ll @@ -94,8 +91,6 @@ Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-constant-numerator.ll Transforms/CodeGenPrepare/NVPTX/bypass-slow-div.ll Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-not-exact.ll Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-special-cases.ll -Transforms/CodeGenPrepare/X86/vec-shift-inseltpoison.ll -Transforms/CodeGenPrepare/X86/vec-shift.ll Transforms/Coroutines/coro-await-suspend-lower-invoke.ll Transforms/Coroutines/coro-await-suspend-lower.ll Transforms/Coroutines/coro-byval-param.ll @@ -148,12 +143,6 @@ Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptosi129.ll Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-fptoui129.ll Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-si129tofp.ll Transforms/ExpandLargeFpConvert/X86/expand-large-fp-convert-ui129tofp.ll -Transforms/ExpandMemCmp/AArch64/memcmp.ll -Transforms/ExpandMemCmp/X86/memcmp.ll -Transforms/ExpandMemCmp/X86/memcmp-x32.ll -Transforms/ExpandVariadics/expand-va-intrinsic-split-linkage.ll -Transforms/ExpandVariadics/expand-va-intrinsic-split-simple.ll -Transforms/ExpandVariadics/intrinsics.ll Transforms/FixIrreducible/basic.ll Transforms/FixIrreducible/bug45623.ll Transforms/FixIrreducible/callbr.ll @@ -182,8 +171,6 @@ Transforms/GlobalOpt/shrink-global-to-bool-check-debug.ll Transforms/GlobalOpt/shrink-global-to-bool-opaque-ptrs.ll Transforms/GVN/debugloc-load-select.ll Transforms/GVN/load-through-select-dbg.ll -Transforms/GVN/masked-load-store.ll -Transforms/GVN/masked-load-store-no-mem-dep.ll Transforms/GVN/opaque-ptr.ll Transforms/GVN/pr69301.ll Transforms/GVN/pre-invalid-prof-metadata.ll @@ -236,9 +223,6 @@ Transforms/IndVarSimplify/pr45835.ll Transforms/IndVarSimplify/preserving-debugloc-rem-div.ll Transforms/InstCombine/2004-09-20-BadLoadCombine.ll Transforms/InstCombine/2005-04-07-UDivSelectCrash.ll -Transforms/InstCombine/AArch64/sve-intrinsic-sel.ll -Transforms/InstCombine/AArch64/sve-intrinsic-simplify-binop.ll -Transforms/InstCombine/AArch64/sve-intrinsic-simplify-shift.ll Transforms/InstCombine/add-mask.ll Transforms/InstCombine/add-shl-mul-umax.ll Transforms/InstCombine/and2.ll @@ -274,7 +258,6 @@ Transforms/InstCombine/fmul-bool.ll Transforms/InstCombine/fmul.ll Transforms/InstCombine/fneg.ll Transforms/InstCombine/fold-ctpop-of-not.ll -Transforms/InstCombine/fold-ext-eq-c-with-op.ll Transforms/InstCombine/free-inversion.ll Transforms/InstCombine/icmp-and-lowbit-mask.ll Transforms/InstCombine/icmp.ll @@ -294,8 +277,6 @@ Transforms/InstCombine/loadstore-metadata.ll Transforms/InstCombine/logical-select-inseltpoison.ll Transforms/InstCombine/logical-select.ll Transforms/InstCombine/lshr.ll -Transforms/InstCombine/masked_intrinsics-inseltpoison.ll -Transforms/InstCombine/masked_intrinsics.ll Transforms/InstCombine/memchr-11.ll Transforms/InstCombine/memchr-2.ll Transforms/InstCombine/memchr-3.ll @@ -332,14 +313,11 @@ Transforms/InstCombine/select-and-or.ll Transforms/InstCombine/select-cmp-br.ll Transforms/InstCombine/select-cmp.ll Transforms/InstCombine/select-factorize.ll -Transforms/InstCombine/select_frexp.ll Transforms/InstCombine/select.ll Transforms/InstCombine/select-min-max.ll Transforms/InstCombine/select-of-symmetric-selects.ll Transforms/InstCombine/select-select.ll Transforms/InstCombine/shift.ll -Transforms/InstCombine/shuffle-select-narrow-inseltpoison.ll -Transforms/InstCombine/shuffle-select-narrow.ll Transforms/InstCombine/simplify-demanded-fpclass.ll Transforms/InstCombine/sink-not-into-another-hand-of-logical-and.ll Transforms/InstCombine/sink-not-into-another-hand-of-logical-or.ll @@ -355,11 +333,8 @@ Transforms/InstCombine/sub-xor-cmp.ll Transforms/InstCombine/truncating-saturate.ll Transforms/InstCombine/unordered-fcmp-select.ll Transforms/InstCombine/urem-via-cmp-select.ll -Transforms/InstCombine/vec_sext.ll -Transforms/InstCombine/vector-urem.ll Transforms/InstCombine/wcslen-1.ll Transforms/InstCombine/wcslen-3.ll -Transforms/InstCombine/X86/blend_x86.ll Transforms/InstCombine/X86/x86-avx512-inseltpoison.ll Transforms/InstCombine/X86/x86-avx512.ll Transforms/InstCombine/xor-and-or.ll @@ -489,9 +464,6 @@ Transforms/LoopDeletion/invalidate-scev-after-hoisting.ll Transforms/LoopIdiom/AArch64/byte-compare-index.ll Transforms/LoopIdiom/AArch64/find-first-byte.ll Transforms/LoopIdiom/RISCV/byte-compare-index.ll -Transforms/LoopUnroll/peel-last-iteration-expansion-cost.ll -Transforms/LoopUnroll/peel-last-iteration-with-guards.ll -Transforms/LoopUnroll/peel-last-iteration-with-variable-trip-count.ll Transforms/LowerAtomic/atomic-load.ll Transforms/LowerAtomic/atomic-swap.ll Transforms/LowerConstantIntrinsics/builtin-object-size-phi.ll @@ -499,10 +471,6 @@ Transforms/LowerConstantIntrinsics/objectsize_basic.ll Transforms/LowerGlobalDestructors/lower-global-dtors-existing-dos_handle.ll Transforms/LowerGlobalDestructors/lower-global-dtors.ll Transforms/LowerGlobalDestructors/non-literal-type.ll -Transforms/LowerIFunc/ifunc-alias.ll -Transforms/LowerIFunc/ifunc-nonsense-resolvers.ll -Transforms/LowerIFunc/ifunc-program-addrspace.ll -Transforms/LowerIFunc/lower-ifunc.ll Transforms/LowerMatrixIntrinsics/data-layout-multiply-fused.ll Transforms/LowerMatrixIntrinsics/multiply-fused-dominance.ll Transforms/LowerMatrixIntrinsics/multiply-fused.ll @@ -522,41 +490,10 @@ Transforms/LowerSwitch/do-not-handle-impossible-values.ll Transforms/LowerSwitch/feature.ll Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll Transforms/LowerSwitch/pr59316.ll -Transforms/LowerTypeTests/aarch64-jumptable.ll -Transforms/LowerTypeTests/blockaddress-2.ll -Transforms/LowerTypeTests/blockaddress.ll -Transforms/LowerTypeTests/cfi-annotation.ll -Transforms/LowerTypeTests/cfi-coff-comdat-rename.ll -Transforms/LowerTypeTests/cfi-direct-call1.ll -Transforms/LowerTypeTests/cfi-icall-alias.ll -Transforms/LowerTypeTests/cfi-nounwind-direct-call.ll -Transforms/LowerTypeTests/cfi-unwind-direct-call.ll -Transforms/LowerTypeTests/export-alias.ll -Transforms/LowerTypeTests/export-cross-dso-cfi.ll -Transforms/LowerTypeTests/export-icall.ll -Transforms/LowerTypeTests/export-rename-local.ll -Transforms/LowerTypeTests/export-symver.ll -Transforms/LowerTypeTests/function-arm-thumb.ll -Transforms/LowerTypeTests/function-disjoint.ll -Transforms/LowerTypeTests/function-ext.ll -Transforms/LowerTypeTests/function.ll -Transforms/LowerTypeTests/function-thumb-bti.ll -Transforms/LowerTypeTests/function-weak.ll -Transforms/LowerTypeTests/icall-branch-funnel.ll -Transforms/LowerTypeTests/import.ll -Transforms/LowerTypeTests/nocfivalue.ll -Transforms/LowerTypeTests/pr37625.ll -Transforms/LowerTypeTests/section.ll -Transforms/LowerTypeTests/simple.ll -Transforms/LowerTypeTests/x86-jumptable.ll -Transforms/MemCpyOpt/memset-memcpy-dbgloc.ll -Transforms/MemCpyOpt/memset-memcpy-redundant-memset.ll -Transforms/MemCpyOpt/opaque-ptr.ll Transforms/MergeFunc/2011-02-08-RemoveEqual.ll Transforms/MergeFunc/apply_function_attributes.ll Transforms/MergeFunc/call-and-invoke-with-ranges-attr.ll Transforms/MergeFunc/call-and-invoke-with-ranges.ll -Transforms/MergeFunc/cfi-thunk-merging.ll Transforms/MergeFunc/comdat.ll Transforms/MergeFunc/crash-cast-arrays.ll Transforms/MergeFunc/crash.ll @@ -589,10 +526,6 @@ Transforms/MergeFunc/ranges-multiple.ll Transforms/MergeFunc/self-referential-global.ll Transforms/MergeFunc/unnamed-addr-reprocessing.ll Transforms/MergeFunc/vector-GEP-crash.ll -Transforms/MergeICmps/X86/alias-merge-blocks.ll -Transforms/MergeICmps/X86/entry-block-shuffled-2.ll -Transforms/MergeICmps/X86/entry-block-shuffled.ll -Transforms/MergeICmps/X86/pr59740.ll Transforms/OpenMP/always_inline_device.ll Transforms/OpenMP/custom_state_machines.ll Transforms/OpenMP/custom_state_machines_remarks.ll @@ -607,35 +540,19 @@ Transforms/OpenMP/spmdization_indirect.ll Transforms/OpenMP/spmdization.ll Transforms/OpenMP/spmdization_no_guarding_two_reaching_kernels.ll Transforms/OpenMP/spmdization_remarks.ll -Transforms/PartiallyInlineLibCalls/X86/good-prototype.ll -Transforms/PGOProfile/chr-dead-pred.ll -Transforms/PGOProfile/chr-dup-threshold.ll -Transforms/PGOProfile/chr-lifetimes.ll -Transforms/PGOProfile/chr-poison.ll Transforms/PGOProfile/comdat.ll Transforms/PGOProfile/memop_profile_funclet_wasm.ll -Transforms/PGOProfile/profcheck-select.ll -Transforms/PGOProfile/prof-verify.ll -Transforms/PGOProfile/prof-verify-no-entrycount.ll Transforms/PGOProfile/X86/macho.ll Transforms/PhaseOrdering/AArch64/constraint-elimination-placement.ll Transforms/PhaseOrdering/AArch64/globals-aa-required-for-vectorization.ll -Transforms/PhaseOrdering/AArch64/hoisting-sinking-required-for-vectorization.ll -Transforms/PhaseOrdering/AArch64/predicated-reduction.ll -Transforms/PhaseOrdering/AArch64/quant_4x4.ll -Transforms/PhaseOrdering/ARM/arm_mean_q7.ll -Transforms/PhaseOrdering/vector-select.ll -Transforms/PhaseOrdering/X86/blendv-select.ll +Transforms/PhaseOrdering/AArch64/hoist-load-from-vector-loop.ll Transforms/PhaseOrdering/X86/merge-functions2.ll Transforms/PhaseOrdering/X86/merge-functions3.ll Transforms/PhaseOrdering/X86/merge-functions.ll Transforms/PhaseOrdering/X86/pr52078.ll -Transforms/PhaseOrdering/X86/pr67803.ll Transforms/PhaseOrdering/X86/preserve-access-group.ll -Transforms/PhaseOrdering/X86/vector-reductions.ll Transforms/PreISelIntrinsicLowering/AArch64/expand-exp.ll Transforms/PreISelIntrinsicLowering/AArch64/expand-log.ll -Transforms/PreISelIntrinsicLowering/expand-vp.ll Transforms/PreISelIntrinsicLowering/PowerPC/memset-pattern.ll Transforms/PreISelIntrinsicLowering/RISCV/memset-pattern.ll Transforms/PreISelIntrinsicLowering/X86/memcpy-inline-non-constant-len.ll @@ -643,7 +560,6 @@ Transforms/PreISelIntrinsicLowering/X86/memset-inline-non-constant-len.ll Transforms/PreISelIntrinsicLowering/X86/memset-pattern.ll Transforms/SampleProfile/pseudo-probe-profile-mismatch-thinlto.ll Transforms/SampleProfile/remarks-hotness.ll -Transforms/SandboxVectorizer/special_opcodes.ll Transforms/ScalarizeMaskedMemIntrin/AArch64/expand-masked-load.ll Transforms/ScalarizeMaskedMemIntrin/AArch64/expand-masked-store.ll Transforms/ScalarizeMaskedMemIntrin/AArch64/streaming-compatible-expand-masked-gather-scatter.ll @@ -682,5 +598,3 @@ Transforms/UnifyLoopExits/switch.ll Transforms/UnifyLoopExits/undef-phis.ll Transforms/Util/libcalls-opt-remarks.ll Transforms/Util/lowerswitch.ll -Transforms/VectorCombine/AArch64/shuffletoidentity.ll -Transforms/VectorCombine/X86/shuffle-of-selects.ll diff --git a/llvm/utils/release/build_llvm_release.bat b/llvm/utils/release/build_llvm_release.bat index 3aeedaa..8bedb6e 100644 --- a/llvm/utils/release/build_llvm_release.bat +++ b/llvm/utils/release/build_llvm_release.bat @@ -190,8 +190,7 @@ if "%force-msvc%" == "" ( set common_lldb_flags=^
-DLLDB_RELOCATABLE_PYTHON=1 ^
- -DLLDB_EMBED_PYTHON_HOME=OFF ^
- -DLLDB_ENABLE_LIBXML2=OFF
+ -DLLDB_EMBED_PYTHON_HOME=OFF
set cmake_profile_flags=""
@@ -347,7 +346,7 @@ if "%arch%"=="amd64" ( set filename=clang+llvm-%version%-aarch64-pc-windows-msvc
)
cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
- -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ..\llvm-project\llvm || exit /b 1
+ -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% %llvm_src%\llvm || exit /b 1
ninja install || exit /b 1
:: check llvm_config is present & returns something
%build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1
@@ -395,7 +394,7 @@ cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install ^ -DLIBXML2_WITH_LZMA=OFF -DLIBXML2_WITH_MEM_DEBUG=OFF -DLIBXML2_WITH_MODULES=OFF ^
-DLIBXML2_WITH_OUTPUT=ON -DLIBXML2_WITH_PATTERN=OFF -DLIBXML2_WITH_PROGRAMS=OFF ^
-DLIBXML2_WITH_PUSH=OFF -DLIBXML2_WITH_PYTHON=OFF -DLIBXML2_WITH_READER=OFF ^
- -DLIBXML2_WITH_REGEXPS=OFF -DLIBXML2_WITH_RUN_DEBUG=OFF -DLIBXML2_WITH_SAX1=OFF ^
+ -DLIBXML2_WITH_REGEXPS=OFF -DLIBXML2_WITH_RUN_DEBUG=OFF -DLIBXML2_WITH_SAX1=ON ^
-DLIBXML2_WITH_SCHEMAS=OFF -DLIBXML2_WITH_SCHEMATRON=OFF -DLIBXML2_WITH_TESTS=OFF ^
-DLIBXML2_WITH_THREADS=ON -DLIBXML2_WITH_THREAD_ALLOC=OFF -DLIBXML2_WITH_TREE=ON ^
-DLIBXML2_WITH_VALID=OFF -DLIBXML2_WITH_WRITER=OFF -DLIBXML2_WITH_XINCLUDE=OFF ^
diff --git a/llvm/utils/release/github-upload-release.py b/llvm/utils/release/github-upload-release.py index d58bb54..893cda0 100755 --- a/llvm/utils/release/github-upload-release.py +++ b/llvm/utils/release/github-upload-release.py @@ -10,6 +10,9 @@ # Create and manage releases in the llvm github project. # # This script requires python3 and the PyGithub module. + +# Requirements and lockfiles can be found in llvm/utils/git/requirements.upload_release.txt.in +# and llvm/utils/git/requirements.upload_release.txt # # Example Usage: # diff --git a/llvm/utils/update_mc_test_checks.py b/llvm/utils/update_mc_test_checks.py index 791ff0d..9b80267 100755 --- a/llvm/utils/update_mc_test_checks.py +++ b/llvm/utils/update_mc_test_checks.py @@ -29,6 +29,11 @@ SUBSTITUTIONS = [ ] +class Error(Exception): + def __init__(self, test_info, line_no, msg): + super().__init__(f"{test_info.path}:{line_no}: {msg}") + + def invoke_tool(exe, check_rc, cmd_args, testline, verbose=False): substs = SUBSTITUTIONS + [(t, exe) for t in mc_LIKE_TOOLS] args = [common.applySubstitutions(cmd, substs) for cmd in cmd_args.split("|")] @@ -125,14 +130,67 @@ def getErrCheckLine(prefix, output, mc_mode, line_offset=1): ) +def parse_token_defs(test_info): + tokens = {} + current_token = None + for line_no, line in enumerate(test_info.input_lines, start=1): + # Remove comments. + line = line.split("#")[0].rstrip() + + # Skip everything up to the instructions definition. + if not tokens and not current_token and line != "// INSTS=": + continue + + if not line.startswith("//"): + break + + original_len = len(line) + line = line[2:].lstrip(" ") + indent = original_len - len(line) + + if not line: + current_token = None + continue + + # Define a new token. + if not current_token: + if indent != 4 or not line.endswith("="): + raise Error(test_info, line_no, "token definition expected") + + current_token = line[:-1].strip() + if current_token in tokens: + raise Error(test_info, line_no, f"'{current_token}' redefined") + + tokens[current_token] = [] + continue + + # Add token value. + if indent != 8: + raise Error(test_info, line_no, "wrong indentation for token value") + + tokens[current_token].append(line) + + return tokens + + +def expand_insts(tokens): + def subst(s): + for token, values in tokens.items(): + if token in s: + for value in values: + yield from subst(s.replace(token, value, 1)) + return + + yield s + + yield from subst("INSTS") + + def update_test(ti: common.TestInfo): if ti.path.endswith(".s"): mc_mode = "asm" elif ti.path.endswith(".txt"): mc_mode = "dasm" - - if ti.args.sort: - raise Exception("sorting with dasm(.txt) file is not supported!") else: common.warn("Expected .s and .txt, Skipping file : ", ti.path) return @@ -212,6 +270,14 @@ def update_test(ti: common.TestInfo): testlines = list(dict.fromkeys(testlines)) common.debug("Valid test line found: ", len(testlines)) + # Where instruction templates are specified, use them instead. + use_asm_templates = False + if mc_mode == "asm": + tokens = parse_token_defs(ti) + if "INSTS" in tokens: + testlines = list(expand_insts(tokens)) + use_asm_templates = True + raw_output = [] raw_prefixes = [] for ( @@ -247,8 +313,8 @@ def update_test(ti: common.TestInfo): raw_prefixes.append(prefixes) - output_lines = [] generated_prefixes = {} + sort_keys = {} used_prefixes = set() prefix_set = set([prefix for p in run_list for prefix in p[0]]) common.debug("Rewriting FileCheck prefixes:", str(prefix_set)) @@ -294,6 +360,17 @@ def update_test(ti: common.TestInfo): used_run_ids.update(run_ids) + # Use smallest outputs across RUN lines as sorting keys for + # disassembler tests. Sort by instruction codes if no RUN line + # produced a disassembled instruction. + if mc_mode == "dasm": + instr_outs = [ + o + for prefix, (o, run_ids) in p_dict_sorted + if o is not None and "encoding:" in o + ] + sort_keys[input_line] = min(instr_outs) if instr_outs else input_line + # Generate check lines in alphabetical order. check_lines = [] for prefix in sorted(selected_prefixes): @@ -312,14 +389,32 @@ def update_test(ti: common.TestInfo): generated_prefixes[input_line] = "\n".join(check_lines) # write output - for input_info in ti.iterlines(output_lines): - input_line = input_info.line - if input_line in testlines: - output_lines.append(input_line) - output_lines.append(generated_prefixes[input_line]) + output_lines = [] + if use_asm_templates: + # Keep all leading comments and empty lines. + for input_info in ti.iterlines(output_lines): + input_line = input_info.line + if not input_line or input_line.startswith(COMMENT[mc_mode]): + output_lines.append(input_line) + continue + break + + # Remove tail empty lines. + while not output_lines[-1]: + del output_lines[-1] + + # Emit test and check lines. + for input_line in testlines: + output_lines.extend(["", input_line, generated_prefixes[input_line]]) + else: + for input_info in ti.iterlines(output_lines): + input_line = input_info.line + if input_line in testlines: + output_lines.append(input_line) + output_lines.append(generated_prefixes[input_line]) - elif should_add_line_to_output(input_line, prefix_set, mc_mode): - output_lines.append(input_line) + elif should_add_line_to_output(input_line, prefix_set, mc_mode): + output_lines.append(input_line) if ti.args.unique or ti.args.sort: # split with double newlines @@ -367,7 +462,7 @@ def update_test(ti: common.TestInfo): line = l.split("\n")[0] # runline placed on the top - return (not isRunLine(line), line) + return (not isRunLine(line), sort_keys.get(line, line)) test_units = sorted(test_units, key=getkey) |
