Index: llvm/trunk/utils/TableGen/CodeGenSchedule.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenSchedule.cpp +++ llvm/trunk/utils/TableGen/CodeGenSchedule.cpp @@ -82,8 +82,10 @@ Target.getInstructionsByEnumValue(); unsigned NumGeneric = Target.getNumFixedInstructions(); + unsigned NumPseudos = Target.getNumPseudoInstructions(); auto Generics = Instructions.slice(0, NumGeneric); - auto NonGenerics = Instructions.slice(NumGeneric); + auto Pseudos = Instructions.slice(NumGeneric, NumPseudos); + auto NonPseudos = Instructions.slice(NumGeneric + NumPseudos); for (Init *Arg : make_range(Expr->arg_begin(), Expr->arg_end())) { StringInit *SI = dyn_cast(Arg); @@ -125,8 +127,9 @@ } } - // Target instructions are sorted. Find the range that starts with our - // prefix. + // Target instructions are split into two ranges: pseudo instructions + // first, than non-pseudos. Each range is in lexicographical order + // sorted by name. Find the sub-ranges that start with our prefix. struct Comp { bool operator()(const CodeGenInstruction *LHS, StringRef RHS) { return LHS->TheDef->getName() < RHS; @@ -136,11 +139,13 @@ !RHS->TheDef->getName().startswith(LHS); } }; - auto Range = std::equal_range(NonGenerics.begin(), NonGenerics.end(), - Prefix, Comp()); + auto Range1 = + std::equal_range(Pseudos.begin(), Pseudos.end(), Prefix, Comp()); + auto Range2 = std::equal_range(NonPseudos.begin(), NonPseudos.end(), + Prefix, Comp()); - // For this range we know that it starts with the prefix. Check if there's - // a regex that needs to be checked. + // For these ranges we know that instruction names start with the prefix. + // Check if there's a regex that needs to be checked. const auto HandleNonGeneric = [&](const CodeGenInstruction *Inst) { StringRef InstName = Inst->TheDef->getName(); if (!Regexpr || Regexpr->match(InstName.substr(Prefix.size()))) { @@ -148,7 +153,8 @@ NumMatches++; } }; - std::for_each(Range.first, Range.second, HandleNonGeneric); + std::for_each(Range1.first, Range1.second, HandleNonGeneric); + std::for_each(Range2.first, Range2.second, HandleNonGeneric); if (0 == NumMatches) PrintFatalError(Loc, "instregex has no matches: " + Original); Index: llvm/trunk/utils/TableGen/CodeGenTarget.h =================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.h +++ llvm/trunk/utils/TableGen/CodeGenTarget.h @@ -62,6 +62,7 @@ mutable std::unique_ptr SchedModels; mutable std::vector InstrsByEnum; + mutable unsigned NumPseudoInstructions = 0; public: CodeGenTarget(RecordKeeper &Records); ~CodeGenTarget(); @@ -148,8 +149,19 @@ /// Returns the number of predefined instructions. static unsigned getNumFixedInstructions(); + /// Returns the number of pseudo instructions. + unsigned getNumPseudoInstructions() const { + if (InstrsByEnum.empty()) + ComputeInstrsByEnum(); + return NumPseudoInstructions; + } + /// Return all of the instructions defined by the target, ordered by their /// enum value. + /// The following order of instructions is also guaranteed: + /// - fixed / generic instructions as declared in TargetOpcodes.def, in order; + /// - pseudo instructions in lexicographical order sorted by name; + /// - other instructions in lexicographical order sorted by name. ArrayRef getInstructionsByEnumValue() const { if (InstrsByEnum.empty()) ComputeInstrsByEnum(); Index: llvm/trunk/utils/TableGen/CodeGenTarget.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenTarget.cpp +++ llvm/trunk/utils/TableGen/CodeGenTarget.cpp @@ -374,19 +374,24 @@ for (const auto &I : Insts) { const CodeGenInstruction *CGI = I.second.get(); - if (CGI->Namespace != "TargetOpcode") + if (CGI->Namespace != "TargetOpcode") { InstrsByEnum.push_back(CGI); + if (CGI->TheDef->getValueAsBit("isPseudo")) + ++NumPseudoInstructions; + } } assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr"); // All of the instructions are now in random order based on the map iteration. - // Sort them by name. - llvm::sort(InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(), - [](const CodeGenInstruction *Rec1, - const CodeGenInstruction *Rec2) { - return Rec1->TheDef->getName() < Rec2->TheDef->getName(); - }); + llvm::sort( + InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(), + [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) { + const auto &D1 = *Rec1->TheDef; + const auto &D2 = *Rec2->TheDef; + return std::make_tuple(!D1.getValueAsBit("isPseudo"), D1.getName()) < + std::make_tuple(!D2.getValueAsBit("isPseudo"), D2.getName()); + }); }