This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/67565] [concepts] Very slow compile time and high memory usage with complex concept definitions, even if unused


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67565

Tom Honermann <tom at honermann dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrew.n.sutton at gmail dot com,
                   |                            |asutton at gcc dot gnu.org,
                   |                            |tom at honermann dot net

--- Comment #2 from Tom Honermann <tom at honermann dot net> ---
I'm also experiencing this issue and finding it to be rather catastrophic at
present.  I'm currently using gcc trunk (r232017).

I distilled the following test case from my project before coming across this
bug report.  The test cases shares some properties with the one in comment 0;
no actual instantiations of the class template (or function for Adrian's test
case) are needed to trigger the issue, both conjunctions and disjunctions are
present.

This test case includes some conditional compilation options intended to
demonstrate that syntactic transformations that should have no semantic affect
have dramatic compile time performance impact; search for GO_FAST1 and
GO_FAST2.  Additionally, defining the GO_SLOWER1 macro demonstrates a means of
scaling the performance impact.

$ cat t.cpp
$ cat t.cpp
template<typename T>
concept bool
C1()
{
  return sizeof(T) > 4;
}

template<typename T>
constexpr bool
f1()
{
  return C1<T>();
}

template<typename T>
constexpr bool
f2()
{
  return f1<T>()
      || f1<T>()
      || f1<T>()
      || f1<T>()
      || f1<T>();
}

template<typename T>
concept bool
C2()
{
#if GO_FAST1
  return f2<T>();
#else
  return f1<T>()
      || f1<T>()
      || f1<T>()
      || f1<T>()
#if GO_SLOWER1
      || f1<T>()
#endif
      || f1<T>();
#endif
}

template<typename T>
concept bool C3() {
    return C2<T>()
        && (C1<T>()
            || C1<T>()
            || C1<T>());
}

template<typename T>
concept bool C4() {
    return C3<typename T::type1>()
        && C3<typename T::type2>();
}

template<typename T>
concept bool C5() {
    return C4<T>();
}

template<typename T>
concept bool C6() {
    return C5<T>()
        && true;
}

#if GO_FAST2
template<typename C>
requires C4<C>()
      && C5<C>()
      && C6<C>()
#else
template<C4 C>
requires C5<C>()
      && C6<C>()
#endif
struct S {
};


$ time g++ -c -std=c++1z t.cpp
real    0m9.485s
user    0m8.672s
sys     0m0.820s

$ time g++ -c -std=c++1z t.cpp -DGO_FAST1
real    0m0.027s
user    0m0.008s
sys     0m0.008s

$ time g++ -c -std=c++1z t.cpp -DGO_FAST2
real    0m0.064s
user    0m0.056s
sys     0m0.000s

$ time g++ -c -std=c++1z t.cpp -DGO_SLOWER1
real    0m30.464s
user    0m26.100s
sys     0m2.832s

The GO_SLOWER1 test peaks at about 10G of virtual memory for me.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]