https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65848
Bug ID: 65848 Summary: [c++-concepts] High memory usage and compilation times for subsuming concept chains; regression from r211824 Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tom at honermann dot net The following test case demonstrates high CPU and memory utilization during compilation when compiled with gcc r222238. I have an old gcc build (r211824) that compiles this test case quickly with low memory usage. Details are below the test case. The performance issue depends on use of the type trait templates. Replacing references to them with 'true' suffices to enable the code to be quickly compiled (though possibly with still higher resource usage then with an r211824 build, I didn't measure). Likewise, reducing the length of the CN<T> concept chain or the number of types for which concepts are asserted has an exponential effect on resource usage. Increasing the length of the concept chain much further results in compilations that will not complete successfully on my modest hardware (Lenovo T420 laptop with 8GB ram). I attempted to remove the dependency on the type_traits header, but the number of entities I would have needed to add to the test case below would have made the test case much longer. Simplifying their implementation to keep the test case small greatly reduced resource usage. It seems their implementation is relevant to the issue. $ cat t.cpp #include <type_traits> template<typename T> concept bool Destructible() { return std::is_destructible<T>::value; } template<typename T, typename... Args> concept bool Constructible() { return Destructible<T>() && std::is_constructible<T, Args...>::value; } template<typename T> concept bool Move_constructible() { return Constructible<T, T&&>(); } template<typename T> concept bool Copy_constructible() { return Move_constructible<T>() && Constructible<T, const T&>(); } template<typename T, typename U> concept bool Assignable() { return std::is_assignable<T, U>::value; } template<typename T> concept bool Move_assignable() { return Assignable<T&, T&&>(); } template<typename T> concept bool Copy_assignable() { return Move_assignable<T>() && Assignable<T&, const T&>(); } template<typename T> concept bool Copyable() { return Copy_constructible<T>() && Copy_assignable<T>(); } template<typename T> concept bool C1() { return Copyable<T>(); } template<typename T> concept bool C2() { return C1<T>(); } template<typename T> concept bool C3() { return C2<T>(); } template<typename T> concept bool C4() { return C3<T>(); } template<typename T> concept bool C5() { return C4<T>(); } template<typename T> concept bool C6() { return C5<T>(); } template<typename T> concept bool C7() { return C6<T>(); } template<typename T> concept bool C8() { return C7<T>(); } template<typename T> concept bool C9() { return C8<T>(); } template<typename T> concept bool C10() { return C9<T>(); } template<typename T> concept bool C11() { return C10<T>(); } struct S1 {}; struct S2 {}; struct S3 {}; struct S4 {}; struct S5 {}; struct S6 {}; static_assert(C11<S1>(), ""); static_assert(C11<S2>(), ""); static_assert(C11<S3>(), ""); static_assert(C11<S4>(), ""); static_assert(C11<S5>(), ""); static_assert(C11<S6>(), ""); $ svn info # From my local svn gcc repo. Path: . URL: svn://gcc.gnu.org/svn/gcc/branches/c++-concepts Repository Root: svn://gcc.gnu.org/svn/gcc Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4 Revision: 222238 Node Kind: directory Schedule: normal Last Changed Author: asutton Last Changed Rev: 222236 Last Changed Date: 2015-04-20 09:43:31 -0400 (Mon, 20 Apr 2015) Timing details for both the r222238 gcc build above and an old r211824 based build follow. The timing data was produced by /usr/bin/time on an Ubuntu 12.04 system. The data below was produced with a hot cache in each case. # Using gcc r222238, compilation time and memory usage is significant: $ /usr/bin/time -v g++ -c -std=c++1z t.cpp Command being timed: "g++ -c -std=c++1z t.cpp" User time (seconds): 17.73 System time (seconds): 0.88 Percent of CPU this job got: 99% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:18.67 ... Maximum resident set size (kbytes): 8409216 ... Minor (reclaiming a frame) page faults: 527712 ... # Using an old gcc r211824, compilation completes quickly (note # that this old build required -std=c++1y to enable support for concepts). $ /usr/bin/time -v g++ -c -std=c++1y t.cpp Command being timed: "g++ -c -std=c++1y t.cpp" User time (seconds): 0.05 System time (seconds): 0.00 Percent of CPU this job got: 88% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.06 ... Maximum resident set size (kbytes): 63936 ... Minor (reclaiming a frame) page faults: 6107 ...