[GlobalISel][Tablegen] Assign small opcodes to pseudos
Sort pseudo instructions first while emitting enum's for target
instructions info. That puts them close to each other and to generic
G_* opcodes for GlobalISel. This makes it easier to build small jump
tables over opcodes that could be directly embedded into MatchTable's
Tablegen'erated for GlobalISel's InstructionSelect.
Reviewed By: bogner
Differential Revision: https://reviews.llvm.org/D47240
llvm-svn: 333135
diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp
index ea22ce6..9331fad 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/llvm/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<StringInit>(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);