On Fri, Apr 25, 2025 at 9:47 PM Jonathan Wakely <jwak...@redhat.com> wrote:
> This will hardly make a dent in the very slow compile times for <regex> > but it seems worth doing anyway. > > libstdc++-v3/ChangeLog: > > * include/bits/regex_compiler.h (_AnyMatcher::operator()): > Replace tag dispatching with 'if constexpr'. > (_AnyMatcher::_M_apply): Remove both overloads. > (_BracketMatcher::operator(), _BracketMatcher::_M_ready): > Replace tag dispatching with 'if constexpr'. > (_BracketMatcher::_M_apply(_CharT, true_type)): Remove. > (_BracketMatcher::_M_apply(_CharT, false_type)): Remove second > parameter. > (_BracketMatcher::_M_make_cache): Remove both overloads. > * include/bits/regex_compiler.tcc (_BracketMatcher::_M_apply): > Remove second parameter. > --- > > Tested x86_64-linux. > > libstdc++-v3/include/bits/regex_compiler.h | 59 +++++++++----------- > libstdc++-v3/include/bits/regex_compiler.tcc | 2 +- > 2 files changed, 26 insertions(+), 35 deletions(-) > > diff --git a/libstdc++-v3/include/bits/regex_compiler.h > b/libstdc++-v3/include/bits/regex_compiler.h > index f24c7e3baa6..3931790091a 100644 > --- a/libstdc++-v3/include/bits/regex_compiler.h > +++ b/libstdc++-v3/include/bits/regex_compiler.h > @@ -376,26 +376,21 @@ namespace __detail > > bool > operator()(_CharT __ch) const > - { return _M_apply(__ch, typename is_same<_CharT, char>::type()); } > - > - bool > - _M_apply(_CharT __ch, true_type) const > { > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr > auto __c = _M_translator._M_translate(__ch); > auto __n = _M_translator._M_translate('\n'); > auto __r = _M_translator._M_translate('\r'); > - return __c != __n && __c != __r; > - } > - > - bool > - _M_apply(_CharT __ch, false_type) const > - { > - auto __c = _M_translator._M_translate(__ch); > - auto __n = _M_translator._M_translate('\n'); > - auto __r = _M_translator._M_translate('\r'); > - auto __u2028 = _M_translator._M_translate(u'\u2028'); > - auto __u2029 = _M_translator._M_translate(u'\u2029'); > - return __c != __n && __c != __r && __c != __u2028 && __c != > __u2029; > Could we implement this as, to avoid calling _M_translate when not necessary? ``` if (__c == __n || __c == __r) return false; if constexpr (!is_same<_CharT, char>::value) { auto __ls = _M_translator._M_translate(u'\u2028'); // line sep auto __ps = _M_translator._M_translate(u'\u2029'); // para sep return __c != __ls && __c != __ps; } return true; ``` > + if constexpr (is_same<_CharT, char>::value) > + return __c != __n && __c != __r; > + else > + { > + auto __ls = _M_translator._M_translate(u'\u2028'); // line sep > + auto __ps = _M_translator._M_translate(u'\u2029'); // para sep > + return __c != __n && __c != __r && __c != __ls && __c != __ps; > + } > +#pragma GCC diagnostic pop > } > > _TransT _M_translator; > @@ -440,8 +435,14 @@ namespace __detail > bool > operator()(_CharT __ch) const > { > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr > _GLIBCXX_DEBUG_ASSERT(_M_is_ready); > - return _M_apply(__ch, _UseCache()); > + if constexpr (_UseCache::value) > + if (!(__ch & 0x80)) [[__likely__]] > + return _M_cache[static_cast<_UnsignedCharT>(__ch)]; > + return _M_apply(__ch); > +#pragma GCC diagnostic pop > } > > void > @@ -509,11 +510,16 @@ namespace __detail > void > _M_ready() > { > +#pragma GCC diagnostic push > +#pragma GCC diagnostic ignored "-Wc++17-extensions" // if constexpr > std::sort(_M_char_set.begin(), _M_char_set.end()); > auto __end = std::unique(_M_char_set.begin(), _M_char_set.end()); > _M_char_set.erase(__end, _M_char_set.end()); > - _M_make_cache(_UseCache()); > + if constexpr (_UseCache::value) > + for (unsigned __i = 0; __i < 128; __i++) // Only cache 7-bit > chars > + _M_cache[__i] = _M_apply(static_cast<_CharT>(__i)); > _GLIBCXX_DEBUG_ONLY(_M_is_ready = true); > +#pragma GCC diagnostic pop > } > > private: > @@ -531,22 +537,7 @@ namespace __detail > using _UnsignedCharT = typename std::make_unsigned<_CharT>::type; > > bool > - _M_apply(_CharT __ch, false_type) const; > - > - bool > - _M_apply(_CharT __ch, true_type) const > - { return _M_cache[static_cast<_UnsignedCharT>(__ch)]; } > - > - void > - _M_make_cache(true_type) > - { > - for (unsigned __i = 0; __i < _M_cache.size(); __i++) > - _M_cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type()); > - } > - > - void > - _M_make_cache(false_type) > - { } > + _M_apply(_CharT __ch) const; > > private: > _GLIBCXX_STD_C::vector<_CharT> _M_char_set; > diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc > b/libstdc++-v3/include/bits/regex_compiler.tcc > index cd0db2761b5..59b79fdd106 100644 > --- a/libstdc++-v3/include/bits/regex_compiler.tcc > +++ b/libstdc++-v3/include/bits/regex_compiler.tcc > @@ -598,7 +598,7 @@ namespace __detail > template<typename _TraitsT, bool __icase, bool __collate> > bool > _BracketMatcher<_TraitsT, __icase, __collate>:: > - _M_apply(_CharT __ch, false_type) const > + _M_apply(_CharT __ch) const > { > return [this, __ch] > { > -- > 2.49.0 > >