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

            Bug ID: 118126
           Summary: GCC Compilation Performance Issue with endless
                    recursion during mangling
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: iamanonymous.cs at gmail dot com
  Target Milestone: ---

*******************************************************************************
A performance issue has been observed when compiling the provided C++ code
using GCC. The compilation takes around 20 minutes or more and not complete,
which is significantly slower than expected, especially when compared to Clang.
This issue occurs even though the code appears to be relatively standard and
does not contain overly complex constructs that should trigger long compilation
times.
The issue can also be reproduced on Compiler Explorer.

*******************************************************************************
OS and Platform:
# uname -a
Linux ubuntu 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023
x86_64 x86_64 x86_64 GNU/Linux
*******************************************************************************
# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/root/gdbtest/gcc/gcc-241217/libexec/gcc/x86_64-pc-linux-gnu/15.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc/configure --prefix=/root/gdbtest/gcc/gcc-241217
--enable-languages=c,c++ --disable-multilib --disable-bootstra
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.0.0 20241217 (experimental) (GCC) 
*******************************************************************************
Program:
#cat Z.C
 typedef int octave_idx_type;
 extern "C" double sqrt (double);
 namespace std
 {
   double abs (double __x)
   {
     return __builtin_fabs (__x);
   }
   using::sqrt;
   template <typename _Tp> _Tp &max (_Tp &__a, _Tp &__b)
   {
     if (__a < __b)
       return __b;
     return __a;
   }
 }

 extern "C" int __lo_ieee_isinf (double);
 extern "C" int __lo_ieee_float_isinf ();

 class dim_vector
 {
 protected:class dim_vector_rep
   {
   public:octave_idx_type dims;
     int count;
   dim_vector_rep (octave_idx_type r, octave_idx_type):dims (), count ()
     {
     }
   };
   dim_vector_rep * rep;
 private:dim_vector_rep nil_rep ()
   {
   }
 public:
   dim_vector ()
   {
   }
 dim_vector (octave_idx_type r, octave_idx_type c):rep
     (new
      dim_vector_rep (r, c))
   {
   }
   ~dim_vector ()
   {
     delete rep;
   }
 };
 namespace std
 {
   struct __numeric_limits_base
   {
   };
   template <typename _Tp> struct numeric_limits:public __numeric_limits_base
   {
     static _Tp epsilon () throw ()
     {
     }
   };
 }

 template <class T> class Array
 {
 protected:class ArrayRep
   {
   public:T * data;
     int count;
   ArrayRep (octave_idx_type n):data (new T[n]), count ()
     {
     }
   };
   Array::ArrayRep * rep;
   dim_vector dimensions;
   T slice_data;
   octave_idx_type slice_len;
 public: Array (dim_vector dv):rep
     (new Array <T>::ArrayRep (get_size (dv)))
   {
   }
 Array (dim_vector dv, T):rep
     (Array
      <T>::ArrayRep (get_size ())), dimensions ()
   {
   }
   octave_idx_type capacity ()
   {
     return slice_len;
   }
   octave_idx_type nelem ()
   {
     return capacity ();
   }
   octave_idx_type numel ()
   {
     return nelem ();
   }
   octave_idx_type get_size (dim_vector);
   T xelem (octave_idx_type n)
   {
     slice_data[n];
   }
   T elem ()
   {
     xelem ();
   }
   T operator ()()
   {
     elem ();
   }
 };
 template <class T> class Array2:public Array <T>
 {
 public:
 Array2 ():Array <T> (dim_vector (0, 0))
   {
   }
 Array2 (octave_idx_type r, octave_idx_type c):Array
     <T> (dim_vector (r, c))
   {
   }
 Array2 (octave_idx_type r, octave_idx_type c, T):Array
     <T> (dim_vector ())
   {
   }
 };
 template <class T> class MArray2:public Array2 <T>
 {
 public: MArray2 ():Array2 <T> ()
   {
   }
 MArray2 (octave_idx_type n, octave_idx_type m):Array2 <T> (n, m)
   {
   }
 MArray2 (octave_idx_type n, octave_idx_type m, T):Array2 <T> ()
   {
   }
 };
 template <class T> class MArray:public Array <T>
 {
 };
 class Matrix:public MArray2 <double>
 {
 public:typedef void (solve_singularity_handler) ();
     Matrix ():MArray2 <double>()
   {
   }
   Matrix (octave_idx_type r, octave_idx_type c):MArray2 <double>(r, c)
   {
   }
   Matrix (octave_idx_type r, octave_idx_type c, double val):MArray2 (r, val)
   {
   }
 };
 class ColumnVector:public MArray <double>
 {
 };
 template <class T> class Sparse
 {
 protected:class SparseRep
   {
   };
 public:typename Sparse <T>::SparseRep rep;
   octave_idx_type rows ()
   {
   }
 };
 template <class T> class MSparse:public Sparse <T>
 {
 };
 class SparseMatrix:public MSparse <double>
 {
 };
 template <class R> class norm_accumulator_2
 {
   R scl, sum;
 public:
 norm_accumulator_2 ():scl (), sum ()
   {
   }
   void accum (R val)
   {
     R t = std::abs (val);
     if (scl == t)
       sum += 1;
   }
   operator R ()
   {
     sqrt (sum);
   }
 };
 template <class R> class norm_accumulator_1
 {
   R sum;
 public:
 norm_accumulator_1 ():sum ()
   {
   }
   template <class U> void accum (U val)
   {
     sum += std::abs (val);
   }
   operator R ()
   {;
   }
 };
 template <class R> class norm_accumulator_inf
 {
   R max;
 public:
 norm_accumulator_inf ():max ()
   {
   }
   template <class U> void accum (U val)
   {
     double m = std::abs (val);
     max = std::max (max, m);
   }
   operator R ()
   {
     return max;
   }
 };
 template <class R> class norm_accumulator_0
 {
   unsigned num;
 public:
 norm_accumulator_0 ():num ()
   {
   }
   template <class U> void accum (U)
   {
   }
   operator R ()
   {
     return num;
   }
 };
 template <class T, class R, class ACC> void vector_norm (Array <T> &v, R &res,
ACC acc)
 {
   for (octave_idx_type i = 0; i < v.numel (); i++)
     acc.accum ((i));
   res = acc;
 }

 template <class T, class R> R vector_norm (MArray <T> &v, R)
 {
   R res;
   vector_norm (v, norm_accumulator_2 <R> ());
 }

 template <class T, class R> R vector_norm (MArray2 <T> &v, R p)
 {
   R res;
   if (p == 2)
     vector_norm (v, res, norm_accumulator_2 <R> ());
   else if (p == 1)
     vector_norm (v, res, norm_accumulator_1 <R> ());
   else if (((p) == sizeof (float) ? (p) : __lo_ieee_isinf (p)))
     {
       if (p> 0)
        vector_norm (v, res, norm_accumulator_inf <R> ());
     }
   else if (p == 0)
     vector_norm (v, res, norm_accumulator_0 <R> ());
   return res;
 }

 template <class MatrixT, class VectorT, class R>
 R higham (MatrixT m, R p, R tol, int maxiter, VectorT)
 {
   VectorT y (m.rows (), 0), z (m.rows (), 1);
   R q;
   R gamma = 0, gamma1;
   int iter;
   while (maxiter)
     {
       gamma = vector_norm (y, p);
       (iter> 0 && (vector_norm (z, q) <= (gamma1) <= gamma));
     }
 }

 int max_norm_iter = 100;
 template <class MatrixT, class VectorT, class R> R matrix_norm (MatrixT m, R
p, VectorT)
 {
   R res = 0;
   {
     VectorT x;
     R sqrteps (std::numeric_limits <R>::epsilon ());
     higham (m, p, sqrteps, max_norm_iter, x);
   }
 }

 double xnorm (ColumnVector x, double p)
 {
   vector_norm (x, p);
 }

 double xnorm (SparseMatrix x, double p)
 {
   matrix_norm (x, p, Matrix ());
 }

*******************************************************************************
Command Lines:
 g++ Z.C  -fno-tree-copy-prop -fno-tree-vrp -fno-immediate-escalation
-fno-implicit-templates -funroll-loops -flto  -Wall -Wextra 
-fno-strict-aliasing  -fwrapv -g -fsanitize=address   -c -o Z.o

Steps to Reproduce:
1.Compile the above code using GCC trunk.
2.Observe the slow compilation time. (https://godbolt.org/z/P9W3hY5Mz)
3.Compile the same code using Clang and notice the much faster compilation.
(https://godbolt.org/z/n9Y96vjMs)

Expected Behavior: The code should compile within a reasonable time frame,
similar to Clang.
Actual Behavior: The compilation on GCC trunk takes over 20 minutes and still
does not complete.

Please let me know if you need further details or if there are specific flags
to help debug this issue,thanks!
*******************************************************************************

Reply via email to