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

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #16 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Stepping through the constexpr evaluation of the reduced comment #14 testcase,
I noticed a lot of unnecessary casts when passing a reference argument to a
reference parameter of the same type, e.g. for

  void f(int&);
  void g(int& x) { f(x); }

we represent the call as

  f ((int &) (int *) x);

(at least until it goes through cp_fold which gets rid of the unnecessary casts
but sometimes we may attempt constexpr folding before cp_fold).

Constexpr evaluation of these unnecessary casts seems to create a ton of
garbage.  Avoiding creating these unnecessary casts in the first place with
e.g.

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index c1c8987ec8b..ff84d6591fa 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -9280,6 +9280,9 @@ convert_like_internal (conversion *convs, tree expr, tree
fn, int argnum,
            expr = build_target_expr_with_type (expr, type, complain);
          }

+       if (REFERENCE_REF_P (expr))
+         return cp_convert (ref_type, TREE_OPERAND (expr, 0), complain);
+
        /* Take the address of the thing to which we will bind the
           reference.  */
        expr = cp_build_addr_expr (expr, complain);

helps a lot memory-wise.  For the original testcase (with -g), memory use drops
from ~7GB to ~4GB and compile time from ~6m to ~2m!  For the reduced testcase,
memory use drops 300MB to 80MB.

Unfortunately the above patch causes FAILs in g++.dg/init/elide6.C and some
-Wredundant-move tests, which I haven't looked into closely but I think they
can be resolved.

Reply via email to