diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-09 13:28:42 +0000 |
| commit | b1c73532ee8997fe5dfbeb7d223027bdf99758a0 (patch) | |
| tree | 7d6e51c294ab6719475d660217aa0c0ad0526292 /llvm/utils/TableGen/CodeGenSchedule.cpp | |
| parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) | |
Diffstat (limited to 'llvm/utils/TableGen/CodeGenSchedule.cpp')
| -rw-r--r-- | llvm/utils/TableGen/CodeGenSchedule.cpp | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp index 04219a6e54d9..54463da19821 100644 --- a/llvm/utils/TableGen/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/CodeGenSchedule.cpp @@ -91,10 +91,25 @@ struct InstRegexOp : public SetTheory::Operator { PrintFatalError(Loc, "instregex requires pattern string: " + Expr->getAsString()); StringRef Original = SI->getValue(); + // Drop an explicit ^ anchor to not interfere with prefix search. + bool HadAnchor = Original.consume_front("^"); // Extract a prefix that we can binary search on. static const char RegexMetachars[] = "()^$|*+?.[]\\{}"; auto FirstMeta = Original.find_first_of(RegexMetachars); + if (FirstMeta != StringRef::npos && FirstMeta > 0) { + // If we have a regex like ABC* we can only use AB as the prefix, as + // the * acts on C. + switch (Original[FirstMeta]) { + case '+': + case '*': + case '?': + --FirstMeta; + break; + default: + break; + } + } // Look for top-level | or ?. We cannot optimize them to binary search. if (removeParens(Original).find_first_of("|?") != std::string::npos) @@ -106,7 +121,10 @@ struct InstRegexOp : public SetTheory::Operator { if (!PatStr.empty()) { // For the rest use a python-style prefix match. std::string pat = std::string(PatStr); - if (pat[0] != '^') { + // Add ^ anchor. If we had one originally, don't need the group. + if (HadAnchor) { + pat.insert(0, "^"); + } else { pat.insert(0, "^("); pat.insert(pat.end(), ')'); } @@ -118,7 +136,7 @@ struct InstRegexOp : public SetTheory::Operator { // The generic opcodes are unsorted, handle them manually. for (auto *Inst : Generics) { StringRef InstName = Inst->TheDef->getName(); - if (InstName.startswith(Prefix) && + if (InstName.starts_with(Prefix) && (!Regexpr || Regexpr->match(InstName.substr(Prefix.size())))) { Elts.insert(Inst->TheDef); NumMatches++; @@ -134,7 +152,7 @@ struct InstRegexOp : public SetTheory::Operator { } bool operator()(StringRef LHS, const CodeGenInstruction *RHS) { return LHS < RHS->TheDef->getName() && - !RHS->TheDef->getName().startswith(LHS); + !RHS->TheDef->getName().starts_with(LHS); } }; auto Range1 = @@ -369,19 +387,20 @@ processSTIPredicate(STIPredicateFunction &Fn, const std::pair<APInt, APInt> &LhsMasks = OpcodeMasks[LhsIdx]; const std::pair<APInt, APInt> &RhsMasks = OpcodeMasks[RhsIdx]; - auto LessThan = [](const APInt &Lhs, const APInt &Rhs) { - unsigned LhsCountPopulation = Lhs.popcount(); - unsigned RhsCountPopulation = Rhs.popcount(); - return ((LhsCountPopulation < RhsCountPopulation) || - ((LhsCountPopulation == RhsCountPopulation) && - (Lhs.countl_zero() > Rhs.countl_zero()))); + auto PopulationCountAndLeftBit = + [](const APInt &Other) -> std::pair<int, int> { + return std::pair<int, int>(Other.popcount(), + -Other.countl_zero()); }; + auto lhsmask_first = PopulationCountAndLeftBit(LhsMasks.first); + auto rhsmask_first = PopulationCountAndLeftBit(RhsMasks.first); + if (lhsmask_first != rhsmask_first) + return lhsmask_first < rhsmask_first; - if (LhsMasks.first != RhsMasks.first) - return LessThan(LhsMasks.first, RhsMasks.first); - - if (LhsMasks.second != RhsMasks.second) - return LessThan(LhsMasks.second, RhsMasks.second); + auto lhsmask_second = PopulationCountAndLeftBit(LhsMasks.second); + auto rhsmask_second = PopulationCountAndLeftBit(RhsMasks.second); + if (lhsmask_second != rhsmask_second) + return lhsmask_second < rhsmask_second; return LhsIdx < RhsIdx; }); |
