From 10d5949495fa093bf928011d4331166f94b818a6 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Tue, 20 Mar 2018 22:20:28 +0000 Subject: [PATCH] [SchedModel] Simplify InstRegexOp::apply. NFCI. As discussed on D44687, there was no need for 2 separate for loops for collecting the Regex and then matching against instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@328052 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenSchedule.cpp | 51 ++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp index f0482f4069d..f7420cf8d20 100644 --- a/utils/TableGen/CodeGenSchedule.cpp +++ b/utils/TableGen/CodeGenSchedule.cpp @@ -77,39 +77,42 @@ struct InstRegexOp : public SetTheory::Operator { void apply(SetTheory &ST, DagInit *Expr, SetTheory::RecSet &Elts, ArrayRef Loc) override { - SmallVector>, 4> RegexList; for (Init *Arg : make_range(Expr->arg_begin(), Expr->arg_end())) { StringInit *SI = dyn_cast(Arg); if (!SI) PrintFatalError(Loc, "instregex requires pattern string: " + Expr->getAsString()); + StringRef Original = SI->getValue(); + // Extract a prefix that we can binary search on. static const char RegexMetachars[] = "()^$|*+?.[]\\{}"; - auto FirstMeta = SI->getValue().find_first_of(RegexMetachars); + auto FirstMeta = Original.find_first_of(RegexMetachars); + // Look for top-level | or ?. We cannot optimize them to binary search. - if (removeParens(SI->getValue()).find_first_of("|?") != std::string::npos) + if (removeParens(Original).find_first_of("|?") != std::string::npos) FirstMeta = 0; - StringRef Prefix = SI->getValue().substr(0, FirstMeta); - std::string pat = SI->getValue().substr(FirstMeta); - if (pat.empty()) { - RegexList.push_back(std::make_pair(Prefix, None)); - continue; - } - // For the rest use a python-style prefix match. - if (pat[0] != '^') { - pat.insert(0, "^("); - pat.insert(pat.end(), ')'); + + Optional Regexpr = None; + StringRef Prefix = Original.substr(0, FirstMeta); + std::string pat = Original.substr(FirstMeta); + if (!pat.empty()) { + // For the rest use a python-style prefix match. + if (pat[0] != '^') { + pat.insert(0, "^("); + pat.insert(pat.end(), ')'); + } + Regexpr = Regex(pat); } - RegexList.push_back(std::make_pair(Prefix, Regex(pat))); - } - for (auto &R : RegexList) { + unsigned NumGeneric = Target.getNumFixedInstructions(); + ArrayRef Generics = + Target.getInstructionsByEnumValue().slice(0, NumGeneric + 1); + // The generic opcodes are unsorted, handle them manually. - for (auto *Inst : - Target.getInstructionsByEnumValue().slice(0, NumGeneric + 1)) { - if (Inst->TheDef->getName().startswith(R.first) && - (!R.second || - R.second->match(Inst->TheDef->getName().substr(R.first.size())))) + for (auto *Inst : Generics) { + StringRef InstName = Inst->TheDef->getName(); + if (InstName.startswith(Prefix) && + (!Regexpr || Regexpr->match(InstName.substr(Prefix.size())))) Elts.insert(Inst->TheDef); } @@ -128,13 +131,13 @@ struct InstRegexOp : public SetTheory::Operator { } }; auto Range = std::equal_range(Instructions.begin(), Instructions.end(), - R.first, Comp()); + 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 (auto *Inst : make_range(Range)) { - if (!R.second || - R.second->match(Inst->TheDef->getName().substr(R.first.size()))) + StringRef InstName = Inst->TheDef->getName(); + if (!Regexpr || Regexpr->match(InstName.substr(Prefix.size()))) Elts.insert(Inst->TheDef); } } -- 2.11.0