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

            Bug ID: 122597
           Summary: Runtime Stack and Cpu Usage For Compile Time Constant
           Product: gcc
           Version: 15.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: terra at gnome dot org
  Target Milestone: ---

Created attachment 62731
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62731&action=edit
Preprocessed source

g++ appears to have run-time stack and cpu usage for compile-time constants.
IMHO, they ought to be free at run-time.

Consider the code:


#include <iostream>
#include <array>

constexpr
auto reallybig()
{
  std::array<int,100000> res;
  for (size_t i = 0; i < res.size(); i++)
    res[i] = i % 7;
  return res;  
}


int
c()
{
  int s = 0;
  std::cerr << "Stack pointer near " << &s << std::endl;
  return 42;
}

int
b()
{
  int s = 0;
  std::cerr << "Stack pointer near " << &s << std::endl;
  constexpr auto big = reallybig();
  switch (1) {
  case big[0]:
    std::cerr << "Hmm..." << std::endl;
    break;
  default:
    ;
  }

  for (int i : big)
    s += i;
  return s + c();
}

int
a()
{
  int s = 0;
  std::cerr << "Stack pointer near " << &s << std::endl;
  return b();
}


int
main()
{
  int v = a();
  std::cerr << "Value: " << v << std::endl;
  return 0;
}


Running this produces output that makes it clear that 400k worth of stack space
is being consumed.  (The switch is only there to convince me that the compiler
computed the array.  Not important.)

Highlights from the assembler code generated:


_Z1bv:
[...]
        andq    $-32, %rsp
        subq    $400032, %rsp               <---- stack usage
[...]
        movl    $400000, %edx
        leaq    32(%rsp), %rdi
        leaq    .LC0(%rip), %rsi
        call    memcpy@PLT                  <---- copying!
[...]
[...actually above the code...]
.LC0:
        .long   0
        .long   1
        .long   2
        .long   3
        .long   4
        .long   5
        .long   6
        .long   0
        .long   1
        .long   2
[...]



Insofar there is runtime code that needs to access the value of "big", it
should be able to access LC0 directly.



$ g++ -v
Using built-in specs.
COLLECT_GCC=/usr/local/products/gcc/15.1.0/bin/g++
COLLECT_LTO_WRAPPER=/usr/local/products/gcc/15.1.0/lib/gcc/x86_64-suse-linux/15.1.0/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../../gcc-15.1.0/configure
--enable-languages=c,c++,fortran,jit --enable-host-shared --with-pic
--enable-targets=x86_64-suse-linux,i686-suse-linux
--prefix=/usr/local/products/gcc/15.1.0 --with-gnu-as
--with-as=/usr/local/products/gcc/binutils-2.44/bin/as
--with-ld=/usr/local/products/gcc/binutils-2.44/bin/ld.gold --enable-link-mutex
--enable-gnu-indirect-functions --enable-linux-futex --enable-threads=posix
--enable-shared --enable-__cxa_atexit --enable-libstdcxx-allocator=new
x86_64-suse-linux --enable-libstdcxx-backtrace=yes --with-zstd
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.1.0 (GCC)

Reply via email to