This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][C++] Save memory/time when folding CONSTRUCTORs


Currently we copy CONSTRUCTORs we cp_fold even if no elements fold
(we throw the copy away then).  That's wasteful and we can easily
do the copying on-demand.  For simplicity the following resorts
to memcpy-ing the whole original vector on the first change
and only overwrites changed elements in the folding loop
(I suspect that's usually faster given initializer elements do
usually not fold(?)).

That removes another 35MB GC memory use from the PR12245 testcase.
(the biggest offender there is, non-surprisingly the C++ preprocessor
tokens with 130MB followed by 35MB for the CONSTRUCTOR and 40MB for
INTEGER_CSTs).

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

Ok for trunk if that succeeds?

Thanks,
Richard.

2017-02-01  Richard Biener  <rguenther@suse.de>

	PR cp/14179
	cp/
	* cp-gimplify.c (cp_fold): When folding a CONSTRUCTOR copy
	it lazily on the first changed element only and copy it
	fully upfront, only storing changed elements.

Index: gcc/cp/cp-gimplify.c
===================================================================
--- gcc/cp/cp-gimplify.c	(revision 245094)
+++ gcc/cp/cp-gimplify.c	(working copy)
@@ -2361,12 +2361,9 @@ cp_fold (tree x)
 	bool changed = false;
 	vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
 	vec<constructor_elt, va_gc> *nelts = NULL;
-	vec_safe_reserve (nelts, vec_safe_length (elts));
 	FOR_EACH_VEC_SAFE_ELT (elts, i, p)
 	  {
 	    tree op = cp_fold (p->value);
-	    constructor_elt e = { p->index, op };
-	    nelts->quick_push (e);
 	    if (op != p->value)
 	      {
 		if (op == error_mark_node)
@@ -2375,7 +2372,13 @@ cp_fold (tree x)
 		    changed = false;
 		    break;
 		  }
-		changed = true;
+		if (! changed)
+		  {
+		    nelts = elts->copy ();
+		    changed = true;
+		  }
+		constructor_elt e = { p->index, op };
+		(*nelts)[i] = e;
 	      }
 	  }
 	if (changed)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]