On 10/2/24 7:50 AM, Richard Biener wrote:
This reduces peak memory usage by 20% for a specific testcase.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

It's very ugly so I'd appreciate suggestions on how to handle such
situations better?

gcc/cp/
        * pt.cc (coerce_template_parms): Release expanded argument
        vector when not needed.
---
  gcc/cp/pt.cc | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 04f0a1d5fff..2c8b0d8609d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -9442,6 +9442,9 @@ coerce_template_parms (tree parms,
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_inner_args,
                                         TREE_VEC_LENGTH (new_inner_args));
+ if ((return_full_args ? new_args != inner_args : new_inner_args != inner_args)

I think we always want to compare new_inner_args != inner_args, regardless of return_full_args. OK with that change.

Alternatively we could use std::unique_ptr or something like it for inner_args, as the attached (untested). This isn't very idiomatic use of unique_ptr, a custom class might be better...

Jason
commit ff16a607f8ba21bc8591f6b7476d1fc4abff693e
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Oct 2 08:17:19 2024 -0400

    unique

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 5178e4deec0..b801014e739 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "config.h"
 #define INCLUDE_ALGORITHM // for std::equal
+#define INCLUDE_MEMORY // for std::unique_ptr
 #include "system.h"
 #include "coretypes.h"
 #include "cp-tree.h"
@@ -9079,6 +9080,11 @@ pack_expansion_args_count (tree args)
   return count;
 }
 
+struct ggc_freer
+{
+  void operator()(void *p) { ggc_free (p); }
+};
+
 /* Convert all template arguments to their appropriate types, and
    return a vector containing the innermost resulting template
    arguments.  If any error occurs, return error_mark_node. Error and
@@ -9161,8 +9167,13 @@ coerce_template_parms (tree parms,
      with a nested class inside a partial specialization of a class
      template, as in variadic92.C, or when deducing a template parameter pack
      from a sub-declarator, as in variadic114.C.  */
+  std::unique_ptr<tree_node,ggc_freer> inner_arg_deleter;
   if (!post_variadic_parms)
-    inner_args = expand_template_argument_pack (inner_args);
+    {
+      inner_args = expand_template_argument_pack (inner_args);
+      if (inner_args != orig_inner_args)
+	inner_arg_deleter.reset (inner_args);
+    }
 
   /* Count any pack expansion args.  */
   variadic_args_p = pack_expansion_args_count (inner_args);
@@ -9331,6 +9342,7 @@ coerce_template_parms (tree parms,
               /* We don't know how many args we have yet, just
                  use the unconverted ones for now.  */
               new_inner_args = inner_args;
+	      inner_arg_deleter.release ();
 	      arg_idx = nargs;
               break;
             }

Reply via email to