public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
@ 2020-07-25 12:22 Martin Liška
  2020-07-27  7:11 ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-25 12:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jan Hubicka

Hello.

When inserting into fast_call_summary (or fast_function_summary), we grow
a vector to a _exact_ size based on cgraph_max_summary_id or edges_max_summary_id.
Problem is that it causes very many reallocation and we should rather use ::reserve
function that selects a reasonable size of a new vector.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Fixes chromium WPA build time:
https://gist.githubusercontent.com/marxin/223890df4d8d8e490b6b2918b77dacad/raw/f766f6546739e739a273639dde90ac6179aa3077/chromium-gcc10-fixed-summary-crash.svg

Ready to be installed?
Thanks,
Martin

gcc/ChangeLog:

	* symbol-summary.h: Call vec_safe_reserve before grow is called
	in order to grow to a reasonable size.
	* vec.h (vec_safe_reserve): Add missing function for vl_ptr
	type.
---
  gcc/symbol-summary.h | 13 ++++++++++---
  gcc/vec.h            | 11 +++++++++++
  2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index a38eb1db778..fa1df5c8015 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -354,8 +354,11 @@ public:
        id = this->m_symtab->assign_summary_id (node);
  
      if ((unsigned int)id >= m_vector->length ())
-      vec_safe_grow_cleared (m_vector,
-			     this->m_symtab->cgraph_max_summary_id);
+      {
+	int newlen = this->m_symtab->cgraph_max_summary_id;
+	vec_safe_reserve (m_vector, newlen - m_vector->length ());
+	m_vector->quick_grow_cleared (newlen);
+      }
  
      if ((*m_vector)[id] == NULL)
        (*m_vector)[id] = this->allocate_new ();
@@ -812,7 +815,11 @@ public:
        id = this->m_symtab->assign_summary_id (edge);
  
      if ((unsigned)id >= m_vector->length ())
-      vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
+      {
+	int newlen = this->m_symtab->edges_max_summary_id;
+	m_vector->reserve (newlen - m_vector->length ());
+	m_vector->quick_grow_cleared (newlen);
+      }
  
      if ((*m_vector)[id] == NULL)
        (*m_vector)[id] = this->allocate_new ();
diff --git a/gcc/vec.h b/gcc/vec.h
index bd7c7351dcd..3ad99b83690 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -753,6 +753,17 @@ vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
    v->safe_grow_cleared (len PASS_MEM_STAT);
  }
  
+/* If V does not have space for NELEMS elements, call
+   V->reserve(NELEMS, EXACT).  */
+
+template<typename T>
+inline bool
+vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = false
+		  CXX_MEM_STAT_INFO)
+{
+  return v->reserve (nelems, exact);
+}
+
  
  /* If V is NULL return false, otherwise return V->iterate(IX, PTR).  */
  template<typename T, typename A>
-- 
2.27.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-25 12:22 [PATCH] Use vec::reserve before vec_safe_grow_cleared is called Martin Liška
@ 2020-07-27  7:11 ` Richard Biener
  2020-07-27  7:14   ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2020-07-27  7:11 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches, Jan Hubicka

On Sat, Jul 25, 2020 at 2:23 PM Martin Liška <mliska@suse.cz> wrote:
>
> Hello.
>
> When inserting into fast_call_summary (or fast_function_summary), we grow
> a vector to a _exact_ size based on cgraph_max_summary_id or edges_max_summary_id.
> Problem is that it causes very many reallocation and we should rather use ::reserve
> function that selects a reasonable size of a new vector.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> Fixes chromium WPA build time:
> https://gist.githubusercontent.com/marxin/223890df4d8d8e490b6b2918b77dacad/raw/f766f6546739e739a273639dde90ac6179aa3077/chromium-gcc10-fixed-summary-crash.svg
>
> Ready to be installed?

OK.  I guess the previous code tried to use less memory.

Thanks,
Richard.

> Thanks,
> Martin
>
> gcc/ChangeLog:
>
>         * symbol-summary.h: Call vec_safe_reserve before grow is called
>         in order to grow to a reasonable size.
>         * vec.h (vec_safe_reserve): Add missing function for vl_ptr
>         type.
> ---
>   gcc/symbol-summary.h | 13 ++++++++++---
>   gcc/vec.h            | 11 +++++++++++
>   2 files changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
> index a38eb1db778..fa1df5c8015 100644
> --- a/gcc/symbol-summary.h
> +++ b/gcc/symbol-summary.h
> @@ -354,8 +354,11 @@ public:
>         id = this->m_symtab->assign_summary_id (node);
>
>       if ((unsigned int)id >= m_vector->length ())
> -      vec_safe_grow_cleared (m_vector,
> -                            this->m_symtab->cgraph_max_summary_id);
> +      {
> +       int newlen = this->m_symtab->cgraph_max_summary_id;
> +       vec_safe_reserve (m_vector, newlen - m_vector->length ());
> +       m_vector->quick_grow_cleared (newlen);
> +      }
>
>       if ((*m_vector)[id] == NULL)
>         (*m_vector)[id] = this->allocate_new ();
> @@ -812,7 +815,11 @@ public:
>         id = this->m_symtab->assign_summary_id (edge);
>
>       if ((unsigned)id >= m_vector->length ())
> -      vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
> +      {
> +       int newlen = this->m_symtab->edges_max_summary_id;
> +       m_vector->reserve (newlen - m_vector->length ());
> +       m_vector->quick_grow_cleared (newlen);
> +      }
>
>       if ((*m_vector)[id] == NULL)
>         (*m_vector)[id] = this->allocate_new ();
> diff --git a/gcc/vec.h b/gcc/vec.h
> index bd7c7351dcd..3ad99b83690 100644
> --- a/gcc/vec.h
> +++ b/gcc/vec.h
> @@ -753,6 +753,17 @@ vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
>     v->safe_grow_cleared (len PASS_MEM_STAT);
>   }
>
> +/* If V does not have space for NELEMS elements, call
> +   V->reserve(NELEMS, EXACT).  */
> +
> +template<typename T>
> +inline bool
> +vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = false
> +                 CXX_MEM_STAT_INFO)
> +{
> +  return v->reserve (nelems, exact);
> +}
> +
>
>   /* If V is NULL return false, otherwise return V->iterate(IX, PTR).  */
>   template<typename T, typename A>
> --
> 2.27.0
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27  7:11 ` Richard Biener
@ 2020-07-27  7:14   ` Martin Liška
  2020-07-27  9:51     ` Jan Hubicka
  2020-07-27 11:11     ` Jan Hubicka
  0 siblings, 2 replies; 40+ messages in thread
From: Martin Liška @ 2020-07-27  7:14 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 7/27/20 9:11 AM, Richard Biener wrote:
> OK.  I guess the previous code tried to use less memory.

It did. But I didn't realize that such exact growth would lead
to a massive reallocation for huge apps like chromium.

I'm going to backport the patch older releases as well.

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27  7:14   ` Martin Liška
@ 2020-07-27  9:51     ` Jan Hubicka
  2020-07-27 10:29       ` Martin Liška
  2020-07-27 11:11     ` Jan Hubicka
  1 sibling, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2020-07-27  9:51 UTC (permalink / raw)
  To: Martin Liška; +Cc: Richard Biener, GCC Patches

> On 7/27/20 9:11 AM, Richard Biener wrote:
> > OK.  I guess the previous code tried to use less memory.
> 
> It did. But I didn't realize that such exact growth would lead
> to a massive reallocation for huge apps like chromium.
> 
> I'm going to backport the patch older releases as well.

Thank you!  Did it solved the the Chromium problem?  I guess I can try
to do some profiling since this problem did not show on Firefox (that i
find odd given that Firefox is just about half of the size).
Perhaps glibc has some stupid limit in realloc that makes it to behave
in a silly way for very large arrays?

Honza
> 
> Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27  9:51     ` Jan Hubicka
@ 2020-07-27 10:29       ` Martin Liška
  2020-07-27 10:48         ` Jan Hubicka
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-27 10:29 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, GCC Patches

On 7/27/20 11:51 AM, Jan Hubicka wrote:
>> On 7/27/20 9:11 AM, Richard Biener wrote:
>>> OK.  I guess the previous code tried to use less memory.
>>
>> It did. But I didn't realize that such exact growth would lead
>> to a massive reallocation for huge apps like chromium.
>>
>> I'm going to backport the patch older releases as well.
> 
> Thank you!  Did it solved the the Chromium problem?

Yes, I verified that.

> I guess I can try
> to do some profiling since this problem did not show on Firefox (that i
> find odd given that Firefox is just about half of the size).

Yep, I'm also surprised about it.

> Perhaps glibc has some stupid limit in realloc that makes it to behave
> in a silly way for very large arrays?

Dunno :P

Martin

> 
> Honza
>>
>> Martin


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 10:29       ` Martin Liška
@ 2020-07-27 10:48         ` Jan Hubicka
  2020-07-27 11:00           ` Martin Liška
  2020-07-27 11:07           ` Richard Biener
  0 siblings, 2 replies; 40+ messages in thread
From: Jan Hubicka @ 2020-07-27 10:48 UTC (permalink / raw)
  To: Martin Liška; +Cc: Richard Biener, GCC Patches

> Yes, I verified that.
> 
> > I guess I can try
> > to do some profiling since this problem did not show on Firefox (that i
> > find odd given that Firefox is just about half of the size).
> 
> Yep, I'm also surprised about it.
> 
> > Perhaps glibc has some stupid limit in realloc that makes it to behave
> > in a silly way for very large arrays?
> 
> Dunno :P
Seems like glibc issue. On my debian testing box:

hubicka@lomikamen-jh:~$ cat t.c
#include <stdlib.h>
main(int argc, char **argv)
{
  char *a = malloc (1);
  int i,n=atoi(argv[1]);
  for (i=2;i<n;i++)
    a = realloc (a,i);
}

hubicka@lomikamen-jh:~$ time ./a.out 1000000000

real    0m10.057s
user    0m9.696s
sys     0m0.356s

And kunlun (which is a lot faster than my 2013 buldozer):


abuild@kunlun:~> time ./a.out 1000000000

real    0m59.808s
user    0m58.703s
sys     0m1.080s

GDB stops at:
(gdb) bt
#0  0x00007ffff7e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00005555555550bf in main ()
on debian while:
(gdb) bt
#0  0x00007ffff7e7d6d0 in mem2mem_check () from /lib64/libc.so.6
#1  0x00007ffff7e81c7d in realloc_check () from /lib64/libc.so.6
#2  0x00005555555550bf in main ()
on kunlun.

Perhaps someone enabled some cool security harnessing feature without
much of benchmarking :) (but even debian numbers seems like they can be
improved)

Honza
> 
> Martin
> 
> > 
> > Honza
> > > 
> > > Martin
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 10:48         ` Jan Hubicka
@ 2020-07-27 11:00           ` Martin Liška
  2020-07-27 11:03             ` Jan Hubicka
  2020-07-27 11:07           ` Richard Biener
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-27 11:00 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, GCC Patches

On 7/27/20 12:48 PM, Jan Hubicka wrote:
>> Yes, I verified that.
>>
>>> I guess I can try
>>> to do some profiling since this problem did not show on Firefox (that i
>>> find odd given that Firefox is just about half of the size).
>>
>> Yep, I'm also surprised about it.
>>
>>> Perhaps glibc has some stupid limit in realloc that makes it to behave
>>> in a silly way for very large arrays?
>>
>> Dunno :P
> Seems like glibc issue. On my debian testing box:
> 
> hubicka@lomikamen-jh:~$ cat t.c
> #include <stdlib.h>
> main(int argc, char **argv)
> {
>    char *a = malloc (1);
>    int i,n=atoi(argv[1]);
>    for (i=2;i<n;i++)
>      a = realloc (a,i);
> }
> 
> hubicka@lomikamen-jh:~$ time ./a.out 1000000000
> 
> real    0m10.057s
> user    0m9.696s
> sys     0m0.356s
> 
> And kunlun (which is a lot faster than my 2013 buldozer):
> 
> 
> abuild@kunlun:~> time ./a.out 1000000000
> 
> real    0m59.808s
> user    0m58.703s
> sys     0m1.080s

It runs for me in:

$ time ./a.out 1000000000

real	0m10.048s
user	0m9.742s
sys	0m0.305s

Note that there may be an interleaving load on the machine.
Perf says:

     55.40%  a.out    libc-2.26.so      [.] realloc
     36.01%  a.out    a.out             [.] realloc@plt
      4.98%  a.out    libc-2.26.so      [.] mremap_chunk
      3.60%  a.out    a.out             [.] main

while on my machine I see:

real	0m4.998s
user	0m4.947s
sys	0m0.050s

     54.49%  a.out    libc-2.31.so      [.] realloc
     37.63%  a.out    libc-2.31.so      [.] mremap_chunk
      3.72%  a.out    a.out             [.] realloc@plt

Martin

> 
> GDB stops at:
> (gdb) bt
> #0  0x00007ffff7e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
> #1  0x00005555555550bf in main ()
> on debian while:
> (gdb) bt
> #0  0x00007ffff7e7d6d0 in mem2mem_check () from /lib64/libc.so.6
> #1  0x00007ffff7e81c7d in realloc_check () from /lib64/libc.so.6
> #2  0x00005555555550bf in main ()
> on kunlun.
> 
> Perhaps someone enabled some cool security harnessing feature without
> much of benchmarking :) (but even debian numbers seems like they can be
> improved)
> 
> Honza
>>
>> Martin
>>
>>>
>>> Honza
>>>>
>>>> Martin
>>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 11:00           ` Martin Liška
@ 2020-07-27 11:03             ` Jan Hubicka
  2020-07-27 11:22               ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2020-07-27 11:03 UTC (permalink / raw)
  To: Martin Liška; +Cc: GCC Patches

> It runs for me in:
> 
> $ time ./a.out 1000000000
> 
> real	0m10.048s
> user	0m9.742s
> sys	0m0.305s

Did you do chroot to the chromium build?
> 
> Note that there may be an interleaving load on the machine.
> Perf says:
> 
>     55.40%  a.out    libc-2.26.so      [.] realloc
>     36.01%  a.out    a.out             [.] realloc@plt
>      4.98%  a.out    libc-2.26.so      [.] mremap_chunk
>      3.60%  a.out    a.out             [.] main

How one can do perfing on kunlun?
> 
> while on my machine I see:
> 
> real	0m4.998s
> user	0m4.947s
> sys	0m0.050s
> 
>     54.49%  a.out    libc-2.31.so      [.] realloc
>     37.63%  a.out    libc-2.31.so      [.] mremap_chunk
>      3.72%  a.out    a.out             [.] realloc@plt

Honza
> 
> Martin
> 
> > 
> > GDB stops at:
> > (gdb) bt
> > #0  0x00007ffff7e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
> > #1  0x00005555555550bf in main ()
> > on debian while:
> > (gdb) bt
> > #0  0x00007ffff7e7d6d0 in mem2mem_check () from /lib64/libc.so.6
> > #1  0x00007ffff7e81c7d in realloc_check () from /lib64/libc.so.6
> > #2  0x00005555555550bf in main ()
> > on kunlun.
> > 
> > Perhaps someone enabled some cool security harnessing feature without
> > much of benchmarking :) (but even debian numbers seems like they can be
> > improved)
> > 
> > Honza
> > > 
> > > Martin
> > > 
> > > > 
> > > > Honza
> > > > > 
> > > > > Martin
> > > 
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 10:48         ` Jan Hubicka
  2020-07-27 11:00           ` Martin Liška
@ 2020-07-27 11:07           ` Richard Biener
  1 sibling, 0 replies; 40+ messages in thread
From: Richard Biener @ 2020-07-27 11:07 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Martin Liška, GCC Patches

On Mon, Jul 27, 2020 at 12:48 PM Jan Hubicka <hubicka@ucw.cz> wrote:
>
> > Yes, I verified that.
> >
> > > I guess I can try
> > > to do some profiling since this problem did not show on Firefox (that i
> > > find odd given that Firefox is just about half of the size).
> >
> > Yep, I'm also surprised about it.
> >
> > > Perhaps glibc has some stupid limit in realloc that makes it to behave
> > > in a silly way for very large arrays?
> >
> > Dunno :P
> Seems like glibc issue. On my debian testing box:

I'm sure in your actual testcase you run into fragmentation and
eventually fall out of cache which should make things worse by
an order of magnitude.

> hubicka@lomikamen-jh:~$ cat t.c
> #include <stdlib.h>
> main(int argc, char **argv)
> {
>   char *a = malloc (1);
>   int i,n=atoi(argv[1]);
>   for (i=2;i<n;i++)
>     a = realloc (a,i);
> }
>
> hubicka@lomikamen-jh:~$ time ./a.out 1000000000
>
> real    0m10.057s
> user    0m9.696s
> sys     0m0.356s
>
> And kunlun (which is a lot faster than my 2013 buldozer):
>
>
> abuild@kunlun:~> time ./a.out 1000000000
>
> real    0m59.808s
> user    0m58.703s
> sys     0m1.080s
>
> GDB stops at:
> (gdb) bt
> #0  0x00007ffff7e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
> #1  0x00005555555550bf in main ()
> on debian while:
> (gdb) bt
> #0  0x00007ffff7e7d6d0 in mem2mem_check () from /lib64/libc.so.6
> #1  0x00007ffff7e81c7d in realloc_check () from /lib64/libc.so.6
> #2  0x00005555555550bf in main ()
> on kunlun.
>
> Perhaps someone enabled some cool security harnessing feature without
> much of benchmarking :) (but even debian numbers seems like they can be
> improved)
>
> Honza
> >
> > Martin
> >
> > >
> > > Honza
> > > >
> > > > Martin
> >

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27  7:14   ` Martin Liška
  2020-07-27  9:51     ` Jan Hubicka
@ 2020-07-27 11:11     ` Jan Hubicka
  2020-07-27 11:24       ` Martin Liška
  1 sibling, 1 reply; 40+ messages in thread
From: Jan Hubicka @ 2020-07-27 11:11 UTC (permalink / raw)
  To: Martin Liška; +Cc: Richard Biener, GCC Patches

> On 7/27/20 9:11 AM, Richard Biener wrote:
> > OK.  I guess the previous code tried to use less memory.
> 
> It did. But I didn't realize that such exact growth would lead
> to a massive reallocation for huge apps like chromium.

I would consider it an API issue - it is not really at all that obvious
when vec API does auto reserve and when it does not. 

Grepping for vec_safe_grow, rtl_create_basic_block, gimple_set_bb,
extend_h_i_d, stack_regs_mentioned, init_deps_data_vector
extend_insn_data, create_bb, move_block_to_fn logic has similar logic
but implemented by hand.  Perhaps we can switch it to the new API.  

combine_split_insns, combine_instructions, update_row_reg_save,
grow_label_align, update_uses, final_warning_record::grow_type_warnings,
sem_function::bb_dict_test, ::add_single_to_queue,
symtab_node::create_reference, mark_phi_for_rewrite, addr_for_mem_ref,
multiplier_allowed_in_address_p, get_address_cost_ainc,
make_ssa_name_fn, add_to_value, phi_translate_1,
optimize_range_tests_cmp_bitwise, set_strinfo,
ssa_name_values.safe_grow_cleared, vect_record_loop_mask has similarly
suspicious logic in it.  

Honza
> 
> I'm going to backport the patch older releases as well.
> 
> Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 11:03             ` Jan Hubicka
@ 2020-07-27 11:22               ` Martin Liška
  2020-07-27 12:49                 ` Andreas Schwab
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-27 11:22 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: GCC Patches, Andreas Schwab

On 7/27/20 1:03 PM, Jan Hubicka wrote:
> Did you do chroot to the chromium build?

Oh, you are right!

It really takes move than 60 seconds with:

     35.43%  a.out    libc-2.31.so      [.] mem2chunk_check
     26.54%  a.out    libc-2.31.so      [.] mem2mem_check
     21.50%  a.out    libc-2.31.so      [.] realloc_check
      8.38%  a.out    libc-2.31.so      [.] mremap_chunk
      5.03%  a.out    libc-2.31.so      [.] realloc
      1.87%  a.out    a.out             [.] main

So there's really a hardening enabled in openSUSE:Factory chroot.
@Andreas: Is it a known issue?

>> Note that there may be an interleaving load on the machine.
>> Perf says:
>>
>>      55.40%  a.out    libc-2.26.so      [.] realloc
>>      36.01%  a.out    a.out             [.] realloc@plt
>>       4.98%  a.out    libc-2.26.so      [.] mremap_chunk
>>       3.60%  a.out    a.out             [.] main
> How one can do perfing on kunlun?

You can install perf with:
osc build -x perf -x kernel-default

and then you can run it in a chroot env.

Martin



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 11:11     ` Jan Hubicka
@ 2020-07-27 11:24       ` Martin Liška
  2020-07-27 11:31         ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-27 11:24 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, GCC Patches

On 7/27/20 1:11 PM, Jan Hubicka wrote:
>> On 7/27/20 9:11 AM, Richard Biener wrote:
>>> OK.  I guess the previous code tried to use less memory.
>>
>> It did. But I didn't realize that such exact growth would lead
>> to a massive reallocation for huge apps like chromium.
> 
> I would consider it an API issue - it is not really at all that obvious
> when vec API does auto reserve and when it does not.

Fully agree here, it's super-confusing.

> 
> Grepping for vec_safe_grow, rtl_create_basic_block, gimple_set_bb,
> extend_h_i_d, stack_regs_mentioned, init_deps_data_vector
> extend_insn_data, create_bb, move_block_to_fn logic has similar logic
> but implemented by hand.  Perhaps we can switch it to the new API.
> 
> combine_split_insns, combine_instructions, update_row_reg_save,
> grow_label_align, update_uses, final_warning_record::grow_type_warnings,
> sem_function::bb_dict_test, ::add_single_to_queue,
> symtab_node::create_reference, mark_phi_for_rewrite, addr_for_mem_ref,
> multiplier_allowed_in_address_p, get_address_cost_ainc,
> make_ssa_name_fn, add_to_value, phi_translate_1,
> optimize_range_tests_cmp_bitwise, set_strinfo,
> ssa_name_values.safe_grow_cleared, vect_record_loop_mask has similarly
> suspicious logic in it.

Are you talking about changing all '*gros*' calls to use exact=false, right?
I can experiment with that.

Martin

> 
> Honza
>>
>> I'm going to backport the patch older releases as well.
>>
>> Martin


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 11:24       ` Martin Liška
@ 2020-07-27 11:31         ` Richard Biener
  2020-07-28 10:23           ` [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2020-07-27 11:31 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jan Hubicka, GCC Patches

On Mon, Jul 27, 2020 at 1:24 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 7/27/20 1:11 PM, Jan Hubicka wrote:
> >> On 7/27/20 9:11 AM, Richard Biener wrote:
> >>> OK.  I guess the previous code tried to use less memory.
> >>
> >> It did. But I didn't realize that such exact growth would lead
> >> to a massive reallocation for huge apps like chromium.
> >
> > I would consider it an API issue - it is not really at all that obvious
> > when vec API does auto reserve and when it does not.
>
> Fully agree here, it's super-confusing.
>
> >
> > Grepping for vec_safe_grow, rtl_create_basic_block, gimple_set_bb,
> > extend_h_i_d, stack_regs_mentioned, init_deps_data_vector
> > extend_insn_data, create_bb, move_block_to_fn logic has similar logic
> > but implemented by hand.  Perhaps we can switch it to the new API.
> >
> > combine_split_insns, combine_instructions, update_row_reg_save,
> > grow_label_align, update_uses, final_warning_record::grow_type_warnings,
> > sem_function::bb_dict_test, ::add_single_to_queue,
> > symtab_node::create_reference, mark_phi_for_rewrite, addr_for_mem_ref,
> > multiplier_allowed_in_address_p, get_address_cost_ainc,
> > make_ssa_name_fn, add_to_value, phi_translate_1,
> > optimize_range_tests_cmp_bitwise, set_strinfo,
> > ssa_name_values.safe_grow_cleared, vect_record_loop_mask has similarly
> > suspicious logic in it.
>
> Are you talking about changing all '*gros*' calls to use exact=false, right?
> I can experiment with that.

No, add gro*_exact variants and replace existing ones with this, then switch
to exact = false for the non-_exact variants.  Or add a exact=false argument
to all of them and make all existing calls explicitly passing true.

Only later, on a case by case basis, swap one for the other when obvious.

Richard.

> Martin
>
> >
> > Honza
> >>
> >> I'm going to backport the patch older releases as well.
> >>
> >> Martin
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 11:22               ` Martin Liška
@ 2020-07-27 12:49                 ` Andreas Schwab
  2020-07-27 12:51                   ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Andreas Schwab @ 2020-07-27 12:49 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jan Hubicka, GCC Patches

On Jul 27 2020, Martin Liška wrote:

> @Andreas: Is it a known issue?

Which issue?

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 12:49                 ` Andreas Schwab
@ 2020-07-27 12:51                   ` Richard Biener
  2020-07-27 12:54                     ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2020-07-27 12:51 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Martin Liška, GCC Patches, Jan Hubicka

On Mon, Jul 27, 2020 at 2:50 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>
> On Jul 27 2020, Martin Liška wrote:
>
> > @Andreas: Is it a known issue?
>
> Which issue?

I guess Martin means the checking glibc done looks excessive
(for the specific case of realloc). But yes, it's enabled in the build roots
so we just get what we ask for.

Richard.

> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 12:51                   ` Richard Biener
@ 2020-07-27 12:54                     ` Martin Liška
  2020-07-27 12:58                       ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-27 12:54 UTC (permalink / raw)
  To: Richard Biener, Andreas Schwab; +Cc: GCC Patches, Jan Hubicka

On 7/27/20 2:51 PM, Richard Biener wrote:
> On Mon, Jul 27, 2020 at 2:50 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
>>
>> On Jul 27 2020, Martin Liška wrote:
>>
>>> @Andreas: Is it a known issue?
>>
>> Which issue?
> 
> I guess Martin means the checking glibc done looks excessive
> (for the specific case of realloc). But yes, it's enabled in the build roots
> so we just get what we ask for.

Yes. I'm basically curious who is this enabled/disabled for glibc.
I speak e.g. about:

#0  0x00007ffff7e886f0 in mem2chunk_check () from /lib64/libc.so.6
#1  0x00007ffff7e8cb8a in realloc_check () from /lib64/libc.so.6
#2  0x00005555555550bf in main (argc=<optimized out>, argv=<optimized out>) at bench.c:7

Martin

> 
> Richard.
> 
>> Andreas.
>>
>> --
>> Andreas Schwab, schwab@linux-m68k.org
>> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
>> "And now for something completely different."


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called
  2020-07-27 12:54                     ` Martin Liška
@ 2020-07-27 12:58                       ` Richard Biener
  0 siblings, 0 replies; 40+ messages in thread
From: Richard Biener @ 2020-07-27 12:58 UTC (permalink / raw)
  To: Martin Liška; +Cc: Andreas Schwab, GCC Patches, Jan Hubicka

On Mon, Jul 27, 2020 at 2:54 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 7/27/20 2:51 PM, Richard Biener wrote:
> > On Mon, Jul 27, 2020 at 2:50 PM Andreas Schwab <schwab@linux-m68k.org> wrote:
> >>
> >> On Jul 27 2020, Martin Liška wrote:
> >>
> >>> @Andreas: Is it a known issue?
> >>
> >> Which issue?
> >
> > I guess Martin means the checking glibc done looks excessive
> > (for the specific case of realloc). But yes, it's enabled in the build roots
> > so we just get what we ask for.
>
> Yes. I'm basically curious who is this enabled/disabled for glibc.
> I speak e.g. about:
>
> #0  0x00007ffff7e886f0 in mem2chunk_check () from /lib64/libc.so.6
> #1  0x00007ffff7e8cb8a in realloc_check () from /lib64/libc.so.6
> #2  0x00005555555550bf in main (argc=<optimized out>, argv=<optimized out>) at bench.c:7

It's /etc/profile.d/malloc-debug.sh

> Martin
>
> >
> > Richard.
> >
> >> Andreas.
> >>
> >> --
> >> Andreas Schwab, schwab@linux-m68k.org
> >> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> >> "And now for something completely different."
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions.
  2020-07-27 11:31         ` Richard Biener
@ 2020-07-28 10:23           ` Martin Liška
  2020-07-29 13:47             ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-28 10:23 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 624 bytes --]

On 7/27/20 1:31 PM, Richard Biener wrote:
> No, add gro*_exact variants and replace existing ones with this, then switch
> to exact = false for the non-_exact variants.  Or add a exact=false argument
> to all of them and make all existing calls explicitly passing true.

-EBITLAZY

Anyway, I prepared a patch that adds exact=false for all the grow functions.
Apart from selective scheduling, all other consumers seems happy. And I removed
the artificial capacity growth calculations at places mentioned by Honza.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

[-- Attachment #2: 0001-Use-exact-false-for-vec_safe_grow-_cleared-functions.patch --]
[-- Type: text/x-patch, Size: 9899 bytes --]

From 494c193931c42cbb2ca670bf2be203f7b70bd88d Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Mon, 27 Jul 2020 14:36:16 +0200
Subject: [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions.

gcc/ChangeLog:

	* cfgrtl.c (rtl_create_basic_block): Do not calculate vector
	growth manually.
	* gimple.c (gimple_set_bb): Likewise.
	* tree-cfg.c (create_bb): Likewise.
	(move_block_to_fn): Likewise.
	* vec.h (vec_safe_grow): Add new argument exact with default
	value equal to false.
	(vec_safe_grow_cleared): Likewise.
	(vl_ptr>::safe_grow): Likewise.
	(vl_ptr>::safe_grow_cleared): Likewise.
	* symbol-summary.h: Do not call vec_safe_reserve +
	quick_grow_cleared.
---
 gcc/cfgrtl.c         |  8 ++------
 gcc/gimple.c         |  7 +------
 gcc/haifa-sched.c    |  2 +-
 gcc/sched-deps.c     |  2 +-
 gcc/sel-sched-ir.c   |  2 +-
 gcc/symbol-summary.h | 13 +++----------
 gcc/tree-cfg.c       | 21 ++++++---------------
 gcc/vec.h            | 27 +++++++++++++++------------
 8 files changed, 30 insertions(+), 52 deletions(-)

diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 827e84a44dd..0e65537f255 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -374,12 +374,8 @@ rtl_create_basic_block (void *headp, void *endp, basic_block after)
   /* Grow the basic block array if needed.  */
   if ((size_t) last_basic_block_for_fn (cfun)
       >= basic_block_info_for_fn (cfun)->length ())
-    {
-      size_t new_size =
-	(last_basic_block_for_fn (cfun)
-	 + (last_basic_block_for_fn (cfun) + 3) / 4);
-      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size);
-    }
+    vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
+			   last_basic_block_for_fn (cfun) + 1);
 
   n_basic_blocks_for_fn (cfun)++;
 
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 10c562f4def..1175176aa70 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1703,12 +1703,7 @@ gimple_set_bb (gimple *stmt, basic_block bb)
 	    vec_safe_length (label_to_block_map_for_fn (cfun));
 	  LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
 	  if (old_len <= (unsigned) uid)
-	    {
-	      unsigned new_len = 3 * uid / 2 + 1;
-
-	      vec_safe_grow_cleared (label_to_block_map_for_fn (cfun),
-				     new_len);
-	    }
+	    vec_safe_grow_cleared (label_to_block_map_for_fn (cfun), uid + 1);
 	}
 
       (*label_to_block_map_for_fn (cfun))[uid] = bb;
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 80687fb5359..e18a1de6855 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -9039,7 +9039,7 @@ extend_h_i_d (void)
   if (reserve > 0
       && ! h_i_d.space (reserve))
     {
-      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2);
+      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
       sched_extend_target ();
     }
 }
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 1bc75074e5d..d8b5c53c6a4 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -4072,7 +4072,7 @@ init_deps_data_vector (void)
 {
   int reserve = (sched_max_luid + 1 - h_d_i_d.length ());
   if (reserve > 0 && ! h_d_i_d.space (reserve))
-    h_d_i_d.safe_grow_cleared (3 * sched_max_luid / 2);
+    h_d_i_d.safe_grow_cleared (3 * sched_max_luid / 2, true);
 }
 
 /* If it is profitable to use them, initialize or extend (depending on
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 4f1e4afdc4c..63fb6c671af 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -4209,7 +4209,7 @@ extend_insn_data (void)
         size = 3 * sched_max_luid / 2;
 
 
-      s_i_d.safe_grow_cleared (size);
+      s_i_d.safe_grow_cleared (size, true);
     }
 }
 
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index fa1df5c8015..a38eb1db778 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -354,11 +354,8 @@ public:
       id = this->m_symtab->assign_summary_id (node);
 
     if ((unsigned int)id >= m_vector->length ())
-      {
-	int newlen = this->m_symtab->cgraph_max_summary_id;
-	vec_safe_reserve (m_vector, newlen - m_vector->length ());
-	m_vector->quick_grow_cleared (newlen);
-      }
+      vec_safe_grow_cleared (m_vector,
+			     this->m_symtab->cgraph_max_summary_id);
 
     if ((*m_vector)[id] == NULL)
       (*m_vector)[id] = this->allocate_new ();
@@ -815,11 +812,7 @@ public:
       id = this->m_symtab->assign_summary_id (edge);
 
     if ((unsigned)id >= m_vector->length ())
-      {
-	int newlen = this->m_symtab->edges_max_summary_id;
-	m_vector->reserve (newlen - m_vector->length ());
-	m_vector->quick_grow_cleared (newlen);
-      }
+      vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
 
     if ((*m_vector)[id] == NULL)
       (*m_vector)[id] = this->allocate_new ();
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index b4d0c6db238..b79cf6c6d4c 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -681,12 +681,8 @@ create_bb (void *h, void *e, basic_block after)
   /* Grow the basic block array if needed.  */
   if ((size_t) last_basic_block_for_fn (cfun)
       == basic_block_info_for_fn (cfun)->length ())
-    {
-      size_t new_size =
-	(last_basic_block_for_fn (cfun)
-	 + (last_basic_block_for_fn (cfun) + 3) / 4);
-      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size);
-    }
+    vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
+			   last_basic_block_for_fn (cfun) + 1);
 
   /* Add the newly created block to the array.  */
   SET_BASIC_BLOCK_FOR_FN (cfun, last_basic_block_for_fn (cfun), bb);
@@ -7097,7 +7093,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
   edge_iterator ei;
   edge e;
   gimple_stmt_iterator si;
-  unsigned old_len, new_len;
+  unsigned old_len;
 
   /* Remove BB from dominance structures.  */
   delete_from_dominance_info (CDI_DOMINATORS, bb);
@@ -7133,10 +7129,8 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
 
   old_len = vec_safe_length (cfg->x_basic_block_info);
   if ((unsigned) cfg->x_last_basic_block >= old_len)
-    {
-      new_len = cfg->x_last_basic_block + (cfg->x_last_basic_block + 3) / 4;
-      vec_safe_grow_cleared (cfg->x_basic_block_info, new_len);
-    }
+    vec_safe_grow_cleared (cfg->x_basic_block_info,
+			   cfg->x_last_basic_block + 1);
 
   (*cfg->x_basic_block_info)[bb->index] = bb;
 
@@ -7209,10 +7203,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
 
 	  old_len = vec_safe_length (cfg->x_label_to_block_map);
 	  if (old_len <= (unsigned) uid)
-	    {
-	      new_len = 3 * uid / 2 + 1;
-	      vec_safe_grow_cleared (cfg->x_label_to_block_map, new_len);
-	    }
+	    vec_safe_grow_cleared (cfg->x_label_to_block_map, uid + 1);
 
 	  (*cfg->x_label_to_block_map)[uid] = bb;
 	  (*cfun->cfg->x_label_to_block_map)[uid] = NULL;
diff --git a/gcc/vec.h b/gcc/vec.h
index 3ad99b83690..a908d751ab7 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -723,11 +723,12 @@ vec_free (vec<T, A, vl_embed> *&v)
 /* Grow V to length LEN.  Allocate it, if necessary.  */
 template<typename T, typename A>
 inline void
-vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
+vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len,
+	       bool exact = false CXX_MEM_STAT_INFO)
 {
   unsigned oldlen = vec_safe_length (v);
   gcc_checking_assert (len >= oldlen);
-  vec_safe_reserve_exact (v, len - oldlen PASS_MEM_STAT);
+  vec_safe_reserve (v, len - oldlen, exact PASS_MEM_STAT);
   v->quick_grow (len);
 }
 
@@ -735,10 +736,11 @@ vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
 /* If V is NULL, allocate it.  Call V->safe_grow_cleared(LEN).  */
 template<typename T, typename A>
 inline void
-vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
+vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len,
+		       bool exact = false CXX_MEM_STAT_INFO)
 {
   unsigned oldlen = vec_safe_length (v);
-  vec_safe_grow (v, len PASS_MEM_STAT);
+  vec_safe_grow (v, len, exact PASS_MEM_STAT);
   vec_default_construct (v->address () + oldlen, len - oldlen);
 }
 
@@ -748,9 +750,9 @@ vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
 template<typename T>
 inline void
 vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
-		       unsigned len CXX_MEM_STAT_INFO)
+		       unsigned len, bool exact = false CXX_MEM_STAT_INFO)
 {
-  v->safe_grow_cleared (len PASS_MEM_STAT);
+  v->safe_grow_cleared (len, exact PASS_MEM_STAT);
 }
 
 /* If V does not have space for NELEMS elements, call
@@ -1460,8 +1462,8 @@ public:
   T *safe_push (const T &CXX_MEM_STAT_INFO);
   T &pop (void);
   void truncate (unsigned);
-  void safe_grow (unsigned CXX_MEM_STAT_INFO);
-  void safe_grow_cleared (unsigned CXX_MEM_STAT_INFO);
+  void safe_grow (unsigned, bool = false CXX_MEM_STAT_INFO);
+  void safe_grow_cleared (unsigned, bool = false CXX_MEM_STAT_INFO);
   void quick_grow (unsigned);
   void quick_grow_cleared (unsigned);
   void quick_insert (unsigned, const T &);
@@ -1887,11 +1889,11 @@ vec<T, va_heap, vl_ptr>::truncate (unsigned size)
 
 template<typename T>
 inline void
-vec<T, va_heap, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
+vec<T, va_heap, vl_ptr>::safe_grow (unsigned len, bool exact MEM_STAT_DECL)
 {
   unsigned oldlen = length ();
   gcc_checking_assert (oldlen <= len);
-  reserve_exact (len - oldlen PASS_MEM_STAT);
+  reserve (len - oldlen, exact PASS_MEM_STAT);
   if (m_vec)
     m_vec->quick_grow (len);
   else
@@ -1905,11 +1907,12 @@ vec<T, va_heap, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
 
 template<typename T>
 inline void
-vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
+vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len, bool exact
+					    MEM_STAT_DECL)
 {
   unsigned oldlen = length ();
   size_t growby = len - oldlen;
-  safe_grow (len PASS_MEM_STAT);
+  safe_grow (len, exact PASS_MEM_STAT);
   if (growby != 0)
     vec_default_construct (address () + oldlen, growby);
 }
-- 
2.27.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions.
  2020-07-28 10:23           ` [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions Martin Liška
@ 2020-07-29 13:47             ` Richard Biener
  2020-07-30 13:22               ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2020-07-29 13:47 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jan Hubicka, GCC Patches

On Tue, Jul 28, 2020 at 12:23 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 7/27/20 1:31 PM, Richard Biener wrote:
> > No, add gro*_exact variants and replace existing ones with this, then switch
> > to exact = false for the non-_exact variants.  Or add a exact=false argument
> > to all of them and make all existing calls explicitly passing true.
>
> -EBITLAZY

Indeed you are - you're missing to update a lot of vec_safe_grow[_cleared]
calls.  Esp. the lto-streamer ones warrant a , true arg since we explicitly
streamed the number of elements.

How did you select the ones you updated and those you did not? (which
is why I asked for a boiler-plate replacement of , true first, then making
the parameter defaulted to false and adjusting those cases you found)

> Anyway, I prepared a patch that adds exact=false for all the grow functions.
> Apart from selective scheduling, all other consumers seems happy. And I removed
> the artificial capacity growth calculations at places mentioned by Honza.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?
> Thanks,
> Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions.
  2020-07-29 13:47             ` Richard Biener
@ 2020-07-30 13:22               ` Martin Liška
  2020-08-03 13:47                 ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-07-30 13:22 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, GCC Patches

On 7/29/20 3:47 PM, Richard Biener wrote:
> On Tue, Jul 28, 2020 at 12:23 PM Martin Liška <mliska@suse.cz> wrote:
>>
>> On 7/27/20 1:31 PM, Richard Biener wrote:
>>> No, add gro*_exact variants and replace existing ones with this, then switch
>>> to exact = false for the non-_exact variants.  Or add a exact=false argument
>>> to all of them and make all existing calls explicitly passing true.
>>
>> -EBITLAZY
> 
> Indeed you are - you're missing to update a lot of vec_safe_grow[_cleared]
> calls.  Esp. the lto-streamer ones warrant a , true arg since we explicitly
> streamed the number of elements.

Yep, these should probably use exact allocation.

> 
> How did you select the ones you updated and those you did not?

Based on testing, I only kept changes in selective scheduling which caused
some ICEs.

(which
> is why I asked for a boiler-plate replacement of , true first, then making

This step would require to change about 250 places in the source code :(

> the parameter defaulted to false and adjusting those cases you found)

What about rather doing exact = true and changing the few places which don't need
it (as they make their of growth calculations)?

Martin

>> Anyway, I prepared a patch that adds exact=false for all the grow functions.
>> Apart from selective scheduling, all other consumers seems happy. And I removed
>> the artificial capacity growth calculations at places mentioned by Honza.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>> Thanks,
>> Martin


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions.
  2020-07-30 13:22               ` Martin Liška
@ 2020-08-03 13:47                 ` Richard Biener
  2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2020-08-03 13:47 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jan Hubicka, GCC Patches

On Thu, Jul 30, 2020 at 3:22 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 7/29/20 3:47 PM, Richard Biener wrote:
> > On Tue, Jul 28, 2020 at 12:23 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> On 7/27/20 1:31 PM, Richard Biener wrote:
> >>> No, add gro*_exact variants and replace existing ones with this, then switch
> >>> to exact = false for the non-_exact variants.  Or add a exact=false argument
> >>> to all of them and make all existing calls explicitly passing true.
> >>
> >> -EBITLAZY
> >
> > Indeed you are - you're missing to update a lot of vec_safe_grow[_cleared]
> > calls.  Esp. the lto-streamer ones warrant a , true arg since we explicitly
> > streamed the number of elements.
>
> Yep, these should probably use exact allocation.
>
> >
> > How did you select the ones you updated and those you did not?
>
> Based on testing, I only kept changes in selective scheduling which caused
> some ICEs.
>
> (which
> > is why I asked for a boiler-plate replacement of , true first, then making
>
> This step would require to change about 250 places in the source code :(
>
> > the parameter defaulted to false and adjusting those cases you found)
>
> What about rather doing exact = true and changing the few places which don't need
> it (as they make their of growth calculations)?

But that would be inconsistent with the other 'exact' defaulted params in vec.h.

I think your patch points at the valid issue that the usually
defaulted 'exact' is
overridden in non _exact named functions without any way to change that
override.  But then we shouldn't change behavior when correcting that mistake.

Which is why my original suggestion added non-defaulted 'exact' paramters
to those places (to discover all places that need adjustment) and only after
that default it and remove the cases now equal to the defaulted case ...

Richard.

> Martin
>
> >> Anyway, I prepared a patch that adds exact=false for all the grow functions.
> >> Apart from selective scheduling, all other consumers seems happy. And I removed
> >> the artificial capacity growth calculations at places mentioned by Honza.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> >> Thanks,
> >> Martin
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-03 13:47                 ` Richard Biener
@ 2020-08-11 11:36                   ` Martin Liška
  2020-08-11 11:37                     ` [PATCH 2/3] vec: default exact = false in " Martin Liška
                                       ` (4 more replies)
  0 siblings, 5 replies; 40+ messages in thread
From: Martin Liška @ 2020-08-11 11:36 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 378 bytes --]

Hello.

All right, I did it in 3 steps:
1) - new exact argument is added (no default value) - I tested the on x86_64-linux-gnu
and I build all cross targets.
2) set default value of exact = false
3) change places which calculate its own growth to use the default argument

I would like to install first 1) and then wait some time before the rest is installed.

Thoughts?
Martin

[-- Attachment #2: 0001-vec-add-exact-argument-for-various-grow-functions.patch --]
[-- Type: text/x-patch, Size: 92695 bytes --]

From c659680bd65bdaa749d8c07fc99b45542a872786 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Mon, 10 Aug 2020 11:11:05 +0200
Subject: [PATCH 1/3] vec: add exact argument for various grow functions.

gcc/ada/ChangeLog:

	* gcc-interface/trans.c (gigi): Set exact argument of a vector
	growth function to true.
	(Attribute_to_gnu): Likewise.

gcc/ChangeLog:

	* alias.c (init_alias_analysis): Set exact argument of a vector
	growth function to true.
	* calls.c (internal_arg_pointer_based_exp_scan): Likewise.
	* cfgbuild.c (find_many_sub_basic_blocks): Likewise.
	* cfgexpand.c (expand_asm_stmt): Likewise.
	* cfgrtl.c (rtl_create_basic_block): Likewise.
	* combine.c (combine_split_insns): Likewise.
	(combine_instructions): Likewise.
	* config/aarch64/aarch64-sve-builtins.cc (function_expander::add_output_operand): Likewise.
	(function_expander::add_input_operand): Likewise.
	(function_expander::add_integer_operand): Likewise.
	(function_expander::add_address_operand): Likewise.
	(function_expander::add_fixed_operand): Likewise.
	* df-core.c (df_worklist_dataflow_doublequeue): Likewise.
	* dwarf2cfi.c (update_row_reg_save): Likewise.
	* early-remat.c (early_remat::init_block_info): Likewise.
	(early_remat::finalize_candidate_indices): Likewise.
	* except.c (sjlj_build_landing_pads): Likewise.
	* final.c (compute_alignments): Likewise.
	(grow_label_align): Likewise.
	* function.c (temp_slots_at_level): Likewise.
	* fwprop.c (build_single_def_use_links): Likewise.
	(update_uses): Likewise.
	* gcc.c (insert_wrapper): Likewise.
	* genautomata.c (create_state_ainsn_table): Likewise.
	(add_vect): Likewise.
	(output_dead_lock_vect): Likewise.
	* genmatch.c (capture_info::capture_info): Likewise.
	(parser::finish_match_operand): Likewise.
	* genrecog.c (optimize_subroutine_group): Likewise.
	(merge_pattern_info::merge_pattern_info): Likewise.
	(merge_into_decision): Likewise.
	(print_subroutine_start): Likewise.
	(main): Likewise.
	* gimple-loop-versioning.cc (loop_versioning::loop_versioning): Likewise.
	* gimple.c (gimple_set_bb): Likewise.
	* graphite-isl-ast-to-gimple.c (translate_isl_ast_node_user): Likewise.
	* haifa-sched.c (sched_extend_luids): Likewise.
	(extend_h_i_d): Likewise.
	* insn-addr.h (insn_addresses_new): Likewise.
	* ipa-cp.c (gather_context_independent_values): Likewise.
	(find_more_contexts_for_caller_subset): Likewise.
	* ipa-devirt.c (final_warning_record::grow_type_warnings): Likewise.
	(ipa_odr_read_section): Likewise.
	* ipa-fnsummary.c (evaluate_properties_for_edge): Likewise.
	(ipa_fn_summary_t::duplicate): Likewise.
	(analyze_function_body): Likewise.
	(ipa_merge_fn_summary_after_inlining): Likewise.
	(read_ipa_call_summary): Likewise.
	* ipa-icf.c (sem_function::bb_dict_test): Likewise.
	* ipa-prop.c (ipa_alloc_node_params): Likewise.
	(parm_bb_aa_status_for_bb): Likewise.
	(ipa_compute_jump_functions_for_edge): Likewise.
	(ipa_analyze_node): Likewise.
	(update_jump_functions_after_inlining): Likewise.
	(ipa_read_edge_info): Likewise.
	(read_ipcp_transformation_info): Likewise.
	(ipcp_transform_function): Likewise.
	* ipa-reference.c (ipa_reference_write_optimization_summary): Likewise.
	* ipa-split.c (execute_split_functions): Likewise.
	* ira.c (find_moveable_pseudos): Likewise.
	* lower-subreg.c (decompose_multiword_subregs): Likewise.
	* lto-streamer-in.c (input_eh_regions): Likewise.
	(input_cfg): Likewise.
	(input_struct_function_base): Likewise.
	(input_function): Likewise.
	* modulo-sched.c (set_node_sched_params): Likewise.
	(extend_node_sched_params): Likewise.
	(schedule_reg_moves): Likewise.
	* omp-general.c (omp_construct_simd_compare): Likewise.
	* passes.c (pass_manager::create_pass_tab): Likewise.
	(enable_disable_pass): Likewise.
	* predict.c (determine_unlikely_bbs): Likewise.
	* profile.c (compute_branch_probabilities): Likewise.
	* read-rtl-function.c (function_reader::parse_block): Likewise.
	* read-rtl.c (rtx_reader::read_rtx_code): Likewise.
	* reg-stack.c (stack_regs_mentioned): Likewise.
	* regrename.c (regrename_init): Likewise.
	* rtlanal.c (T>::add_single_to_queue): Likewise.
	* sched-deps.c (init_deps_data_vector): Likewise.
	* sel-sched-ir.c (sel_extend_global_bb_info): Likewise.
	(extend_region_bb_info): Likewise.
	(extend_insn_data): Likewise.
	* symtab.c (symtab_node::create_reference): Likewise.
	* tracer.c (tail_duplicate): Likewise.
	* trans-mem.c (tm_region_init): Likewise.
	(get_bb_regions_instrumented): Likewise.
	* tree-cfg.c (init_empty_tree_cfg_for_function): Likewise.
	(build_gimple_cfg): Likewise.
	(create_bb): Likewise.
	(move_block_to_fn): Likewise.
	* tree-complex.c (tree_lower_complex): Likewise.
	* tree-if-conv.c (predicate_rhs_code): Likewise.
	* tree-inline.c (copy_bb): Likewise.
	* tree-into-ssa.c (get_ssa_name_ann): Likewise.
	(mark_phi_for_rewrite): Likewise.
	* tree-object-size.c (compute_builtin_object_size): Likewise.
	(init_object_sizes): Likewise.
	* tree-predcom.c (initialize_root_vars_store_elim_1): Likewise.
	(initialize_root_vars_store_elim_2): Likewise.
	(prepare_initializers_chain_store_elim): Likewise.
	* tree-ssa-address.c (addr_for_mem_ref): Likewise.
	(multiplier_allowed_in_address_p): Likewise.
	* tree-ssa-coalesce.c (ssa_conflicts_new): Likewise.
	* tree-ssa-forwprop.c (simplify_vector_constructor): Likewise.
	* tree-ssa-loop-ivopts.c (addr_offset_valid_p): Likewise.
	(get_address_cost_ainc): Likewise.
	* tree-ssa-loop-niter.c (discover_iteration_bound_by_body_walk): Likewise.
	* tree-ssa-pre.c (add_to_value): Likewise.
	(phi_translate_1): Likewise.
	(do_pre_regular_insertion): Likewise.
	(do_pre_partial_partial_insertion): Likewise.
	(init_pre): Likewise.
	* tree-ssa-propagate.c (ssa_prop_init): Likewise.
	(update_call_from_tree): Likewise.
	* tree-ssa-reassoc.c (optimize_range_tests_cmp_bitwise): Likewise.
	* tree-ssa-sccvn.c (vn_reference_lookup_3): Likewise.
	(vn_reference_lookup_pieces): Likewise.
	(eliminate_dom_walker::eliminate_push_avail): Likewise.
	* tree-ssa-strlen.c (set_strinfo): Likewise.
	(get_stridx_plus_constant): Likewise.
	(zero_length_string): Likewise.
	(find_equal_ptrs): Likewise.
	(printf_strlen_execute): Likewise.
	* tree-ssa-threadedge.c (set_ssa_name_value): Likewise.
	* tree-ssanames.c (make_ssa_name_fn): Likewise.
	* tree-streamer-in.c (streamer_read_tree_bitfields): Likewise.
	* tree-vect-loop.c (vect_record_loop_mask): Likewise.
	(vect_get_loop_mask): Likewise.
	(vect_record_loop_len): Likewise.
	(vect_get_loop_len): Likewise.
	* tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Likewise.
	* tree-vect-slp.c (vect_slp_convert_to_external): Likewise.
	(vect_bb_slp_scalar_cost): Likewise.
	(vect_bb_vectorization_profitable_p): Likewise.
	(vectorizable_slp_permutation): Likewise.
	* tree-vect-stmts.c (vectorizable_call): Likewise.
	(vectorizable_simd_clone_call): Likewise.
	(scan_store_can_perm_p): Likewise.
	(vectorizable_store): Likewise.
	* vec.c (test_safe_grow_cleared): Likewise.
	* vec.h (vec_safe_grow): Likewise.
	(vec_safe_grow_cleared): Likewise.
	(vl_ptr>::safe_grow): Likewise.
	(vl_ptr>::safe_grow_cleared): Likewise.
	* config/c6x/c6x.c (insn_set_clock): Likewise.

gcc/c/ChangeLog:

	* gimple-parser.c (c_parser_gimple_compound_statement): Set exact argument of a vector
	growth function to true.

gcc/cp/ChangeLog:

	* class.c (build_vtbl_initializer): Set exact argument of a vector
	growth function to true.
	* constraint.cc (get_mapped_args): Likewise.
	* decl.c (cp_maybe_mangle_decomp): Likewise.
	(cp_finish_decomp): Likewise.
	* parser.c (cp_parser_omp_for_loop): Likewise.
	* pt.c (canonical_type_parameter): Likewise.
	* rtti.c (get_pseudo_ti_init): Likewise.

gcc/fortran/ChangeLog:

	* trans-openmp.c (gfc_trans_omp_do): Set exact argument of a vector
	growth function to true.

gcc/lto/ChangeLog:

	* lto-common.c (lto_file_finalize): Set exact argument of a vector
	growth function to true.
---
 gcc/ada/gcc-interface/trans.c              |  4 ++--
 gcc/alias.c                                |  5 ++--
 gcc/c/gimple-parser.c                      |  4 ++--
 gcc/calls.c                                |  2 +-
 gcc/cfgbuild.c                             |  2 +-
 gcc/cfgexpand.c                            | 12 +++++-----
 gcc/cfgrtl.c                               |  2 +-
 gcc/combine.c                              |  4 ++--
 gcc/config/aarch64/aarch64-sve-builtins.cc | 10 ++++----
 gcc/config/c6x/c6x.c                       |  2 +-
 gcc/cp/class.c                             |  5 ++--
 gcc/cp/constraint.cc                       |  2 +-
 gcc/cp/decl.c                              |  4 ++--
 gcc/cp/parser.c                            |  2 +-
 gcc/cp/pt.c                                |  2 +-
 gcc/cp/rtti.c                              |  2 +-
 gcc/df-core.c                              |  4 ++--
 gcc/dwarf2cfi.c                            |  2 +-
 gcc/early-remat.c                          |  4 ++--
 gcc/except.c                               |  2 +-
 gcc/final.c                                |  4 ++--
 gcc/fortran/trans-openmp.c                 |  2 +-
 gcc/function.c                             |  2 +-
 gcc/fwprop.c                               |  6 ++---
 gcc/gcc.c                                  |  2 +-
 gcc/genautomata.c                          |  6 ++---
 gcc/genmatch.c                             |  4 ++--
 gcc/genrecog.c                             | 12 +++++-----
 gcc/gimple-loop-versioning.cc              |  4 ++--
 gcc/gimple.c                               |  2 +-
 gcc/graphite-isl-ast-to-gimple.c           |  2 +-
 gcc/haifa-sched.c                          |  4 ++--
 gcc/insn-addr.h                            |  4 ++--
 gcc/ipa-cp.c                               |  9 ++++----
 gcc/ipa-devirt.c                           |  4 ++--
 gcc/ipa-fnsummary.c                        | 24 +++++++++----------
 gcc/ipa-icf.c                              |  2 +-
 gcc/ipa-prop.c                             | 26 ++++++++++-----------
 gcc/ipa-reference.c                        |  2 +-
 gcc/ipa-split.c                            |  2 +-
 gcc/ira.c                                  |  2 +-
 gcc/lower-subreg.c                         |  2 +-
 gcc/lto-streamer-in.c                      | 18 +++++++--------
 gcc/lto/lto-common.c                       |  2 +-
 gcc/modulo-sched.c                         |  6 ++---
 gcc/omp-general.c                          |  2 +-
 gcc/passes.c                               |  4 ++--
 gcc/predict.c                              |  2 +-
 gcc/profile.c                              |  2 +-
 gcc/read-rtl-function.c                    |  2 +-
 gcc/read-rtl.c                             |  2 +-
 gcc/reg-stack.c                            |  2 +-
 gcc/regrename.c                            |  2 +-
 gcc/rtlanal.c                              |  2 +-
 gcc/sched-deps.c                           |  2 +-
 gcc/sel-sched-ir.c                         |  6 ++---
 gcc/symtab.c                               |  3 ++-
 gcc/tracer.c                               |  2 +-
 gcc/trans-mem.c                            |  4 ++--
 gcc/tree-cfg.c                             | 12 +++++-----
 gcc/tree-complex.c                         |  4 ++--
 gcc/tree-if-conv.c                         |  2 +-
 gcc/tree-inline.c                          |  2 +-
 gcc/tree-into-ssa.c                        |  4 ++--
 gcc/tree-object-size.c                     |  4 ++--
 gcc/tree-predcom.c                         |  8 +++----
 gcc/tree-ssa-address.c                     |  4 ++--
 gcc/tree-ssa-coalesce.c                    |  2 +-
 gcc/tree-ssa-forwprop.c                    |  2 +-
 gcc/tree-ssa-loop-ivopts.c                 |  4 ++--
 gcc/tree-ssa-loop-niter.c                  |  2 +-
 gcc/tree-ssa-pre.c                         | 13 ++++++-----
 gcc/tree-ssa-propagate.c                   |  4 ++--
 gcc/tree-ssa-reassoc.c                     |  4 ++--
 gcc/tree-ssa-sccvn.c                       |  8 +++----
 gcc/tree-ssa-strlen.c                      | 10 ++++----
 gcc/tree-ssa-threadedge.c                  |  2 +-
 gcc/tree-ssanames.c                        |  2 +-
 gcc/tree-streamer-in.c                     |  2 +-
 gcc/tree-vect-loop.c                       |  8 +++----
 gcc/tree-vect-patterns.c                   |  2 +-
 gcc/tree-vect-slp.c                        |  9 ++++----
 gcc/tree-vect-stmts.c                      | 15 ++++++------
 gcc/vec.c                                  |  2 +-
 gcc/vec.h                                  | 27 ++++++++++++----------
 85 files changed, 217 insertions(+), 207 deletions(-)

diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index f74e0e728c9..e3d71bca40f 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -624,7 +624,7 @@ gigi (Node_Id gnat_root,
       constructor_elt *elt;
 
       fdesc_type_node = make_node (RECORD_TYPE);
-      vec_safe_grow (null_vec, TARGET_VTABLE_USES_DESCRIPTORS);
+      vec_safe_grow (null_vec, TARGET_VTABLE_USES_DESCRIPTORS, true);
       elt = (null_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1);
 
       for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; j++)
@@ -1747,7 +1747,7 @@ Attribute_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, int attribute)
 	      gnu_result = build1 (INDIRECT_REF, gnu_result_type, gnu_result);
 	    }
 
-	  vec_safe_grow (gnu_vec, TARGET_VTABLE_USES_DESCRIPTORS);
+	  vec_safe_grow (gnu_vec, TARGET_VTABLE_USES_DESCRIPTORS, true);
 	  elt = (gnu_vec->address () + TARGET_VTABLE_USES_DESCRIPTORS - 1);
 	  for (gnu_field = TYPE_FIELDS (gnu_result_type), i = 0;
 	       i < TARGET_VTABLE_USES_DESCRIPTORS;
diff --git a/gcc/alias.c b/gcc/alias.c
index 49bd7b37966..df85f07ee9a 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -3349,7 +3349,8 @@ init_alias_analysis (void)
 
   timevar_push (TV_ALIAS_ANALYSIS);
 
-  vec_safe_grow_cleared (reg_known_value, maxreg - FIRST_PSEUDO_REGISTER);
+  vec_safe_grow_cleared (reg_known_value, maxreg - FIRST_PSEUDO_REGISTER,
+			 true);
   reg_known_equiv_p = sbitmap_alloc (maxreg - FIRST_PSEUDO_REGISTER);
   bitmap_clear (reg_known_equiv_p);
 
@@ -3360,7 +3361,7 @@ init_alias_analysis (void)
   if (reg_base_value)
     reg_base_value->truncate (0);
 
-  vec_safe_grow_cleared (reg_base_value, maxreg);
+  vec_safe_grow_cleared (reg_base_value, maxreg, true);
 
   new_reg_base_value = XNEWVEC (rtx, maxreg);
   reg_seen = sbitmap_alloc (maxreg);
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 577d8b58c7d..5c0ed826119 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -590,7 +590,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
 			       : ENTRY_BLOCK_PTR_FOR_FN (cfun)));
 	      if (basic_block_info_for_fn (cfun)->length () <= (size_t)index)
 		vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
-				       index + 1);
+				       index + 1, true);
 	      SET_BASIC_BLOCK_FOR_FN (cfun, index, bb);
 	      if (last_basic_block_for_fn (cfun) <= index)
 		last_basic_block_for_fn (cfun) = index + 1;
@@ -617,7 +617,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
 		      loop->num = is_loop_header_of;
 		      loop->header = bb;
 		      vec_safe_grow_cleared (loops_for_fn (cfun)->larray,
-					     is_loop_header_of + 1);
+					     is_loop_header_of + 1, true);
 		      (*loops_for_fn (cfun)->larray)[is_loop_header_of] = loop;
 		      flow_loop_tree_node_add (loops_for_fn (cfun)->tree_root,
 					       loop);
diff --git a/gcc/calls.c b/gcc/calls.c
index 44401e6350d..a11da66492d 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2881,7 +2881,7 @@ internal_arg_pointer_based_exp_scan (void)
 	    {
 	      if (idx >= internal_arg_pointer_exp_state.cache.length ())
 		internal_arg_pointer_exp_state.cache
-		  .safe_grow_cleared (idx + 1);
+		  .safe_grow_cleared (idx + 1, true);
 	      internal_arg_pointer_exp_state.cache[idx] = val;
 	    }
 	}
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 478afa5fe91..5c3772cd40a 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -657,7 +657,7 @@ find_many_sub_basic_blocks (sbitmap blocks)
   basic_block bb, min, max;
   bool found = false;
   auto_vec<unsigned int> n_succs;
-  n_succs.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  n_succs.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
 
   FOR_EACH_BB_FN (bb, cfun)
     SET_STATE (bb,
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b270a4ddb9d..b334ea03c25 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2949,9 +2949,9 @@ expand_asm_stmt (gasm *stmt)
 
   /* Copy the gimple vectors into new vectors that we can manipulate.  */
 
-  output_tvec.safe_grow (noutputs);
-  input_tvec.safe_grow (ninputs);
-  constraints.safe_grow (noutputs + ninputs);
+  output_tvec.safe_grow (noutputs, true);
+  input_tvec.safe_grow (ninputs, true);
+  constraints.safe_grow (noutputs + ninputs, true);
 
   for (i = 0; i < noutputs; ++i)
     {
@@ -3124,7 +3124,7 @@ expand_asm_stmt (gasm *stmt)
   auto_vec<int, MAX_RECOG_OPERANDS> inout_opnum;
   rtx_insn *after_rtl_seq = NULL, *after_rtl_end = NULL;
 
-  output_rvec.safe_grow (noutputs);
+  output_rvec.safe_grow (noutputs, true);
 
   for (i = 0; i < noutputs; ++i)
     {
@@ -3203,8 +3203,8 @@ expand_asm_stmt (gasm *stmt)
   auto_vec<rtx, MAX_RECOG_OPERANDS> input_rvec;
   auto_vec<machine_mode, MAX_RECOG_OPERANDS> input_mode;
 
-  input_rvec.safe_grow (ninputs);
-  input_mode.safe_grow (ninputs);
+  input_rvec.safe_grow (ninputs, true);
+  input_mode.safe_grow (ninputs, true);
 
   generating_concat_p = 0;
 
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 827e84a44dd..03fa688fed6 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -378,7 +378,7 @@ rtl_create_basic_block (void *headp, void *endp, basic_block after)
       size_t new_size =
 	(last_basic_block_for_fn (cfun)
 	 + (last_basic_block_for_fn (cfun) + 3) / 4);
-      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size);
+      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size, true);
     }
 
   n_basic_blocks_for_fn (cfun)++;
diff --git a/gcc/combine.c b/gcc/combine.c
index 4fee114b3cc..c88382efbd3 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -544,7 +544,7 @@ combine_split_insns (rtx pattern, rtx_insn *insn)
   ret = split_insns (pattern, insn);
   nregs = max_reg_num ();
   if (nregs > reg_stat.length ())
-    reg_stat.safe_grow_cleared (nregs);
+    reg_stat.safe_grow_cleared (nregs, true);
   return ret;
 }
 
@@ -1172,7 +1172,7 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
 
   rtl_hooks = combine_rtl_hooks;
 
-  reg_stat.safe_grow_cleared (nregs);
+  reg_stat.safe_grow_cleared (nregs, true);
 
   init_recog_no_volatile ();
 
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index c49fcebcd43..fb7a7108696 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -2792,7 +2792,7 @@ function_expander::add_output_operand (insn_code icode)
 {
   unsigned int opno = m_ops.length ();
   machine_mode mode = insn_data[icode].operand[opno].mode;
-  m_ops.safe_grow (opno + 1);
+  m_ops.safe_grow (opno + 1, true);
   create_output_operand (&m_ops.last (), possible_target, mode);
 }
 
@@ -2829,7 +2829,7 @@ function_expander::add_input_operand (insn_code icode, rtx x)
       gcc_assert (GET_MODE (x) == VNx16BImode);
       x = gen_lowpart (mode, x);
     }
-  m_ops.safe_grow (m_ops.length () + 1);
+  m_ops.safe_grow (m_ops.length () + 1, true);
   create_input_operand (&m_ops.last (), x, mode);
 }
 
@@ -2837,7 +2837,7 @@ function_expander::add_input_operand (insn_code icode, rtx x)
 void
 function_expander::add_integer_operand (HOST_WIDE_INT x)
 {
-  m_ops.safe_grow (m_ops.length () + 1);
+  m_ops.safe_grow (m_ops.length () + 1, true);
   create_integer_operand (&m_ops.last (), x);
 }
 
@@ -2861,7 +2861,7 @@ function_expander::add_mem_operand (machine_mode mode, rtx addr)
 void
 function_expander::add_address_operand (rtx x)
 {
-  m_ops.safe_grow (m_ops.length () + 1);
+  m_ops.safe_grow (m_ops.length () + 1, true);
   create_address_operand (&m_ops.last (), x);
 }
 
@@ -2870,7 +2870,7 @@ function_expander::add_address_operand (rtx x)
 void
 function_expander::add_fixed_operand (rtx x)
 {
-  m_ops.safe_grow (m_ops.length () + 1);
+  m_ops.safe_grow (m_ops.length () + 1, true);
   create_fixed_operand (&m_ops.last (), x);
 }
 
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 39b0f753047..6bd793bdd21 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -3698,7 +3698,7 @@ insn_set_clock (rtx insn, int cycle)
   unsigned uid = INSN_UID (insn);
 
   if (uid >= INSN_INFO_LENGTH)
-    insn_info.safe_grow (uid * 5 / 4 + 10);
+    insn_info.safe_grow (uid * 5 / 4 + 10, true);
 
   INSN_INFO_ENTRY (uid).clock = cycle;
   INSN_INFO_ENTRY (uid).new_cond = NULL;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b39bdaaa3ab..3479b8207d2 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -9742,7 +9742,8 @@ build_vtbl_initializer (tree binfo,
     {
       int n_entries = vec_safe_length (vid.inits);
 
-      vec_safe_grow (vid.inits, TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries);
+      vec_safe_grow (vid.inits, TARGET_VTABLE_DATA_ENTRY_DISTANCE * n_entries,
+		     true);
 
       /* Move data entries into their new positions and add padding
 	 after the new positions.  Iterate backwards so we don't
@@ -9774,7 +9775,7 @@ build_vtbl_initializer (tree binfo,
      order.  Straighten them out and add them to the running list in one
      step.  */
   jx = vec_safe_length (*inits);
-  vec_safe_grow (*inits, jx + vid.inits->length ());
+  vec_safe_grow (*inits, jx + vid.inits->length (), true);
 
   for (ix = vid.inits->length () - 1;
        vid.inits->iterate (ix, &e);
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index e4aace596e7..e7294f06d3b 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -2550,7 +2550,7 @@ get_mapped_args (tree map)
       /* Insert the argument into its corresponding position.  */
       vec<tree> &list = lists[level - 1];
       if (index >= (int)list.length ())
-	list.safe_grow_cleared (index + 1);
+	list.safe_grow_cleared (index + 1, true);
       list[index] = TREE_PURPOSE (p);
     }
 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a68bbe04da7..73891960dc6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8204,7 +8204,7 @@ cp_maybe_mangle_decomp (tree decl, tree first, unsigned int count)
       && TREE_STATIC (decl))
     {
       auto_vec<tree, 16> v;
-      v.safe_grow (count);
+      v.safe_grow (count, true);
       tree d = first;
       for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
 	v[count - i - 1] = d;
@@ -8264,7 +8264,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
     }
 
   auto_vec<tree, 16> v;
-  v.safe_grow (count);
+  v.safe_grow (count, true);
   tree d = first;
   for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
     {
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 981c625a3cd..d6c453cef92 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -39303,7 +39303,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
       TREE_VEC_ELT (incrv, i) = incr;
       if (orig_init)
 	{
-	  orig_inits.safe_grow_cleared (i + 1);
+	  orig_inits.safe_grow_cleared (i + 1, true);
 	  orig_inits[i] = orig_init;
 	}
       if (orig_decl)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cff2db4a07e..fdd376a538b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4420,7 +4420,7 @@ canonical_type_parameter (tree type)
   gcc_assert (TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM);
 
   if (vec_safe_length (canonical_template_parms) <= (unsigned) idx)
-    vec_safe_grow_cleared (canonical_template_parms, idx + 1);
+    vec_safe_grow_cleared (canonical_template_parms, idx + 1, true);
 
   for (tree list = (*canonical_template_parms)[idx];
        list; list = TREE_CHAIN (list))
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index d43248cba7c..11f3360d31f 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -1177,7 +1177,7 @@ get_pseudo_ti_init (tree type, unsigned tk_index)
 
 	gcc_assert (tk_index - TK_VMI_CLASS_TYPES + 1 == nbases);
 
-	vec_safe_grow (init_vec, nbases);
+	vec_safe_grow (init_vec, nbases, true);
 	/* Generate the base information initializer.  */
 	for (unsigned ix = nbases; ix--;)
 	  {
diff --git a/gcc/df-core.c b/gcc/df-core.c
index 9875a26895c..e0490893703 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -1014,8 +1014,8 @@ df_worklist_dataflow_doublequeue (struct dataflow *dataflow,
   vec<int> last_change_age = vNULL;
   int prev_age;
 
-  last_visit_age.safe_grow_cleared (n_blocks);
-  last_change_age.safe_grow_cleared (n_blocks);
+  last_visit_age.safe_grow_cleared (n_blocks, true);
+  last_change_age.safe_grow_cleared (n_blocks, true);
 
   /* Double-queueing. Worklist is for the current iteration,
      and pending is for the next. */
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 0d179b388e4..ccfc2bd0ea9 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -524,7 +524,7 @@ static void
 update_row_reg_save (dw_cfi_row *row, unsigned column, dw_cfi_ref cfi)
 {
   if (vec_safe_length (row->reg_save) <= column)
-    vec_safe_grow_cleared (row->reg_save, column + 1);
+    vec_safe_grow_cleared (row->reg_save, column + 1, true);
   (*row->reg_save)[column] = cfi;
 }
 
diff --git a/gcc/early-remat.c b/gcc/early-remat.c
index 9f5f8541644..5e415f77d5d 100644
--- a/gcc/early-remat.c
+++ b/gcc/early-remat.c
@@ -1007,7 +1007,7 @@ void
 early_remat::init_block_info (void)
 {
   unsigned int n_blocks = last_basic_block_for_fn (m_fn);
-  m_block_info.safe_grow_cleared (n_blocks);
+  m_block_info.safe_grow_cleared (n_blocks, true);
 }
 
 /* Maps basic block indices to their position in the post order.  */
@@ -1068,7 +1068,7 @@ void
 early_remat::finalize_candidate_indices (void)
 {
   /* Create a bitmap for each candidate register.  */
-  m_regno_to_candidates.safe_grow (max_reg_num ());
+  m_regno_to_candidates.safe_grow (max_reg_num (), true);
   unsigned int regno;
   bitmap_iterator bi;
   EXECUTE_IF_SET_IN_BITMAP (&m_candidate_regnos, 0, regno, bi)
diff --git a/gcc/except.c b/gcc/except.c
index 5df0a4c163d..3152ee120a8 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1454,7 +1454,7 @@ sjlj_build_landing_pads (void)
   num_dispatch = vec_safe_length (cfun->eh->lp_array);
   if (num_dispatch == 0)
     return;
-  sjlj_lp_call_site_index.safe_grow_cleared (num_dispatch);
+  sjlj_lp_call_site_index.safe_grow_cleared (num_dispatch, true);
 
   num_dispatch = sjlj_assign_call_site_values ();
   if (num_dispatch > 0)
diff --git a/gcc/final.c b/gcc/final.c
index a3601964a8d..80423d117d9 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -642,7 +642,7 @@ compute_alignments (void)
 
   max_labelno = max_label_num ();
   min_labelno = get_first_label_num ();
-  label_align.safe_grow_cleared (max_labelno - min_labelno + 1);
+  label_align.safe_grow_cleared (max_labelno - min_labelno + 1, true);
 
   /* If not optimizing or optimizing for size, don't assign any alignments.  */
   if (! optimize || optimize_function_for_size_p (cfun))
@@ -771,7 +771,7 @@ grow_label_align (void)
   n_labels = max_labelno - min_labelno + 1;
   n_old_labels = old - min_labelno + 1;
 
-  label_align.safe_grow_cleared (n_labels);
+  label_align.safe_grow_cleared (n_labels, true);
 
   /* Range of labels grows monotonically in the function.  Failing here
      means that the initialization of array got lost.  */
diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c
index 7891a7e651b..3484217f8d0 100644
--- a/gcc/fortran/trans-openmp.c
+++ b/gcc/fortran/trans-openmp.c
@@ -4477,7 +4477,7 @@ gfc_trans_omp_do (gfc_code *code, gfc_exec_op op, stmtblock_t *pblock,
 	  if (clauses->orderedc)
 	    {
 	      if (doacross_steps == NULL)
-		vec_safe_grow_cleared (doacross_steps, clauses->orderedc);
+		vec_safe_grow_cleared (doacross_steps, clauses->orderedc, true);
 	      (*doacross_steps)[i] = step;
 	    }
 	}
diff --git a/gcc/function.c b/gcc/function.c
index cdfcc4b6b86..2c8fa217f1f 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -637,7 +637,7 @@ static class temp_slot **
 temp_slots_at_level (int level)
 {
   if (level >= (int) vec_safe_length (used_temp_slots))
-    vec_safe_grow_cleared (used_temp_slots, level + 1);
+    vec_safe_grow_cleared (used_temp_slots, level + 1, true);
 
   return &(*used_temp_slots)[level];
 }
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 705d2885aae..756c1d6b405 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -292,10 +292,10 @@ build_single_def_use_links (void)
   df_maybe_reorganize_use_refs (DF_REF_ORDER_BY_INSN_WITH_NOTES);
 
   use_def_ref.create (DF_USES_TABLE_SIZE ());
-  use_def_ref.safe_grow_cleared (DF_USES_TABLE_SIZE ());
+  use_def_ref.safe_grow_cleared (DF_USES_TABLE_SIZE (), true);
 
   reg_defs.create (max_reg_num ());
-  reg_defs.safe_grow_cleared (max_reg_num ());
+  reg_defs.safe_grow_cleared (max_reg_num (), true);
 
   reg_defs_stack.create (n_basic_blocks_for_fn (cfun) * 10);
   local_md = BITMAP_ALLOC (NULL);
@@ -975,7 +975,7 @@ update_uses (df_ref use)
 
       /* Set up the use-def chain.  */
       if (DF_REF_ID (use) >= (int) use_def_ref.length ())
-        use_def_ref.safe_grow_cleared (DF_REF_ID (use) + 1);
+	use_def_ref.safe_grow_cleared (DF_REF_ID (use) + 1, true);
 
       if (flag_checking)
 	gcc_assert (sparseset_bit_p (active_defs_check, regno));
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 10bc9881aed..61ee1b0ad9e 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -5437,7 +5437,7 @@ insert_wrapper (const char *wrapper)
     }
   while ((p = strchr (p, ',')) != NULL);
 
-  argbuf.safe_grow (old_length + n);
+  argbuf.safe_grow (old_length + n, true);
   memmove (argbuf.address () + n,
 	   argbuf.address (),
 	   old_length * sizeof (const_char_p));
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index 0f29e206dcb..849a16162e5 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -7247,7 +7247,7 @@ create_state_ainsn_table (automaton_t automaton)
   tab->check_vect.create (10000);
 
   tab->base_vect.create (0);
-  tab->base_vect.safe_grow (automaton->achieved_states_num);
+  tab->base_vect.safe_grow (automaton->achieved_states_num, true);
 
   full_vect_length = (automaton->insn_equiv_classes_num
                       * automaton->achieved_states_num);
@@ -7339,7 +7339,7 @@ add_vect (state_ainsn_table_t tab, int vect_num, vla_hwint_t vect)
   {
     size_t full_base = tab->automaton->insn_equiv_classes_num * vect_num;
     if (tab->full_vect.length () < full_base + vect_length)
-      tab->full_vect.safe_grow (full_base + vect_length);
+      tab->full_vect.safe_grow (full_base + vect_length, true);
     for (i = 0; i < vect_length; i++)
       tab->full_vect[full_base + i] = vect[i];
   }
@@ -7743,7 +7743,7 @@ output_dead_lock_vect (automaton_t automaton)
   output_states_vect.create (0);
   pass_states (automaton, add_states_vect_el);
 
-  dead_lock_vect.safe_grow (output_states_vect.length ());
+  dead_lock_vect.safe_grow (output_states_vect.length (), true);
   for (i = 0; i < output_states_vect.length (); i++)
     {
       state_t s = output_states_vect[i];
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 107f6f2ec9e..906d842c4d8 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -2122,7 +2122,7 @@ capture_info::capture_info (simplify *s, operand *result, bool gimple_)
     }
 
   force_no_side_effects = 0;
-  info.safe_grow_cleared (s->capture_max + 1);
+  info.safe_grow_cleared (s->capture_max + 1, true);
   for (int i = 0; i <= s->capture_max; ++i)
     info[i].same_as = i;
 
@@ -5050,7 +5050,7 @@ parser::finish_match_operand (operand *op)
   /* Look for matching captures, diagnose mis-uses of @@ and apply
      early lowering and distribution of value_match.  */
   auto_vec<vec<capture *> > cpts;
-  cpts.safe_grow_cleared (capture_ids->elements ());
+  cpts.safe_grow_cleared (capture_ids->elements (), true);
   walk_captures (op, cpts);
   for (unsigned i = 0; i < cpts.length (); ++i)
     {
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index bc371b1903c..5b5b72fd6ca 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -2214,8 +2214,8 @@ optimize_subroutine_group (const char *type, state *root)
   if (cse_tests_p)
     {
       known_conditions kc;
-      kc.position_tests.safe_grow_cleared (num_positions);
-      kc.set_operands.safe_grow_cleared (num_operands);
+      kc.position_tests.safe_grow_cleared (num_positions, true);
+      kc.set_operands.safe_grow_cleared (num_operands, true);
       kc.peep2_count = 1;
       cse_tests (&root_pos, root, &kc);
     }
@@ -2337,7 +2337,7 @@ merge_pattern_info::merge_pattern_info (unsigned int num_transitions)
     num_results (0),
     routine (0)
 {
-  transitions.safe_grow_cleared (num_transitions);
+  transitions.safe_grow_cleared (num_transitions, true);
 }
 
 /* Describes one way of matching a particular state to a particular
@@ -3667,7 +3667,7 @@ merge_into_decision (decision *d1, state *s2, const int_set *exclude,
     {
       transition *trans1 = intersecting[i];
       next->truncate (0);
-      next->safe_grow (trans1->labels.length () + combined->length ());
+      next->safe_grow (trans1->labels.length () + combined->length (), true);
       int_set::iterator end
 	= std::set_union (trans1->labels.begin (), trans1->labels.end (),
 			  combined->begin (), combined->end (),
@@ -5148,7 +5148,7 @@ print_subroutine_start (output_state *os, state *s, position *root)
 	}
 
       /* Say that x1 is valid and the rest aren't.  */
-      os->seen_vars.safe_grow_cleared (num_vars);
+      os->seen_vars.safe_grow_cleared (num_vars, true);
       os->seen_vars[1] = true;
     }
   if (os->type == SUBPATTERN || os->type == RECOG)
@@ -5421,7 +5421,7 @@ main (int argc, const char **argv)
   optimize_subroutine_group ("peephole2_insns", &peephole2_root);
 
   output_state os;
-  os.id_to_var.safe_grow_cleared (num_positions);
+  os.id_to_var.safe_grow_cleared (num_positions, true);
 
   if (use_pattern_routines_p)
     {
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index 002b2a68b96..2687088a908 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -555,7 +555,7 @@ loop_versioning::loop_versioning (function *fn)
   gcc_obstack_init (&m_obstack);
 
   /* Initialize the loop information.  */
-  m_loops.safe_grow_cleared (m_nloops);
+  m_loops.safe_grow_cleared (m_nloops, true);
   for (unsigned int i = 0; i < m_nloops; ++i)
     {
       m_loops[i].outermost = get_loop (m_fn, 0);
@@ -564,7 +564,7 @@ loop_versioning::loop_versioning (function *fn)
 
   /* Initialize the list of blocks that belong to each loop.  */
   unsigned int nbbs = last_basic_block_for_fn (fn);
-  m_next_block_in_loop.safe_grow (nbbs);
+  m_next_block_in_loop.safe_grow (nbbs, true);
   basic_block bb;
   FOR_EACH_BB_FN (bb, fn)
     {
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 41f7cf38b1c..337a83a9154 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1693,7 +1693,7 @@ gimple_set_bb (gimple *stmt, basic_block bb)
 	      unsigned new_len = 3 * uid / 2 + 1;
 
 	      vec_safe_grow_cleared (label_to_block_map_for_fn (cfun),
-				     new_len);
+				     new_len, true);
 	    }
 	}
 
diff --git a/gcc/graphite-isl-ast-to-gimple.c b/gcc/graphite-isl-ast-to-gimple.c
index 5fa70ff2d4e..9f39df67b88 100644
--- a/gcc/graphite-isl-ast-to-gimple.c
+++ b/gcc/graphite-isl-ast-to-gimple.c
@@ -808,7 +808,7 @@ translate_isl_ast_node_user (__isl_keep isl_ast_node *node,
   const int nb_loops = number_of_loops (cfun);
   vec<tree> iv_map;
   iv_map.create (nb_loops);
-  iv_map.safe_grow_cleared (nb_loops);
+  iv_map.safe_grow_cleared (nb_loops, true);
 
   build_iv_mapping (iv_map, gbb, user_expr, ip, pbb->scop->scop_info->region);
   isl_ast_expr_free (user_expr);
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 80687fb5359..350178c82b8 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -8967,7 +8967,7 @@ sched_extend_luids (void)
 {
   int new_luids_max_uid = get_max_uid () + 1;
 
-  sched_luids.safe_grow_cleared (new_luids_max_uid);
+  sched_luids.safe_grow_cleared (new_luids_max_uid, true);
 }
 
 /* Initialize LUID for INSN.  */
@@ -9039,7 +9039,7 @@ extend_h_i_d (void)
   if (reserve > 0
       && ! h_i_d.space (reserve))
     {
-      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2);
+      h_i_d.safe_grow_cleared (3 * get_max_uid () / 2, true);
       sched_extend_target ();
     }
 }
diff --git a/gcc/insn-addr.h b/gcc/insn-addr.h
index f595c379b42..b897c65235c 100644
--- a/gcc/insn-addr.h
+++ b/gcc/insn-addr.h
@@ -28,7 +28,7 @@ extern int insn_current_address;
   do							\
     {							\
       insn_addresses_.create (size);			\
-      insn_addresses_.safe_grow_cleared (size);		\
+      insn_addresses_.safe_grow_cleared (size, true);	\
       memset (insn_addresses_.address (),		\
 	      0, sizeof (int) * size);			\
     }							\
@@ -48,7 +48,7 @@ insn_addresses_new (rtx_insn *insn, int insn_addr)
       if (size <= insn_uid)
 	{
 	  int *p;
-	  insn_addresses_.safe_grow (insn_uid + 1);
+	  insn_addresses_.safe_grow (insn_uid + 1, true);
 	  p = insn_addresses_.address ();
 	  memset (&p[size],
 		  0, sizeof (int) * (insn_uid + 1 - size));
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 10cc59509d5..bad661eba4c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -3323,12 +3323,12 @@ gather_context_independent_values (class ipa_node_params *info,
 
   known_csts->create (0);
   known_contexts->create (0);
-  known_csts->safe_grow_cleared (count);
-  known_contexts->safe_grow_cleared (count);
+  known_csts->safe_grow_cleared (count, true);
+  known_contexts->safe_grow_cleared (count, true);
   if (known_aggs)
     {
       known_aggs->create (0);
-      known_aggs->safe_grow_cleared (count);
+      known_aggs->safe_grow_cleared (count, true);
     }
 
   if (removable_params_cost)
@@ -4821,7 +4821,8 @@ find_more_contexts_for_caller_subset (cgraph_node *node,
 	    }
 
 	  if (!known_contexts->exists ())
-	    known_contexts->safe_grow_cleared (ipa_get_param_count (info));
+	    known_contexts->safe_grow_cleared (ipa_get_param_count (info),
+					       true);
 	  (*known_contexts)[i] = newval;
 	}
 
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 3ab7049734f..067ed5ba073 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2987,7 +2987,7 @@ final_warning_record::grow_type_warnings (unsigned newlen)
   unsigned len = type_warnings.length ();
   if (newlen > len)
     {
-      type_warnings.safe_grow_cleared (newlen);
+      type_warnings.safe_grow_cleared (newlen, true);
       for (unsigned i = len; i < newlen; i++)
 	type_warnings[i].dyn_count = profile_count::zero ();
     }
@@ -4146,7 +4146,7 @@ ipa_odr_read_section (struct lto_file_decl_data *file_data, const char *data,
       /* If this is first time we see the enum, remember its definition.  */
       if (!existed_p)
 	{
-	  this_enum.vals.safe_grow_cleared (nvals);
+	  this_enum.vals.safe_grow_cleared (nvals, true);
 	  this_enum.warned = false;
 	  if (dump_file)
 	    fprintf (dump_file, "enum %s\n{\n", name);
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 59e52927151..e35f04e8eb4 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -609,13 +609,13 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 		  {
 		    gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
 		    if (!known_vals_ptr->length ())
-		      vec_safe_grow_cleared (known_vals_ptr, count);
+		      vec_safe_grow_cleared (known_vals_ptr, count, true);
 		    (*known_vals_ptr)[i] = cst;
 		  }
 		else if (inline_p && !es->param[i].change_prob)
 		  {
 		    if (!known_vals_ptr->length ())
-		      vec_safe_grow_cleared (known_vals_ptr, count);
+		      vec_safe_grow_cleared (known_vals_ptr, count, true);
 		    (*known_vals_ptr)[i] = error_mark_node;
 		  }
 
@@ -649,7 +649,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 		    if (agg.items.length ())
 		      {
 			if (!known_aggs_ptr->length ())
-			  vec_safe_grow_cleared (known_aggs_ptr, count);
+			  vec_safe_grow_cleared (known_aggs_ptr, count, true);
 			(*known_aggs_ptr)[i] = agg;
 		      }
 		  }
@@ -665,7 +665,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 		if (!ctx.useless_p ())
 		  {
 		    if (!known_contexts_ptr->length ())
-		      known_contexts_ptr->safe_grow_cleared (count);
+		      known_contexts_ptr->safe_grow_cleared (count, true);
 		    (*known_contexts_ptr)[i]
 		      = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
 		  }
@@ -686,7 +686,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
 	  if (cst)
 	    {
 	      if (!known_vals_ptr->length ())
-	        vec_safe_grow_cleared (known_vals_ptr, count);
+		vec_safe_grow_cleared (known_vals_ptr, count, true);
 	      (*known_vals_ptr)[i] = cst;
 	    }
 	}
@@ -792,7 +792,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
       struct cgraph_edge *edge, *next;
 
       info->size_time_table = 0;
-      known_vals.safe_grow_cleared (count);
+      known_vals.safe_grow_cleared (count, true);
       for (i = 0; i < count; i++)
 	{
 	  struct ipa_replace_map *r;
@@ -2485,12 +2485,12 @@ analyze_function_body (struct cgraph_node *node, bool early)
 	  fbi.node = node;
 	  fbi.info = IPA_NODE_REF (node);
 	  fbi.bb_infos = vNULL;
-	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
 	  fbi.param_count = count_formal_params (node->decl);
 	  fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
 
 	  nonconstant_names.safe_grow_cleared
-	    (SSANAMES (my_function)->length ());
+	    (SSANAMES (my_function)->length (), true);
 	}
     }
 
@@ -2624,7 +2624,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
 		  int i;
 
 		  if (count)
-		    es->param.safe_grow_cleared (count);
+		    es->param.safe_grow_cleared (count, true);
 		  for (i = 0; i < count; i++)
 		    {
 		      int prob = param_change_prob (&fbi, stmt, i);
@@ -3928,8 +3928,8 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
 
       if (count)
 	{
-	  operand_map.safe_grow_cleared (count);
-	  offset_map.safe_grow_cleared (count);
+	  operand_map.safe_grow_cleared (count, true);
+	  offset_map.safe_grow_cleared (count, true);
 	}
       for (i = 0; i < count; i++)
 	{
@@ -4168,7 +4168,7 @@ read_ipa_call_summary (class lto_input_block *ib, struct cgraph_edge *e,
   length = streamer_read_uhwi (ib);
   if (length && es && e->possibly_call_in_translation_unit_p ())
     {
-      es->param.safe_grow_cleared (length);
+      es->param.safe_grow_cleared (length, true);
       for (i = 0; i < length; i++)
 	es->param[i].change_prob = streamer_read_uhwi (ib);
     }
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 069de9d82fb..d2b4e781389 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -1586,7 +1586,7 @@ sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
   target++;
 
   if (bb_dict->length () <= (unsigned)source)
-    bb_dict->safe_grow_cleared (source + 1);
+    bb_dict->safe_grow_cleared (source + 1, true);
 
   if ((*bb_dict)[source] == 0)
     {
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index da50f0837fd..b28c78eeab4 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -276,7 +276,7 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
 
   if (!info->descriptors && param_count)
     {
-      vec_safe_grow_cleared (info->descriptors, param_count);
+      vec_safe_grow_cleared (info->descriptors, param_count, true);
       return true;
     }
   else
@@ -906,7 +906,7 @@ parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
   gcc_checking_assert (fbi);
   struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
   if (bi->param_aa_statuses.is_empty ())
-    bi->param_aa_statuses.safe_grow_cleared (fbi->param_count);
+    bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
   struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
   if (!paa->valid)
     {
@@ -2113,9 +2113,9 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 
   if (arg_num == 0 || args->jump_functions)
     return;
-  vec_safe_grow_cleared (args->jump_functions, arg_num);
+  vec_safe_grow_cleared (args->jump_functions, arg_num, true);
   if (flag_devirtualize)
-    vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num);
+    vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
 
   if (gimple_call_internal_p (call))
     return;
@@ -2877,7 +2877,7 @@ ipa_analyze_node (struct cgraph_node *node)
   fbi.node = node;
   fbi.info = IPA_NODE_REF (node);
   fbi.bb_infos = vNULL;
-  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
   fbi.param_count = ipa_get_param_count (info);
   fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
 
@@ -3024,7 +3024,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 		  if (!dst_ctx)
 		    {
 		      vec_safe_grow_cleared (args->polymorphic_call_contexts,
-					     count);
+					     count, true);
 		      dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
 		    }
 
@@ -3095,7 +3095,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
 		      if (!dst_ctx)
 			{
 			  vec_safe_grow_cleared (args->polymorphic_call_contexts,
-					         count);
+						 count, true);
 			  dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
 			}
 		      dst_ctx->combine_with (ctx);
@@ -4900,9 +4900,9 @@ ipa_read_edge_info (class lto_input_block *ib,
   if (prevails && e->possibly_call_in_translation_unit_p ())
     {
       class ipa_edge_args *args = IPA_EDGE_REF_GET_CREATE (e);
-      vec_safe_grow_cleared (args->jump_functions, count);
+      vec_safe_grow_cleared (args->jump_functions, count, true);
       if (contexts_computed)
-	vec_safe_grow_cleared (args->polymorphic_call_contexts, count);
+	vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
       for (int k = 0; k < count; k++)
 	{
 	  ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
@@ -5197,7 +5197,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
     {
       ipcp_transformation_initialize ();
       ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
-      vec_safe_grow_cleared (ts->m_vr, count);
+      vec_safe_grow_cleared (ts->m_vr, count, true);
       for (i = 0; i < count; i++)
 	{
 	  ipa_vr *parm_vr;
@@ -5219,7 +5219,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
     {
       ipcp_transformation_initialize ();
       ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
-      vec_safe_grow_cleared (ts->bits, count);
+      vec_safe_grow_cleared (ts->bits, count, true);
 
       for (i = 0; i < count; i++)
 	{
@@ -5754,11 +5754,11 @@ ipcp_transform_function (struct cgraph_node *node)
   fbi.node = node;
   fbi.info = NULL;
   fbi.bb_infos = vNULL;
-  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
   fbi.param_count = param_count;
   fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
 
-  vec_safe_grow_cleared (descriptors, param_count);
+  vec_safe_grow_cleared (descriptors, param_count, true);
   ipa_populate_param_decls (node, *descriptors);
   calculate_dominance_info (CDI_DOMINATORS);
   ipcp_modif_dom_walker (&fbi, descriptors, aggval, &something_changed,
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index c9bc1485a0c..4a6c011c525 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1057,7 +1057,7 @@ ipa_reference_write_optimization_summary (void)
   int i;
 
   vec_alloc (reference_vars_to_consider, ipa_reference_vars_uids);
-  reference_vars_to_consider->safe_grow (ipa_reference_vars_uids);
+  reference_vars_to_consider->safe_grow (ipa_reference_vars_uids, true);
 
   /* See what variables we are interested in.  */
   for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 973e72cea04..0a620247738 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1802,7 +1802,7 @@ execute_split_functions (void)
   calculate_dominance_info (CDI_DOMINATORS);
 
   /* Compute local info about basic blocks and determine function size/time.  */
-  bb_info_vec.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1);
+  bb_info_vec.safe_grow_cleared (last_basic_block_for_fn (cfun) + 1, true);
   best_split_point.split_bbs = NULL;
   basic_block return_bb = find_return_bb ();
   int tsan_exit_found = -1;
diff --git a/gcc/ira.c b/gcc/ira.c
index b748a6de3c2..a759f3c2aa8 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -4564,7 +4564,7 @@ find_moveable_pseudos (void)
 
   first_moveable_pseudo = max_regs;
   pseudo_replaced_reg.release ();
-  pseudo_replaced_reg.safe_grow_cleared (max_regs);
+  pseudo_replaced_reg.safe_grow_cleared (max_regs, true);
 
   df_analyze ();
   calculate_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index abe7180c686..82bb90ae391 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1526,7 +1526,7 @@ decompose_multiword_subregs (bool decompose_copies)
   subreg_context = BITMAP_ALLOC (NULL);
 
   reg_copy_graph.create (max);
-  reg_copy_graph.safe_grow_cleared (max);
+  reg_copy_graph.safe_grow_cleared (max, true);
   memset (reg_copy_graph.address (), 0, sizeof (bitmap) * max);
 
   speed_p = optimize_function_for_speed_p (cfun);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 15bfb614163..e02d69cc196 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -610,7 +610,7 @@ input_eh_regions (class lto_input_block *ib, class data_in *data_in,
   gcc_assert (len == (int) len);
   if (len > 0)
     {
-      vec_safe_grow_cleared (fn->eh->region_array, len);
+      vec_safe_grow_cleared (fn->eh->region_array, len, true);
       for (i = 0; i < len; i++)
 	{
 	  eh_region r = input_eh_region (ib, data_in, i);
@@ -623,7 +623,7 @@ input_eh_regions (class lto_input_block *ib, class data_in *data_in,
   gcc_assert (len == (int) len);
   if (len > 0)
     {
-      vec_safe_grow_cleared (fn->eh->lp_array, len);
+      vec_safe_grow_cleared (fn->eh->lp_array, len, true);
       for (i = 0; i < len; i++)
 	{
 	  eh_landing_pad lp = input_eh_lp (ib, data_in, i);
@@ -636,7 +636,7 @@ input_eh_regions (class lto_input_block *ib, class data_in *data_in,
   gcc_assert (len == (int) len);
   if (len > 0)
     {
-      vec_safe_grow_cleared (fn->eh->ttype_data, len);
+      vec_safe_grow_cleared (fn->eh->ttype_data, len, true);
       for (i = 0; i < len; i++)
 	{
 	  tree ttype = stream_read_tree (ib, data_in);
@@ -651,7 +651,7 @@ input_eh_regions (class lto_input_block *ib, class data_in *data_in,
     {
       if (targetm.arm_eabi_unwinder)
 	{
-	  vec_safe_grow_cleared (fn->eh->ehspec_data.arm_eabi, len);
+	  vec_safe_grow_cleared (fn->eh->ehspec_data.arm_eabi, len, true);
 	  for (i = 0; i < len; i++)
 	    {
 	      tree t = stream_read_tree (ib, data_in);
@@ -660,7 +660,7 @@ input_eh_regions (class lto_input_block *ib, class data_in *data_in,
 	}
       else
 	{
-	  vec_safe_grow_cleared (fn->eh->ehspec_data.other, len);
+	  vec_safe_grow_cleared (fn->eh->ehspec_data.other, len, true);
 	  for (i = 0; i < len; i++)
 	    {
 	      uchar c = streamer_read_uchar (ib);
@@ -712,10 +712,10 @@ input_cfg (class lto_input_block *ib, class data_in *data_in,
 
   last_basic_block_for_fn (fn) = bb_count;
   if (bb_count > basic_block_info_for_fn (fn)->length ())
-    vec_safe_grow_cleared (basic_block_info_for_fn (fn), bb_count);
+    vec_safe_grow_cleared (basic_block_info_for_fn (fn), bb_count, true);
 
   if (bb_count > label_to_block_map_for_fn (fn)->length ())
-    vec_safe_grow_cleared (label_to_block_map_for_fn (fn), bb_count);
+    vec_safe_grow_cleared (label_to_block_map_for_fn (fn), bb_count, true);
 
   index = streamer_read_hwi (ib);
   while (index != -1)
@@ -963,7 +963,7 @@ input_struct_function_base (struct function *fn, class data_in *data_in,
   if (len > 0)
     {
       int i;
-      vec_safe_grow_cleared (fn->local_decls, len);
+      vec_safe_grow_cleared (fn->local_decls, len, true);
       for (i = 0; i < len; i++)
 	{
 	  tree t = stream_read_tree (ib, data_in);
@@ -1058,7 +1058,7 @@ input_function (tree fn_decl, class data_in *data_in,
   if (n_debugargs)
     {
       vec<tree, va_gc> **debugargs = decl_debug_args_insert (fn_decl);
-      vec_safe_grow (*debugargs, n_debugargs);
+      vec_safe_grow (*debugargs, n_debugargs, true);
       for (unsigned i = 0; i < n_debugargs; ++i)
 	(**debugargs)[i] = stream_read_tree (ib, data_in);
     }
diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
index 86d8851dac7..3ca0fd83a41 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -2227,7 +2227,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file,
 
   /* Create vector for fast access of resolution.  We do this lazily
      to save memory.  */
-  resolutions.safe_grow_cleared (file_data->max_index + 1);
+  resolutions.safe_grow_cleared (file_data->max_index + 1, true);
   for (i = 0; file_data->respairs.iterate (i, &rp); i++)
     resolutions[rp->index] = rp->res;
   file_data->respairs.release ();
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 77254b31b42..86701e05550 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -440,7 +440,7 @@ static void
 set_node_sched_params (ddg_ptr g)
 {
   node_sched_param_vec.truncate (0);
-  node_sched_param_vec.safe_grow_cleared (g->num_nodes);
+  node_sched_param_vec.safe_grow_cleared (g->num_nodes, true);
 }
 
 /* Make sure that node_sched_param_vec has an entry for every move in PS.  */
@@ -448,7 +448,7 @@ static void
 extend_node_sched_params (partial_schedule_ptr ps)
 {
   node_sched_param_vec.safe_grow_cleared (ps->g->num_nodes
-					  + ps->reg_moves.length ());
+					  + ps->reg_moves.length (), true);
 }
 
 /* Update the sched_params (time, row and stage) for node U using the II,
@@ -735,7 +735,7 @@ schedule_reg_moves (partial_schedule_ptr ps)
 
       /* Create NREG_MOVES register moves.  */
       first_move = ps->reg_moves.length ();
-      ps->reg_moves.safe_grow_cleared (first_move + nreg_moves);
+      ps->reg_moves.safe_grow_cleared (first_move + nreg_moves, true);
       extend_node_sched_params (ps);
 
       /* Record the moves associated with this node.  */
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 6e6d3e1c6f6..b37a3e89026 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -1491,7 +1491,7 @@ omp_construct_simd_compare (tree clauses1, tree clauses2)
 	  }
 	unsigned HOST_WIDE_INT argno = tree_to_uhwi (OMP_CLAUSE_DECL (c));
 	if (argno >= v->length ())
-	  v->safe_grow_cleared (argno + 1);
+	  v->safe_grow_cleared (argno + 1, true);
 	(*v)[argno] = c;
       }
   /* Here, r is used as a bitmask, 2 is set if CLAUSES1 has something
diff --git a/gcc/passes.c b/gcc/passes.c
index a5da9a46f4e..6ff31ec37d7 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -892,7 +892,7 @@ pass_manager::create_pass_tab (void) const
   if (!flag_dump_passes)
     return;
 
-  pass_tab.safe_grow_cleared (passes_by_id_size + 1);
+  pass_tab.safe_grow_cleared (passes_by_id_size + 1, true);
   m_name_to_pass_map->traverse <void *, passes_pass_traverse> (NULL);
 }
 
@@ -1046,7 +1046,7 @@ enable_disable_pass (const char *arg, bool is_enable)
     tab = &disabled_pass_uid_range_tab;
 
   if ((unsigned) pass->static_pass_number >= tab->length ())
-    tab->safe_grow_cleared (pass->static_pass_number + 1);
+    tab->safe_grow_cleared (pass->static_pass_number + 1, true);
 
   if (!range_str)
     {
diff --git a/gcc/predict.c b/gcc/predict.c
index 2164a06e083..3a86b26cc18 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -3738,7 +3738,7 @@ determine_unlikely_bbs ()
   propagate_unlikely_bbs_forward ();
 
   auto_vec<int, 64> nsuccs;
-  nsuccs.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  nsuccs.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
   FOR_ALL_BB_FN (bb, cfun)
     if (!(bb->count == profile_count::zero ())
 	&& bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
diff --git a/gcc/profile.c b/gcc/profile.c
index bd1eac123df..f5c206813c7 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -412,7 +412,7 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
       return;
     }
 
-  bb_gcov_counts.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  bb_gcov_counts.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
   edge_gcov_counts = new hash_map<edge,gcov_type>;
 
   /* Attach extra info block to each bb.  */
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 3379d6453db..5ff51571f15 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -632,7 +632,7 @@ function_reader::parse_block ()
 
   size_t new_size = m_highest_bb_idx + 1;
   if (basic_block_info_for_fn (cfun)->length () < new_size)
-    vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size);
+    vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size, true);
 
   last_basic_block_for_fn (cfun) = new_size;
 
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index d5f2b11b4af..3ec83a60baf 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -1627,7 +1627,7 @@ rtx_reader::read_rtx_code (const char *code_name)
   if (reuse_id != -1)
     {
       /* Store away for later reuse.  */
-      m_reuse_rtx_by_id.safe_grow_cleared (reuse_id + 1);
+      m_reuse_rtx_by_id.safe_grow_cleared (reuse_id + 1, true);
       m_reuse_rtx_by_id[reuse_id] = return_rtx;
     }
 
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 3aac3c14817..8f98bd85750 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -318,7 +318,7 @@ stack_regs_mentioned (const_rtx insn)
       /* Allocate some extra size to avoid too many reallocs, but
 	 do not grow too quickly.  */
       max = uid + uid / 20 + 1;
-      stack_regs_mentioned_data.safe_grow_cleared (max);
+      stack_regs_mentioned_data.safe_grow_cleared (max, true);
     }
 
   test = stack_regs_mentioned_data[uid];
diff --git a/gcc/regrename.c b/gcc/regrename.c
index ebe74c50d0a..2a0e892e5fd 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -1948,7 +1948,7 @@ regrename_init (bool insn_info)
   gcc_obstack_init (&rename_obstack);
   insn_rr.create (0);
   if (insn_info)
-    insn_rr.safe_grow_cleared (get_max_uid ());
+    insn_rr.safe_grow_cleared (get_max_uid (), true);
 }
 
 /* Free all global data used by the register renamer.  */
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 1d2874d8672..5ae38b7966d 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -97,7 +97,7 @@ generic_subrtx_iterator <T>::add_single_to_queue (array_type &array,
       /* A previous iteration might also have moved from the stack to the
 	 heap, in which case the heap array will already be big enough.  */
       if (vec_safe_length (array.heap) <= i)
-	vec_safe_grow (array.heap, i + 1);
+	vec_safe_grow (array.heap, i + 1, true);
       base = array.heap->address ();
       memcpy (base, array.stack, sizeof (array.stack));
       base[LOCAL_ELEMS] = x;
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 1bc75074e5d..d8b5c53c6a4 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -4072,7 +4072,7 @@ init_deps_data_vector (void)
 {
   int reserve = (sched_max_luid + 1 - h_d_i_d.length ());
   if (reserve > 0 && ! h_d_i_d.space (reserve))
-    h_d_i_d.safe_grow_cleared (3 * sched_max_luid / 2);
+    h_d_i_d.safe_grow_cleared (3 * sched_max_luid / 2, true);
 }
 
 /* If it is profitable to use them, initialize or extend (depending on
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 4f1e4afdc4c..f58628ae92d 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -4152,14 +4152,14 @@ get_seqno_by_preds (rtx_insn *insn)
 void
 sel_extend_global_bb_info (void)
 {
-  sel_global_bb_info.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  sel_global_bb_info.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
 }
 
 /* Extend region-scope data structures for basic blocks.  */
 static void
 extend_region_bb_info (void)
 {
-  sel_region_bb_info.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  sel_region_bb_info.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
 }
 
 /* Extend all data structures to fit for all basic blocks.  */
@@ -4209,7 +4209,7 @@ extend_insn_data (void)
         size = 3 * sched_max_luid / 2;
 
 
-      s_i_d.safe_grow_cleared (size);
+      s_i_d.safe_grow_cleared (size, true);
     }
 }
 
diff --git a/gcc/symtab.c b/gcc/symtab.c
index d7dfbb676df..207c9e75890 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -592,7 +592,8 @@ symtab_node::create_reference (symtab_node *referred_node,
 
   list = &ref_list;
   old_references = vec_safe_address (list->references);
-  vec_safe_grow (list->references, vec_safe_length (list->references) + 1);
+  vec_safe_grow (list->references, vec_safe_length (list->references) + 1,
+		 true);
   ref = &list->references->last ();
 
   list2 = &referred_node->ref_list;
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 7395dd5c939..82ede722534 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -257,7 +257,7 @@ static bool
 tail_duplicate (void)
 {
   auto_vec<fibonacci_node<long, basic_block_def>*> blocks;
-  blocks.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  blocks.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
 
   basic_block *trace = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
   int *counts = XNEWVEC (int, last_basic_block_for_fn (cfun));
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index b6b9157006b..e466b24400d 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -2030,7 +2030,7 @@ tm_region_init (struct tm_region *region)
   /* We could store this information in bb->aux, but we may get called
      through get_all_tm_blocks() from another pass that may be already
      using bb->aux.  */
-  bb_regions.safe_grow_cleared (last_basic_block_for_fn (cfun));
+  bb_regions.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
 
   all_tm_regions = region;
   bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
@@ -2774,7 +2774,7 @@ get_bb_regions_instrumented (bool traverse_clones,
   vec<tm_region *> ret;
 
   ret.create (n);
-  ret.safe_grow_cleared (n);
+  ret.safe_grow_cleared (n, true);
   stuff.bb2reg = &ret;
   stuff.include_uninstrumented_p = include_uninstrumented_p;
   expand_regions (all_tm_regions, collect_bb2reg, &stuff, traverse_clones);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index b4d0c6db238..2bae2eeddba 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -183,12 +183,12 @@ init_empty_tree_cfg_for_function (struct function *fn)
   last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
   vec_alloc (basic_block_info_for_fn (fn), initial_cfg_capacity);
   vec_safe_grow_cleared (basic_block_info_for_fn (fn),
-			 initial_cfg_capacity);
+			 initial_cfg_capacity, true);
 
   /* Build a mapping of labels to their associated blocks.  */
   vec_alloc (label_to_block_map_for_fn (fn), initial_cfg_capacity);
   vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
-			 initial_cfg_capacity);
+			 initial_cfg_capacity, true);
 
   SET_BASIC_BLOCK_FOR_FN (fn, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (fn));
   SET_BASIC_BLOCK_FOR_FN (fn, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (fn));
@@ -232,7 +232,7 @@ build_gimple_cfg (gimple_seq seq)
   if (basic_block_info_for_fn (cfun)->length ()
       < (size_t) n_basic_blocks_for_fn (cfun))
     vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
-			   n_basic_blocks_for_fn (cfun));
+			   n_basic_blocks_for_fn (cfun), true);
 
   /* To speed up statement iterator walks, we first purge dead labels.  */
   cleanup_dead_labels ();
@@ -685,7 +685,7 @@ create_bb (void *h, void *e, basic_block after)
       size_t new_size =
 	(last_basic_block_for_fn (cfun)
 	 + (last_basic_block_for_fn (cfun) + 3) / 4);
-      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size);
+      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size, true);
     }
 
   /* Add the newly created block to the array.  */
@@ -7135,7 +7135,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
   if ((unsigned) cfg->x_last_basic_block >= old_len)
     {
       new_len = cfg->x_last_basic_block + (cfg->x_last_basic_block + 3) / 4;
-      vec_safe_grow_cleared (cfg->x_basic_block_info, new_len);
+      vec_safe_grow_cleared (cfg->x_basic_block_info, new_len, true);
     }
 
   (*cfg->x_basic_block_info)[bb->index] = bb;
@@ -7211,7 +7211,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
 	  if (old_len <= (unsigned) uid)
 	    {
 	      new_len = 3 * uid / 2 + 1;
-	      vec_safe_grow_cleared (cfg->x_label_to_block_map, new_len);
+	      vec_safe_grow_cleared (cfg->x_label_to_block_map, new_len, true);
 	    }
 
 	  (*cfg->x_label_to_block_map)[uid] = bb;
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index c5febcea3eb..2e54bbb917c 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -1776,7 +1776,7 @@ tree_lower_complex (void)
     return 0;
 
   complex_lattice_values.create (num_ssa_names);
-  complex_lattice_values.safe_grow_cleared (num_ssa_names);
+  complex_lattice_values.safe_grow_cleared (num_ssa_names, true);
 
   init_parameter_lattice_values ();
   class complex_propagate complex_propagate;
@@ -1787,7 +1787,7 @@ tree_lower_complex (void)
   complex_variable_components = new int_tree_htab_type (10);
 
   complex_ssa_name_components.create (2 * num_ssa_names);
-  complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names);
+  complex_ssa_name_components.safe_grow_cleared (2 * num_ssa_names, true);
 
   update_parameter_components ();
 
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 257759d01bf..4b8d457867e 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2222,7 +2222,7 @@ predicate_rhs_code (gassign *stmt, tree mask, tree cond,
 
   /* Construct the arguments to the conditional internal function.   */
   auto_vec<tree, 8> args;
-  args.safe_grow (nops + 1);
+  args.safe_grow (nops + 1, true);
   args[0] = mask;
   for (unsigned int i = 1; i < nops; ++i)
     args[i] = gimple_op (stmt, i);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 3160ca3f88a..0d33ee72c0f 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2099,7 +2099,7 @@ copy_bb (copy_body_data *id, basic_block bb,
 	      /* Create the new array of arguments.  */
 	      n = nargs + gimple_call_num_args (call_stmt);
 	      argarray.create (n);
-	      argarray.safe_grow_cleared (n);
+	      argarray.safe_grow_cleared (n, true);
 
 	      /* Copy all the arguments before '...'  */
 	      memcpy (argarray.address (),
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index c24931effac..0d016134774 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -323,7 +323,7 @@ get_ssa_name_ann (tree name)
 
   /* Re-allocate the vector at most once per update/into-SSA.  */
   if (ver >= len)
-    info_for_ssa_name.safe_grow_cleared (num_ssa_names);
+    info_for_ssa_name.safe_grow_cleared (num_ssa_names, true);
 
   /* But allocate infos lazily.  */
   info = info_for_ssa_name[ver];
@@ -944,7 +944,7 @@ mark_phi_for_rewrite (basic_block bb, gphi *phi)
     {
       n = (unsigned) last_basic_block_for_fn (cfun) + 1;
       if (phis_to_rewrite.length () < n)
-	phis_to_rewrite.safe_grow_cleared (n);
+	phis_to_rewrite.safe_grow_cleared (n, true);
 
       phis = phis_to_rewrite[idx];
       gcc_assert (!phis.exists ());
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index bc55b27cff0..c107cb4a866 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -612,7 +612,7 @@ compute_builtin_object_size (tree ptr, int object_size_type,
       unsigned int i;
 
       if (num_ssa_names > object_sizes[object_size_type].length ())
-	object_sizes[object_size_type].safe_grow (num_ssa_names);
+	object_sizes[object_size_type].safe_grow (num_ssa_names, true);
       if (dump_file)
 	{
 	  fprintf (dump_file, "Computing %s %sobject size for ",
@@ -1282,7 +1282,7 @@ init_object_sizes (void)
 
   for (object_size_type = 0; object_size_type <= 3; object_size_type++)
     {
-      object_sizes[object_size_type].safe_grow (num_ssa_names);
+      object_sizes[object_size_type].safe_grow (num_ssa_names, true);
       computed[object_size_type] = BITMAP_ALLOC (NULL);
     }
 
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index d2dcfe7f42d..b1d6e63559c 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -1783,7 +1783,7 @@ initialize_root_vars_store_elim_1 (chain_p chain)
   unsigned i, n = chain->length;
 
   chain->vars.create (n);
-  chain->vars.safe_grow_cleared (n);
+  chain->vars.safe_grow_cleared (n, true);
 
   /* Initialize root value for eliminated stores at each distance.  */
   for (i = 0; i < n; i++)
@@ -1843,7 +1843,7 @@ initialize_root_vars_store_elim_2 (class loop *loop,
   /* Root values are either rhs operand of stores to be eliminated, or
      loaded from memory before loop.  */
   auto_vec<tree> vtemps;
-  vtemps.safe_grow_cleared (n);
+  vtemps.safe_grow_cleared (n, true);
   for (i = 0; i < n; i++)
     {
       init = get_init_expr (chain, i);
@@ -2953,7 +2953,7 @@ prepare_initializers_chain_store_elim (class loop *loop, chain_p chain)
     }
 
   chain->inits.create (n);
-  chain->inits.safe_grow_cleared (n);
+  chain->inits.safe_grow_cleared (n, true);
 
   /* For store eliminatin chain like below:
 
@@ -2971,7 +2971,7 @@ prepare_initializers_chain_store_elim (class loop *loop, chain_p chain)
      elements because loop body is guaranteed to be executed at least once
      after loop's preheader edge.  */
   auto_vec<bool> bubbles;
-  bubbles.safe_grow_cleared (n + 1);
+  bubbles.safe_grow_cleared (n + 1, true);
   for (i = 0; i < chain->refs.length (); i++)
     bubbles[chain->refs[i]->distance] = true;
 
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index 21ad4e57e40..ec3741d7598 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -216,7 +216,7 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
 	= TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off);
 
       if (templ_index >= vec_safe_length (mem_addr_template_list))
-	vec_safe_grow_cleared (mem_addr_template_list, templ_index + 1);
+	vec_safe_grow_cleared (mem_addr_template_list, templ_index + 1, true);
 
       /* Reuse the templates for addresses, so that we do not waste memory.  */
       templ = &(*mem_addr_template_list)[templ_index];
@@ -570,7 +570,7 @@ multiplier_allowed_in_address_p (HOST_WIDE_INT ratio, machine_mode mode,
   sbitmap valid_mult;
 
   if (data_index >= valid_mult_list.length ())
-    valid_mult_list.safe_grow_cleared (data_index + 1);
+    valid_mult_list.safe_grow_cleared (data_index + 1, true);
 
   valid_mult = valid_mult_list[data_index];
   if (!valid_mult)
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 0b0b1b18dc5..a0537fb3d35 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -541,7 +541,7 @@ ssa_conflicts_new (unsigned size)
   ptr = XNEW (ssa_conflicts);
   bitmap_obstack_initialize (&ptr->obstack);
   ptr->conflicts.create (size);
-  ptr->conflicts.safe_grow_cleared (size);
+  ptr->conflicts.safe_grow_cleared (size, true);
   return ptr;
 }
 
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index a4aed3ccade..e2d008dfb92 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2290,7 +2290,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
   tree one_constant = NULL_TREE;
   tree one_nonconstant = NULL_TREE;
   auto_vec<tree> constants;
-  constants.safe_grow_cleared (nelts);
+  constants.safe_grow_cleared (nelts, true);
   auto_vec<std::pair<unsigned, unsigned>, 64> elts;
   FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
     {
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 45b31640e75..5acf044161c 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -2601,7 +2601,7 @@ addr_offset_valid_p (struct iv_use *use, poly_int64 offset)
 
   list_index = (unsigned) as * MAX_MACHINE_MODE + (unsigned) mem_mode;
   if (list_index >= vec_safe_length (addr_list))
-    vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE);
+    vec_safe_grow_cleared (addr_list, list_index + MAX_MACHINE_MODE, true);
 
   addr = (*addr_list)[list_index];
   if (!addr)
@@ -4569,7 +4569,7 @@ get_address_cost_ainc (poly_int64 ainc_step, poly_int64 ainc_offset,
       unsigned nsize = ((unsigned) as + 1) *MAX_MACHINE_MODE;
 
       gcc_assert (nsize > idx);
-      ainc_cost_data_list.safe_grow_cleared (nsize);
+      ainc_cost_data_list.safe_grow_cleared (nsize, true);
     }
 
   ainc_cost_data *data = ainc_cost_data_list[idx];
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 7d61ef080eb..b3647d9efca 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -4002,7 +4002,7 @@ discover_iteration_bound_by_body_walk (class loop *loop)
 
   /* Start walk in loop header with index set to infinite bound.  */
   queue_index = bounds.length ();
-  queues.safe_grow_cleared (queue_index + 1);
+  queues.safe_grow_cleared (queue_index + 1, true);
   queue.safe_push (loop->header);
   queues[queue_index] = queue;
   block_priority.put (loop->header, queue_index);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 0a94f4e3355..63f3a81e94c 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -626,7 +626,7 @@ add_to_value (unsigned int v, pre_expr e)
 
   if (v >= value_expressions.length ())
     {
-      value_expressions.safe_grow_cleared (v + 1);
+      value_expressions.safe_grow_cleared (v + 1, true);
     }
 
   set = value_expressions[v];
@@ -1451,7 +1451,8 @@ phi_translate_1 (bitmap_set_t dest,
 	    else
 	      {
 		new_val_id = get_next_value_id ();
-		value_expressions.safe_grow_cleared (get_max_value_id () + 1);
+		value_expressions.safe_grow_cleared (get_max_value_id () + 1,
+						     true);
 		nary = vn_nary_op_insert_pieces (newnary->length,
 						 newnary->opcode,
 						 newnary->type,
@@ -1605,7 +1606,7 @@ phi_translate_1 (bitmap_set_t dest,
 		  {
 		    new_val_id = get_next_value_id ();
 		    value_expressions.safe_grow_cleared
-		      (get_max_value_id () + 1);
+		      (get_max_value_id () + 1, true);
 		  }
 		else
 		  new_val_id = ref->value_id;
@@ -3193,7 +3194,7 @@ do_pre_regular_insertion (basic_block block, basic_block dom)
   int i;
 
   exprs = sorted_array_from_bitmap_set (ANTIC_IN (block));
-  avail.safe_grow (EDGE_COUNT (block->preds));
+  avail.safe_grow (EDGE_COUNT (block->preds), true);
 
   FOR_EACH_VEC_ELT (exprs, i, expr)
     {
@@ -3360,7 +3361,7 @@ do_pre_partial_partial_insertion (basic_block block, basic_block dom)
   int i;
 
   exprs = sorted_array_from_bitmap_set (PA_IN (block));
-  avail.safe_grow (EDGE_COUNT (block->preds));
+  avail.safe_grow (EDGE_COUNT (block->preds), true);
 
   FOR_EACH_VEC_ELT (exprs, i, expr)
     {
@@ -4099,7 +4100,7 @@ init_pre (void)
   expressions.create (0);
   expressions.safe_push (NULL);
   value_expressions.create (get_max_value_id () + 1);
-  value_expressions.safe_grow_cleared (get_max_value_id () + 1);
+  value_expressions.safe_grow_cleared (get_max_value_id () + 1, true);
   name_to_id.create (0);
 
   inserted_exprs = BITMAP_ALLOC (NULL);
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 1e057284154..5a30176d3b4 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -420,7 +420,7 @@ ssa_prop_init (void)
       FOR_EACH_EDGE (e, ei, bb->succs)
 	e->flags &= ~EDGE_EXECUTABLE;
     }
-  uid_to_stmt.safe_grow (gimple_stmt_max_uid (cfun));
+  uid_to_stmt.safe_grow (gimple_stmt_max_uid (cfun), true);
 }
 
 
@@ -671,7 +671,7 @@ update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
       if (nargs > 0)
         {
           args.create (nargs);
-          args.safe_grow_cleared (nargs);
+	  args.safe_grow_cleared (nargs, true);
 
           for (i = 0; i < nargs; i++)
             args[i] = CALL_EXPR_ARG (expr, i);
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index fed463b0350..bfeba74d7aa 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -3365,9 +3365,9 @@ optimize_range_tests_cmp_bitwise (enum tree_code opcode, int first, int length,
 
       b = TYPE_PRECISION (TREE_TYPE (ranges[i].exp)) * 2 + !zero_p;
       if (buckets.length () <= b)
-	buckets.safe_grow_cleared (b + 1);
+	buckets.safe_grow_cleared (b + 1, true);
       if (chains.length () <= (unsigned) i)
-	chains.safe_grow (i + 1);
+	chains.safe_grow (i + 1, true);
       chains[i] = buckets[b];
       buckets[b] = i + 1;
     }
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 934ae40670d..e92ebdf6dc6 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -3157,7 +3157,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
       /* We need to pre-pend vr->operands[0..i] to rhs.  */
       vec<vn_reference_op_s> old = vr->operands;
       if (i + 1 + rhs.length () > vr->operands.length ())
-	vr->operands.safe_grow (i + 1 + rhs.length ());
+	vr->operands.safe_grow (i + 1 + rhs.length (), true);
       else
 	vr->operands.truncate (i + 1 + rhs.length ());
       FOR_EACH_VEC_ELT (rhs, j, vro)
@@ -3362,7 +3362,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
       if (vr->operands.length () < 2)
 	{
 	  vec<vn_reference_op_s> old = vr->operands;
-	  vr->operands.safe_grow_cleared (2);
+	  vr->operands.safe_grow_cleared (2, true);
 	  if (old == shared_lookup_references)
 	    shared_lookup_references = vr->operands;
 	}
@@ -3448,7 +3448,7 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set,
 
   vr1.vuse = vuse_ssa_val (vuse);
   shared_lookup_references.truncate (0);
-  shared_lookup_references.safe_grow (operands.length ());
+  shared_lookup_references.safe_grow (operands.length (), true);
   memcpy (shared_lookup_references.address (),
 	  operands.address (),
 	  sizeof (vn_reference_op_s)
@@ -5714,7 +5714,7 @@ eliminate_dom_walker::eliminate_push_avail (basic_block, tree op)
   if (TREE_CODE (valnum) == SSA_NAME)
     {
       if (avail.length () <= SSA_NAME_VERSION (valnum))
-	avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1);
+	avail.safe_grow_cleared (SSA_NAME_VERSION (valnum) + 1, true);
       tree pushop = op;
       if (avail[SSA_NAME_VERSION (valnum)])
 	pushop = avail[SSA_NAME_VERSION (valnum)];
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index fbaee745f7d..9793f52bbd2 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -712,7 +712,7 @@ set_strinfo (int idx, strinfo *si)
   if (vec_safe_length (stridx_to_strinfo) && (*stridx_to_strinfo)[0])
     unshare_strinfo_vec ();
   if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
-    vec_safe_grow_cleared (stridx_to_strinfo, idx + 1);
+    vec_safe_grow_cleared (stridx_to_strinfo, idx + 1, true);
   (*stridx_to_strinfo)[idx] = si;
 }
 
@@ -1365,7 +1365,7 @@ get_stridx_plus_constant (strinfo *basesi, unsigned HOST_WIDE_INT off,
 
   if (TREE_CODE (ptr) == SSA_NAME
       && ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
-    ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
+    ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
 
   gcc_checking_assert (compare_tree_int (si->nonzero_chars, off) != -1);
   for (chainsi = si; chainsi->next; chainsi = si)
@@ -1429,7 +1429,7 @@ zero_length_string (tree ptr, strinfo *chainsi)
   strinfo *si;
   int idx;
   if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
-    ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
+    ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
   gcc_checking_assert (TREE_CODE (ptr) == SSA_NAME
 		       && ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] == 0);
 
@@ -1582,7 +1582,7 @@ find_equal_ptrs (tree ptr, int idx)
       /* We might find an endptr created in this pass.  Grow the
 	 vector in that case.  */
       if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
-	ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
+	ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
 
       if (ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] != 0)
 	return;
@@ -5912,7 +5912,7 @@ printf_strlen_execute (function *fun, bool warn_only)
 
   /* This has to happen after initializing the loop optimizer
      and initializing SCEV as they create new SSA_NAMEs.  */
-  ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
+  ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
   max_stridx = 1;
 
   /* String length optimization is implemented as a walk of the dominator
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index c7c08213f9a..03a210846cb 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -59,7 +59,7 @@ void
 set_ssa_name_value (tree name, tree value)
 {
   if (SSA_NAME_VERSION (name) >= ssa_name_values.length ())
-    ssa_name_values.safe_grow_cleared (SSA_NAME_VERSION (name) + 1);
+    ssa_name_values.safe_grow_cleared (SSA_NAME_VERSION (name) + 1, true);
   if (value && TREE_OVERFLOW_P (value))
     value = drop_tree_overflow (value);
   ssa_name_values[SSA_NAME_VERSION (name)] = value;
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index d9432657e30..6ac97fe39c4 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -287,7 +287,7 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt,
       t = make_node (SSA_NAME);
       SSA_NAME_VERSION (t) = version;
       if (version >= SSANAMES (fn)->length ())
-	vec_safe_grow_cleared (SSANAMES (fn), version + 1);
+	vec_safe_grow_cleared (SSANAMES (fn), version + 1, true);
       gcc_assert ((*SSANAMES (fn))[version] == NULL);
       (*SSANAMES (fn))[version] = t;
       ssa_name_nodes_created++;
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index 707a0591bfe..a456709ffd8 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -555,7 +555,7 @@ streamer_read_tree_bitfields (class lto_input_block *ib,
     {
       unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (&bp);
       if (length > 0)
-	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
+	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length, true);
     }
 
 #ifndef ACCEL_COMPILER
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index dba230f6320..78043be2e59 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -8392,7 +8392,7 @@ vect_record_loop_mask (loop_vec_info loop_vinfo, vec_loop_masks *masks,
 {
   gcc_assert (nvectors != 0);
   if (masks->length () < nvectors)
-    masks->safe_grow_cleared (nvectors);
+    masks->safe_grow_cleared (nvectors, true);
   rgroup_controls *rgm = &(*masks)[nvectors - 1];
   /* The number of scalars per iteration and the number of vectors are
      both compile-time constants.  */
@@ -8432,7 +8432,7 @@ vect_get_loop_mask (gimple_stmt_iterator *gsi, vec_loop_masks *masks,
      used it.  */
   if (rgm->controls.is_empty ())
     {
-      rgm->controls.safe_grow_cleared (nvectors);
+      rgm->controls.safe_grow_cleared (nvectors, true);
       for (unsigned int i = 0; i < nvectors; ++i)
 	{
 	  tree mask = make_temp_ssa_name (mask_type, NULL, "loop_mask");
@@ -8474,7 +8474,7 @@ vect_record_loop_len (loop_vec_info loop_vinfo, vec_loop_lens *lens,
 {
   gcc_assert (nvectors != 0);
   if (lens->length () < nvectors)
-    lens->safe_grow_cleared (nvectors);
+    lens->safe_grow_cleared (nvectors, true);
   rgroup_controls *rgl = &(*lens)[nvectors - 1];
 
   /* The number of scalars per iteration, scalar occupied bytes and
@@ -8510,7 +8510,7 @@ vect_get_loop_len (loop_vec_info loop_vinfo, vec_loop_lens *lens,
      used it.  */
   if (rgl->controls.is_empty ())
     {
-      rgl->controls.safe_grow_cleared (nvectors);
+      rgl->controls.safe_grow_cleared (nvectors, true);
       for (unsigned int i = 0; i < nvectors; ++i)
 	{
 	  tree len_type = LOOP_VINFO_RGROUP_COMPARE_TYPE (loop_vinfo);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 03d50ec5c90..478a45a2281 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -4282,7 +4282,7 @@ vect_recog_mask_conversion_pattern (vec_info *vinfo,
 
       auto_vec<tree, 8> args;
       unsigned int nargs = gimple_call_num_args (last_stmt);
-      args.safe_grow (nargs);
+      args.safe_grow (nargs, true);
       for (unsigned int i = 0; i < nargs; ++i)
 	args[i] = ((int) i == mask_argno
 		   ? tmp
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 72192b5a813..c78428d7b92 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -2804,7 +2804,7 @@ vect_slp_convert_to_external (vec_info *vinfo, slp_tree node,
      (need to) ignore child nodes of anything that isn't vect_internal_def.  */
   unsigned int group_size = SLP_TREE_LANES (node);
   SLP_TREE_DEF_TYPE (node) = vect_external_def;
-  SLP_TREE_SCALAR_OPS (node).safe_grow (group_size);
+  SLP_TREE_SCALAR_OPS (node).safe_grow (group_size, true);
   FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (node), i, stmt_info)
     {
       tree lhs = gimple_get_lhs (vect_orig_stmt (stmt_info)->stmt);
@@ -3102,7 +3102,7 @@ vect_bb_slp_scalar_cost (vec_info *vinfo,
 	     confine changes in the callee to the current child/subtree.  */
 	  if (SLP_TREE_CODE (node) == VEC_PERM_EXPR)
 	    {
-	      subtree_life.safe_grow_cleared (SLP_TREE_LANES (child));
+	      subtree_life.safe_grow_cleared (SLP_TREE_LANES (child), true);
 	      for (unsigned j = 0;
 		   j < SLP_TREE_LANE_PERMUTATION (node).length (); ++j)
 		{
@@ -3141,7 +3141,8 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
   FOR_EACH_VEC_ELT (slp_instances, i, instance)
     {
       auto_vec<bool, 20> life;
-      life.safe_grow_cleared (SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)));
+      life.safe_grow_cleared (SLP_TREE_LANES (SLP_INSTANCE_TREE (instance)),
+			      true);
       vect_bb_slp_scalar_cost (bb_vinfo,
 			       SLP_INSTANCE_TREE (instance),
 			       &life, &scalar_costs, visited);
@@ -4147,7 +4148,7 @@ vectorizable_slp_permutation (vec_info *vinfo, gimple_stmt_iterator *gsi,
   auto_vec<std::pair<std::pair<unsigned, unsigned>, unsigned> > vperm;
   auto_vec<unsigned> active_lane;
   vperm.create (olanes);
-  active_lane.safe_grow_cleared (SLP_TREE_CHILDREN (node).length ());
+  active_lane.safe_grow_cleared (SLP_TREE_CHILDREN (node).length (), true);
   for (unsigned i = 0; i < vf; ++i)
     {
       for (unsigned pi = 0; pi < perm.length (); ++pi)
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 65e30bac424..948c508833a 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3364,8 +3364,8 @@ vectorizable_call (vec_info *vinfo,
   if (modifier == NONE || ifn != IFN_LAST)
     {
       tree prev_res = NULL_TREE;
-      vargs.safe_grow (nargs);
-      orig_vargs.safe_grow (nargs);
+      vargs.safe_grow (nargs, true);
+      orig_vargs.safe_grow (nargs, true);
       auto_vec<vec<tree> > vec_defs (nargs);
       for (j = 0; j < ncopies; ++j)
 	{
@@ -4012,7 +4012,8 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
 		== SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP))
 	  {
 	    STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_grow_cleared (i * 3
-									+ 1);
+									+ 1,
+								      true);
 	    STMT_VINFO_SIMD_CLONE_INFO (stmt_info).safe_push (arginfo[i].op);
 	    tree lst = POINTER_TYPE_P (TREE_TYPE (arginfo[i].op))
 		       ? size_type_node : TREE_TYPE (arginfo[i].op);
@@ -4052,8 +4053,8 @@ vectorizable_simd_clone_call (vec_info *vinfo, stmt_vec_info stmt_info,
 
   auto_vec<vec<tree> > vec_oprnds;
   auto_vec<unsigned> vec_oprnds_i;
-  vec_oprnds.safe_grow_cleared (nargs);
-  vec_oprnds_i.safe_grow_cleared (nargs);
+  vec_oprnds.safe_grow_cleared (nargs, true);
+  vec_oprnds_i.safe_grow_cleared (nargs, true);
   for (j = 0; j < ncopies; ++j)
     {
       /* Build argument list for the vectorized call.  */
@@ -6348,7 +6349,7 @@ scan_store_can_perm_p (tree vectype, tree init,
       if (use_whole_vector)
 	{
 	  if (kind != scan_store_kind_perm && use_whole_vector->is_empty ())
-	    use_whole_vector->safe_grow_cleared (i);
+	    use_whole_vector->safe_grow_cleared (i, true);
 	  if (kind != scan_store_kind_perm || !use_whole_vector->is_empty ())
 	    use_whole_vector->safe_push (kind);
 	}
@@ -7831,7 +7832,7 @@ vectorizable_store (vec_info *vinfo,
   tree vec_mask = NULL;
   auto_vec<tree> vec_offsets;
   auto_vec<vec<tree> > gvec_oprnds;
-  gvec_oprnds.safe_grow_cleared (group_size);
+  gvec_oprnds.safe_grow_cleared (group_size, true);
   for (j = 0; j < ncopies; j++)
     {
       gimple *new_stmt;
diff --git a/gcc/vec.c b/gcc/vec.c
index 1c4b958871b..a28899170ed 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -338,7 +338,7 @@ test_safe_grow_cleared ()
 {
   auto_vec <int> v;
   ASSERT_EQ (0, v.length ());
-  v.safe_grow_cleared (50);
+  v.safe_grow_cleared (50, true);
   ASSERT_EQ (50, v.length ());
   ASSERT_EQ (0, v[0]);
   ASSERT_EQ (0, v[49]);
diff --git a/gcc/vec.h b/gcc/vec.h
index 3ad99b83690..e6e40e2f265 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -723,11 +723,12 @@ vec_free (vec<T, A, vl_embed> *&v)
 /* Grow V to length LEN.  Allocate it, if necessary.  */
 template<typename T, typename A>
 inline void
-vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
+vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len,
+	       bool exact CXX_MEM_STAT_INFO)
 {
   unsigned oldlen = vec_safe_length (v);
   gcc_checking_assert (len >= oldlen);
-  vec_safe_reserve_exact (v, len - oldlen PASS_MEM_STAT);
+  vec_safe_reserve (v, len - oldlen, exact PASS_MEM_STAT);
   v->quick_grow (len);
 }
 
@@ -735,10 +736,11 @@ vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
 /* If V is NULL, allocate it.  Call V->safe_grow_cleared(LEN).  */
 template<typename T, typename A>
 inline void
-vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
+vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len,
+		       bool exact CXX_MEM_STAT_INFO)
 {
   unsigned oldlen = vec_safe_length (v);
-  vec_safe_grow (v, len PASS_MEM_STAT);
+  vec_safe_grow (v, len, exact PASS_MEM_STAT);
   vec_default_construct (v->address () + oldlen, len - oldlen);
 }
 
@@ -748,9 +750,9 @@ vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len CXX_MEM_STAT_INFO)
 template<typename T>
 inline void
 vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
-		       unsigned len CXX_MEM_STAT_INFO)
+		       unsigned len, bool exact CXX_MEM_STAT_INFO)
 {
-  v->safe_grow_cleared (len PASS_MEM_STAT);
+  v->safe_grow_cleared (len, exact PASS_MEM_STAT);
 }
 
 /* If V does not have space for NELEMS elements, call
@@ -1460,8 +1462,8 @@ public:
   T *safe_push (const T &CXX_MEM_STAT_INFO);
   T &pop (void);
   void truncate (unsigned);
-  void safe_grow (unsigned CXX_MEM_STAT_INFO);
-  void safe_grow_cleared (unsigned CXX_MEM_STAT_INFO);
+  void safe_grow (unsigned, bool CXX_MEM_STAT_INFO);
+  void safe_grow_cleared (unsigned, bool CXX_MEM_STAT_INFO);
   void quick_grow (unsigned);
   void quick_grow_cleared (unsigned);
   void quick_insert (unsigned, const T &);
@@ -1887,11 +1889,11 @@ vec<T, va_heap, vl_ptr>::truncate (unsigned size)
 
 template<typename T>
 inline void
-vec<T, va_heap, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
+vec<T, va_heap, vl_ptr>::safe_grow (unsigned len, bool exact MEM_STAT_DECL)
 {
   unsigned oldlen = length ();
   gcc_checking_assert (oldlen <= len);
-  reserve_exact (len - oldlen PASS_MEM_STAT);
+  reserve (len - oldlen, exact PASS_MEM_STAT);
   if (m_vec)
     m_vec->quick_grow (len);
   else
@@ -1905,11 +1907,12 @@ vec<T, va_heap, vl_ptr>::safe_grow (unsigned len MEM_STAT_DECL)
 
 template<typename T>
 inline void
-vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len MEM_STAT_DECL)
+vec<T, va_heap, vl_ptr>::safe_grow_cleared (unsigned len, bool exact
+					    MEM_STAT_DECL)
 {
   unsigned oldlen = length ();
   size_t growby = len - oldlen;
-  safe_grow (len PASS_MEM_STAT);
+  safe_grow (len, exact PASS_MEM_STAT);
   if (growby != 0)
     vec_default_construct (address () + oldlen, growby);
 }
-- 
2.28.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 2/3] vec: default exact = false in grow functions.
  2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
@ 2020-08-11 11:37                     ` Martin Liška
  2020-08-26 21:00                       ` Jeff Law
  2020-08-11 11:37                     ` [PATCH 3/3] vec: use inexact growth where possible Martin Liška
                                       ` (3 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-08-11 11:37 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0002-vec-default-exect-false-in-grow-functions.patch --]
[-- Type: text/x-patch, Size: 2045 bytes --]

From 292532ea9e3d42ca164b9951674c1eccc86a1f11 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Mon, 10 Aug 2020 12:01:59 +0200
Subject: [PATCH 2/3] vec: default exect = false in grow functions.

gcc/ChangeLog:

	* vec.h (vec_safe_grow): Change default of exact to false.
	(vec_safe_grow_cleared): Likewise.
---
 gcc/vec.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/vec.h b/gcc/vec.h
index e6e40e2f265..a908d751ab7 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -724,7 +724,7 @@ vec_free (vec<T, A, vl_embed> *&v)
 template<typename T, typename A>
 inline void
 vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len,
-	       bool exact CXX_MEM_STAT_INFO)
+	       bool exact = false CXX_MEM_STAT_INFO)
 {
   unsigned oldlen = vec_safe_length (v);
   gcc_checking_assert (len >= oldlen);
@@ -737,7 +737,7 @@ vec_safe_grow (vec<T, A, vl_embed> *&v, unsigned len,
 template<typename T, typename A>
 inline void
 vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len,
-		       bool exact CXX_MEM_STAT_INFO)
+		       bool exact = false CXX_MEM_STAT_INFO)
 {
   unsigned oldlen = vec_safe_length (v);
   vec_safe_grow (v, len, exact PASS_MEM_STAT);
@@ -750,7 +750,7 @@ vec_safe_grow_cleared (vec<T, A, vl_embed> *&v, unsigned len,
 template<typename T>
 inline void
 vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
-		       unsigned len, bool exact CXX_MEM_STAT_INFO)
+		       unsigned len, bool exact = false CXX_MEM_STAT_INFO)
 {
   v->safe_grow_cleared (len, exact PASS_MEM_STAT);
 }
@@ -1462,8 +1462,8 @@ public:
   T *safe_push (const T &CXX_MEM_STAT_INFO);
   T &pop (void);
   void truncate (unsigned);
-  void safe_grow (unsigned, bool CXX_MEM_STAT_INFO);
-  void safe_grow_cleared (unsigned, bool CXX_MEM_STAT_INFO);
+  void safe_grow (unsigned, bool = false CXX_MEM_STAT_INFO);
+  void safe_grow_cleared (unsigned, bool = false CXX_MEM_STAT_INFO);
   void quick_grow (unsigned);
   void quick_grow_cleared (unsigned);
   void quick_insert (unsigned, const T &);
-- 
2.28.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 3/3] vec: use inexact growth where possible.
  2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
  2020-08-11 11:37                     ` [PATCH 2/3] vec: default exact = false in " Martin Liška
@ 2020-08-11 11:37                     ` Martin Liška
  2020-08-26 21:02                       ` Jeff Law
  2020-08-11 14:58                     ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Sebor
                                       ` (2 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-08-11 11:37 UTC (permalink / raw)
  To: Richard Biener; +Cc: GCC Patches, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0003-vec-use-inexact-growth-where-possible.patch --]
[-- Type: text/x-patch, Size: 6322 bytes --]

From cc1d41a469d76f2f8e4f44bed788ace77a1c6d62 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Mon, 10 Aug 2020 12:09:19 +0200
Subject: [PATCH 3/3] vec: use inexact growth where possible.

gcc/ChangeLog:

	* cfgrtl.c (rtl_create_basic_block): Use default value for
	growth vector function.
	* gimple.c (gimple_set_bb): Likewise.
	* symbol-summary.h: Likewise.
	* tree-cfg.c (init_empty_tree_cfg_for_function): Likewise.
	(build_gimple_cfg): Likewise.
	(create_bb): Likewise.
	(move_block_to_fn): Likewise.
---
 gcc/cfgrtl.c         |  8 ++------
 gcc/gimple.c         |  7 +------
 gcc/symbol-summary.h | 13 +++----------
 gcc/tree-cfg.c       | 27 +++++++++------------------
 4 files changed, 15 insertions(+), 40 deletions(-)

diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 03fa688fed6..0e65537f255 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -374,12 +374,8 @@ rtl_create_basic_block (void *headp, void *endp, basic_block after)
   /* Grow the basic block array if needed.  */
   if ((size_t) last_basic_block_for_fn (cfun)
       >= basic_block_info_for_fn (cfun)->length ())
-    {
-      size_t new_size =
-	(last_basic_block_for_fn (cfun)
-	 + (last_basic_block_for_fn (cfun) + 3) / 4);
-      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size, true);
-    }
+    vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
+			   last_basic_block_for_fn (cfun) + 1);
 
   n_basic_blocks_for_fn (cfun)++;
 
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 337a83a9154..a174ed48e0b 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1689,12 +1689,7 @@ gimple_set_bb (gimple *stmt, basic_block bb)
 	    vec_safe_length (label_to_block_map_for_fn (cfun));
 	  LABEL_DECL_UID (t) = uid = cfun->cfg->last_label_uid++;
 	  if (old_len <= (unsigned) uid)
-	    {
-	      unsigned new_len = 3 * uid / 2 + 1;
-
-	      vec_safe_grow_cleared (label_to_block_map_for_fn (cfun),
-				     new_len, true);
-	    }
+	    vec_safe_grow_cleared (label_to_block_map_for_fn (cfun), uid + 1);
 	}
 
       (*label_to_block_map_for_fn (cfun))[uid] = bb;
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index fa1df5c8015..a38eb1db778 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -354,11 +354,8 @@ public:
       id = this->m_symtab->assign_summary_id (node);
 
     if ((unsigned int)id >= m_vector->length ())
-      {
-	int newlen = this->m_symtab->cgraph_max_summary_id;
-	vec_safe_reserve (m_vector, newlen - m_vector->length ());
-	m_vector->quick_grow_cleared (newlen);
-      }
+      vec_safe_grow_cleared (m_vector,
+			     this->m_symtab->cgraph_max_summary_id);
 
     if ((*m_vector)[id] == NULL)
       (*m_vector)[id] = this->allocate_new ();
@@ -815,11 +812,7 @@ public:
       id = this->m_symtab->assign_summary_id (edge);
 
     if ((unsigned)id >= m_vector->length ())
-      {
-	int newlen = this->m_symtab->edges_max_summary_id;
-	m_vector->reserve (newlen - m_vector->length ());
-	m_vector->quick_grow_cleared (newlen);
-      }
+      vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
 
     if ((*m_vector)[id] == NULL)
       (*m_vector)[id] = this->allocate_new ();
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 2bae2eeddba..b79cf6c6d4c 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -183,12 +183,12 @@ init_empty_tree_cfg_for_function (struct function *fn)
   last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
   vec_alloc (basic_block_info_for_fn (fn), initial_cfg_capacity);
   vec_safe_grow_cleared (basic_block_info_for_fn (fn),
-			 initial_cfg_capacity, true);
+			 initial_cfg_capacity);
 
   /* Build a mapping of labels to their associated blocks.  */
   vec_alloc (label_to_block_map_for_fn (fn), initial_cfg_capacity);
   vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
-			 initial_cfg_capacity, true);
+			 initial_cfg_capacity);
 
   SET_BASIC_BLOCK_FOR_FN (fn, ENTRY_BLOCK, ENTRY_BLOCK_PTR_FOR_FN (fn));
   SET_BASIC_BLOCK_FOR_FN (fn, EXIT_BLOCK, EXIT_BLOCK_PTR_FOR_FN (fn));
@@ -232,7 +232,7 @@ build_gimple_cfg (gimple_seq seq)
   if (basic_block_info_for_fn (cfun)->length ()
       < (size_t) n_basic_blocks_for_fn (cfun))
     vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
-			   n_basic_blocks_for_fn (cfun), true);
+			   n_basic_blocks_for_fn (cfun));
 
   /* To speed up statement iterator walks, we first purge dead labels.  */
   cleanup_dead_labels ();
@@ -681,12 +681,8 @@ create_bb (void *h, void *e, basic_block after)
   /* Grow the basic block array if needed.  */
   if ((size_t) last_basic_block_for_fn (cfun)
       == basic_block_info_for_fn (cfun)->length ())
-    {
-      size_t new_size =
-	(last_basic_block_for_fn (cfun)
-	 + (last_basic_block_for_fn (cfun) + 3) / 4);
-      vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size, true);
-    }
+    vec_safe_grow_cleared (basic_block_info_for_fn (cfun),
+			   last_basic_block_for_fn (cfun) + 1);
 
   /* Add the newly created block to the array.  */
   SET_BASIC_BLOCK_FOR_FN (cfun, last_basic_block_for_fn (cfun), bb);
@@ -7097,7 +7093,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
   edge_iterator ei;
   edge e;
   gimple_stmt_iterator si;
-  unsigned old_len, new_len;
+  unsigned old_len;
 
   /* Remove BB from dominance structures.  */
   delete_from_dominance_info (CDI_DOMINATORS, bb);
@@ -7133,10 +7129,8 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
 
   old_len = vec_safe_length (cfg->x_basic_block_info);
   if ((unsigned) cfg->x_last_basic_block >= old_len)
-    {
-      new_len = cfg->x_last_basic_block + (cfg->x_last_basic_block + 3) / 4;
-      vec_safe_grow_cleared (cfg->x_basic_block_info, new_len, true);
-    }
+    vec_safe_grow_cleared (cfg->x_basic_block_info,
+			   cfg->x_last_basic_block + 1);
 
   (*cfg->x_basic_block_info)[bb->index] = bb;
 
@@ -7209,10 +7203,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
 
 	  old_len = vec_safe_length (cfg->x_label_to_block_map);
 	  if (old_len <= (unsigned) uid)
-	    {
-	      new_len = 3 * uid / 2 + 1;
-	      vec_safe_grow_cleared (cfg->x_label_to_block_map, new_len, true);
-	    }
+	    vec_safe_grow_cleared (cfg->x_label_to_block_map, uid + 1);
 
 	  (*cfg->x_label_to_block_map)[uid] = bb;
 	  (*cfun->cfg->x_label_to_block_map)[uid] = NULL;
-- 
2.28.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
  2020-08-11 11:37                     ` [PATCH 2/3] vec: default exact = false in " Martin Liška
  2020-08-11 11:37                     ` [PATCH 3/3] vec: use inexact growth where possible Martin Liška
@ 2020-08-11 14:58                     ` Martin Sebor
  2020-08-12 12:28                       ` Martin Liška
  2020-08-26 20:59                     ` Jeff Law
  2020-08-28 14:24                     ` Andrew Stubbs
  4 siblings, 1 reply; 40+ messages in thread
From: Martin Sebor @ 2020-08-11 14:58 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/11/20 5:36 AM, Martin Liška wrote:
> Hello.
> 
> All right, I did it in 3 steps:
> 1) - new exact argument is added (no default value) - I tested the on 
> x86_64-linux-gnu
> and I build all cross targets.
> 2) set default value of exact = false
> 3) change places which calculate its own growth to use the default argument

The usual intent of a default argument is to supply a value the function
is the most commonly invoked with.   But in this case it looks like it's
the opposite: most of the callers (hundreds) provide the non-default
value (true) and only a handful make use of the default.  I feel I must
be  missing something.  What is it?

Martin

> 
> I would like to install first 1) and then wait some time before the rest 
> is installed.
> 
> Thoughts?
> Martin


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-11 14:58                     ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Sebor
@ 2020-08-12 12:28                       ` Martin Liška
  2020-08-13  0:18                         ` Martin Sebor
  2020-08-26 13:54                         ` Martin Liška
  0 siblings, 2 replies; 40+ messages in thread
From: Martin Liška @ 2020-08-12 12:28 UTC (permalink / raw)
  To: Martin Sebor, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/11/20 4:58 PM, Martin Sebor wrote:
> On 8/11/20 5:36 AM, Martin Liška wrote:
>> Hello.
>>
>> All right, I did it in 3 steps:
>> 1) - new exact argument is added (no default value) - I tested the on x86_64-linux-gnu
>> and I build all cross targets.
>> 2) set default value of exact = false
>> 3) change places which calculate its own growth to use the default argument
> 
> The usual intent of a default argument is to supply a value the function
> is the most commonly invoked with.   But in this case it looks like it's
> the opposite: most of the callers (hundreds) provide the non-default
> value (true) and only a handful make use of the default.  I feel I must
> be  missing something.  What is it?

You are right, but Richi wanted to make this transformation in more defensive way.
I'm eventually planning to drop the explicit 'true' argument for most of the places
except selective scheduling and LTO streaming.

I guess Richi can defend his strategy for this ;) ?

Martin

> 
> Martin
> 
>>
>> I would like to install first 1) and then wait some time before the rest is installed.
>>
>> Thoughts?
>> Martin
> 


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-12 12:28                       ` Martin Liška
@ 2020-08-13  0:18                         ` Martin Sebor
  2020-08-26 13:54                         ` Martin Liška
  1 sibling, 0 replies; 40+ messages in thread
From: Martin Sebor @ 2020-08-13  0:18 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/12/20 6:28 AM, Martin Liška wrote:
> On 8/11/20 4:58 PM, Martin Sebor wrote:
>> On 8/11/20 5:36 AM, Martin Liška wrote:
>>> Hello.
>>>
>>> All right, I did it in 3 steps:
>>> 1) - new exact argument is added (no default value) - I tested the on 
>>> x86_64-linux-gnu
>>> and I build all cross targets.
>>> 2) set default value of exact = false
>>> 3) change places which calculate its own growth to use the default 
>>> argument
>>
>> The usual intent of a default argument is to supply a value the function
>> is the most commonly invoked with.   But in this case it looks like it's
>> the opposite: most of the callers (hundreds) provide the non-default
>> value (true) and only a handful make use of the default.  I feel I must
>> be  missing something.  What is it?
> 
> You are right, but Richi wanted to make this transformation in more 
> defensive way.
> I'm eventually planning to drop the explicit 'true' argument for most of 
> the places
> except selective scheduling and LTO streaming.

If it's just transitional on the way toward the usual approach
then that seems fine (although even then I can't say I understand
the rationale for going this circuitous route).

Thanks
Martin

> 
> I guess Richi can defend his strategy for this ;) ?
> 
> Martin
> 
>>
>> Martin
>>
>>>
>>> I would like to install first 1) and then wait some time before the 
>>> rest is installed.
>>>
>>> Thoughts?
>>> Martin
>>
> 


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-12 12:28                       ` Martin Liška
  2020-08-13  0:18                         ` Martin Sebor
@ 2020-08-26 13:54                         ` Martin Liška
  2020-08-27 23:29                           ` Martin Sebor
  1 sibling, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-08-26 13:54 UTC (permalink / raw)
  To: Martin Sebor, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/12/20 2:28 PM, Martin Liška wrote:
> I guess Richi can defend his strategy for this

Richi?

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
                                       ` (2 preceding siblings ...)
  2020-08-11 14:58                     ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Sebor
@ 2020-08-26 20:59                     ` Jeff Law
  2020-08-28 14:24                     ` Andrew Stubbs
  4 siblings, 0 replies; 40+ messages in thread
From: Jeff Law @ 2020-08-26 20:59 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On Tue, 2020-08-11 at 13:36 +0200, Martin Liška wrote:
> Hello.
> 
> All right, I did it in 3 steps:
> 1) - new exact argument is added (no default value) - I tested the on x86_64-linux-gnu
> and I build all cross targets.
> 2) set default value of exact = false
> 3) change places which calculate its own growth to use the default argument
> 
> I would like to install first 1) and then wait some time before the rest is installed.
> 
> Thoughts?
Given this is how Richi wanted the series to play out.  #1 is fine with me as is
the plan for the kit as a whole.

Jeff
> 


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/3] vec: default exact = false in grow functions.
  2020-08-11 11:37                     ` [PATCH 2/3] vec: default exact = false in " Martin Liška
@ 2020-08-26 21:00                       ` Jeff Law
  0 siblings, 0 replies; 40+ messages in thread
From: Jeff Law @ 2020-08-26 21:00 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On Tue, 2020-08-11 at 13:37 +0200, Martin Liška wrote:
> From 292532ea9e3d42ca164b9951674c1eccc86a1f11 Mon Sep 17 00:00:00 2001
> From: Martin Liska <mliska@suse.cz>
> Date: Mon, 10 Aug 2020 12:01:59 +0200
> Subject: [PATCH 2/3] vec: default exect = false in grow functions.
> 
> gcc/ChangeLog:
> 
> 	* vec.h (vec_safe_grow): Change default of exact to false.
> 	(vec_safe_grow_cleared): Likewise.
And this is fine when you're ready to install it.
jeff


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/3] vec: use inexact growth where possible.
  2020-08-11 11:37                     ` [PATCH 3/3] vec: use inexact growth where possible Martin Liška
@ 2020-08-26 21:02                       ` Jeff Law
  2020-08-27  8:54                         ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Jeff Law @ 2020-08-26 21:02 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On Tue, 2020-08-11 at 13:37 +0200, Martin Liška wrote:
> From cc1d41a469d76f2f8e4f44bed788ace77a1c6d62 Mon Sep 17 00:00:00 2001
> From: Martin Liska <mliska@suse.cz>
> Date: Mon, 10 Aug 2020 12:09:19 +0200
> Subject: [PATCH 3/3] vec: use inexact growth where possible.
> 
> gcc/ChangeLog:
> 
> 	* cfgrtl.c (rtl_create_basic_block): Use default value for
> 	growth vector function.
> 	* gimple.c (gimple_set_bb): Likewise.
> 	* symbol-summary.h: Likewise.
> 	* tree-cfg.c (init_empty_tree_cfg_for_function): Likewise.
> 	(build_gimple_cfg): Likewise.
> 	(create_bb): Likewise.
> 	(move_block_to_fn): Likewise.
I'll note that in some cases we were avoiding exponential growth in our new size
computations.  Presumably the inexact growth support will do something similar,
even if it's not exactly the same.  Right?  Assuming that's the case this is OK
too.

jeff


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/3] vec: use inexact growth where possible.
  2020-08-26 21:02                       ` Jeff Law
@ 2020-08-27  8:54                         ` Richard Biener
  2020-09-01 11:25                           ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Richard Biener @ 2020-08-27  8:54 UTC (permalink / raw)
  To: Jeff Law; +Cc: Martin Liška, GCC Patches, Jan Hubicka

On Wed, Aug 26, 2020 at 11:02 PM Jeff Law <law@redhat.com> wrote:
>
> On Tue, 2020-08-11 at 13:37 +0200, Martin Liška wrote:
> > From cc1d41a469d76f2f8e4f44bed788ace77a1c6d62 Mon Sep 17 00:00:00 2001
> > From: Martin Liska <mliska@suse.cz>
> > Date: Mon, 10 Aug 2020 12:09:19 +0200
> > Subject: [PATCH 3/3] vec: use inexact growth where possible.
> >
> > gcc/ChangeLog:
> >
> >       * cfgrtl.c (rtl_create_basic_block): Use default value for
> >       growth vector function.
> >       * gimple.c (gimple_set_bb): Likewise.
> >       * symbol-summary.h: Likewise.
> >       * tree-cfg.c (init_empty_tree_cfg_for_function): Likewise.
> >       (build_gimple_cfg): Likewise.
> >       (create_bb): Likewise.
> >       (move_block_to_fn): Likewise.
> I'll note that in some cases we were avoiding exponential growth in our new size
> computations.  Presumably the inexact growth support will do something similar,
> even if it's not exactly the same.  Right?  Assuming that's the case this is OK
> too.

@@ -183,12 +183,12 @@ init_empty_tree_cfg_for_function (struct function *fn)
   last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
   vec_alloc (basic_block_info_for_fn (fn), initial_cfg_capacity);
   vec_safe_grow_cleared (basic_block_info_for_fn (fn),
-                        initial_cfg_capacity, true);
+                        initial_cfg_capacity);

   /* Build a mapping of labels to their associated blocks.  */
   vec_alloc (label_to_block_map_for_fn (fn), initial_cfg_capacity);
   vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
-                        initial_cfg_capacity, true);
+                        initial_cfg_capacity);

this is odd now at least since we explicitely alloc initial_cfg_capacity.
IMHO we should instead use

 basic_block_info_for_fn (fn)->quick_grow_cleared (initial_cfg_capacity)

here?

The rest looks OK and along the plan.

Thanks,
Richard.

> jeff
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-26 13:54                         ` Martin Liška
@ 2020-08-27 23:29                           ` Martin Sebor
  2020-08-28  6:49                             ` Martin Liška
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Sebor @ 2020-08-27 23:29 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

With --enable-valgrind-annotations the change to the member function
signature in this patch triggers compilation errors during bootstrap:

/src/gcc/trunk/gcc/ggc-common.c: In function ‘void gt_pch_save(FILE*)’:
/src/gcc/trunk/gcc/ggc-common.c:509:33: error: no matching function for 
call to ‘vec<char>::safe_grow(size_t&)’
       vbits.safe_grow (valid_size);
                                  ^
In file included from /src/gcc/trunk/gcc/hash-table.h:248,
                  from /src/gcc/trunk/gcc/coretypes.h:476,
                  from /src/gcc/trunk/gcc/ggc-common.c:26:
/src/gcc/trunk/gcc/vec.h:1897:1: note: candidate: ‘void 
vec<T>::safe_grow(unsigned int, bool) [with T = char]’
  vec<T, va_heap, vl_ptr>::safe_grow (unsigned len, bool exact 
MEM_STAT_DECL)
  ^~~~~~~~~~~~~~~~~~~~~~~
/src/gcc/trunk/gcc/vec.h:1897:1: note:   candidate expects 2 arguments, 
1 provided

/src/gcc/trunk/gcc/jit/jit-recording.c: In member function ‘virtual 
gcc::jit::recording::string* 
gcc::jit::recording::switch_::make_debug_string()’:
/src/gcc/trunk/gcc/jit/jit-recording.c:6313:41: error: no matching 
function for call to ‘auto_vec<char>::safe_grow(size_t)’
  6313 |       cases_str.safe_grow (idx + 1 + len);
       |                                         ^
In file included from /src/gcc/trunk/gcc/hash-table.h:248,
                  from /src/gcc/trunk/gcc/coretypes.h:476,
                  from /src/gcc/trunk/gcc/jit/jit-recording.c:23:
/src/gcc/trunk/gcc/vec.h:1897:1: note: candidate: ‘void 
vec<T>::safe_grow(unsigned int, bool) [with T = char]’
  1897 | vec<T, va_heap, vl_ptr>::safe_grow (unsigned len, bool exact 
MEM_STAT_DECL)
       | ^~~~~~~~~~~~~~~~~~~~~~~
/src/gcc/trunk/gcc/vec.h:1897:1: note:   candidate expects 2 arguments, 
1 provided


Bootstrap succeeds with the patch below:

diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 0d528cf455c..d4691cc5448 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -506,7 +506,7 @@ gt_pch_save (FILE *f)
        if (__builtin_expect (RUNNING_ON_VALGRIND, 0))
  	{
  	  if (vbits.length () < valid_size)
-	    vbits.safe_grow (valid_size);
+	    vbits.safe_grow (valid_size, true);
  	  get_vbits = VALGRIND_GET_VBITS (state.ptrs[i]->obj,
  					  vbits.address (), valid_size);
  	  if (get_vbits == 3)
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index b73cd76a0a0..a9e6528db69 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -6310,7 +6310,7 @@ recording::switch_::make_debug_string ()
      {
        size_t len = strlen (c->get_debug_string ());
        unsigned idx = cases_str.length ();
-      cases_str.safe_grow (idx + 1 + len);
+      cases_str.safe_grow (idx + 1 + len, true);
        cases_str[idx] = ' ';
        memcpy (&(cases_str[idx + 1]),
  	      c->get_debug_string (),

Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-27 23:29                           ` Martin Sebor
@ 2020-08-28  6:49                             ` Martin Liška
  2020-08-28 14:35                               ` Martin Sebor
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-08-28  6:49 UTC (permalink / raw)
  To: Martin Sebor, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/28/20 1:29 AM, Martin Sebor wrote:
> With --enable-valgrind-annotations the change to the member function
> signature in this patch triggers compilation errors during bootstrap:

I must confirm I didn't tested the configuration. Feel free to install
the patch, it's obvious.

Thank you,
Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
                                       ` (3 preceding siblings ...)
  2020-08-26 20:59                     ` Jeff Law
@ 2020-08-28 14:24                     ` Andrew Stubbs
  2020-08-28 14:26                       ` Martin Liška
  4 siblings, 1 reply; 40+ messages in thread
From: Andrew Stubbs @ 2020-08-28 14:24 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 11/08/2020 12:36, Martin Liška wrote:
> Hello.
> 
> All right, I did it in 3 steps:
> 1) - new exact argument is added (no default value) - I tested the on 
> x86_64-linux-gnu
> and I build all cross targets.
> 2) set default value of exact = false
> 3) change places which calculate its own growth to use the default argument
> 
> I would like to install first 1) and then wait some time before the rest 
> is installed.

This broke the amdgcn-amdhsa build.

Should I just add "true" to fix it? That's enough to make it build.

Andrew

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-28 14:24                     ` Andrew Stubbs
@ 2020-08-28 14:26                       ` Martin Liška
  2020-08-28 14:44                         ` Andrew Stubbs
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-08-28 14:26 UTC (permalink / raw)
  To: Andrew Stubbs, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/28/20 4:24 PM, Andrew Stubbs wrote:
> Should I just add "true" to fix it? That's enough to make it build.

Yes, please and push it as obvious.

Thanks,
Martin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-28  6:49                             ` Martin Liška
@ 2020-08-28 14:35                               ` Martin Sebor
  0 siblings, 0 replies; 40+ messages in thread
From: Martin Sebor @ 2020-08-28 14:35 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

On 8/28/20 12:49 AM, Martin Liška wrote:
> On 8/28/20 1:29 AM, Martin Sebor wrote:
>> With --enable-valgrind-annotations the change to the member function
>> signature in this patch triggers compilation errors during bootstrap:
> 
> I must confirm I didn't tested the configuration. Feel free to install
> the patch, it's obvious.

I checked it in r11-2925.

Martin

> 
> Thank you,
> Martin


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 1/3] vec: add exact argument for various grow functions.
  2020-08-28 14:26                       ` Martin Liška
@ 2020-08-28 14:44                         ` Andrew Stubbs
  0 siblings, 0 replies; 40+ messages in thread
From: Andrew Stubbs @ 2020-08-28 14:44 UTC (permalink / raw)
  To: Martin Liška, Richard Biener; +Cc: GCC Patches, Jan Hubicka

[-- Attachment #1: Type: text/plain, Size: 248 bytes --]

On 28/08/2020 15:26, Martin Liška wrote:
> On 8/28/20 4:24 PM, Andrew Stubbs wrote:
>> Should I just add "true" to fix it? That's enough to make it build.
> 
> Yes, please and push it as obvious.

I've committed the attached.

Andrew

[-- Attachment #2: 200828-fix-vec_safe_grow_cleared.patch --]
[-- Type: text/x-patch, Size: 706 bytes --]

amdgcn: Update vec_safe_grow_cleared usage

An API change broke the amdgcn build.

gcc/ChangeLog:

	* config/gcn/gcn-tree.c (gcn_goacc_get_worker_red_decl): Add "true"
	parameter to vec_safe_grow_cleared.

diff --git a/gcc/config/gcn/gcn-tree.c b/gcc/config/gcn/gcn-tree.c
index 4dcb179ba71..a681426139b 100644
--- a/gcc/config/gcn/gcn-tree.c
+++ b/gcc/config/gcn/gcn-tree.c
@@ -456,7 +456,7 @@ gcn_goacc_get_worker_red_decl (tree type, unsigned offset)
 
       varpool_node::finalize_decl (decl);
 
-      vec_safe_grow_cleared (machfun->reduc_decls, offset + 1);
+      vec_safe_grow_cleared (machfun->reduc_decls, offset + 1, true);
       (*machfun->reduc_decls)[offset] = decl;
 
       return decl;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/3] vec: use inexact growth where possible.
  2020-08-27  8:54                         ` Richard Biener
@ 2020-09-01 11:25                           ` Martin Liška
  2020-09-01 13:00                             ` Richard Biener
  0 siblings, 1 reply; 40+ messages in thread
From: Martin Liška @ 2020-09-01 11:25 UTC (permalink / raw)
  To: Richard Biener, Jeff Law; +Cc: GCC Patches, Jan Hubicka

On 8/27/20 10:54 AM, Richard Biener wrote:
> On Wed, Aug 26, 2020 at 11:02 PM Jeff Law <law@redhat.com> wrote:
>>
>> On Tue, 2020-08-11 at 13:37 +0200, Martin Liška wrote:
>>>  From cc1d41a469d76f2f8e4f44bed788ace77a1c6d62 Mon Sep 17 00:00:00 2001
>>> From: Martin Liska <mliska@suse.cz>
>>> Date: Mon, 10 Aug 2020 12:09:19 +0200
>>> Subject: [PATCH 3/3] vec: use inexact growth where possible.
>>>
>>> gcc/ChangeLog:
>>>
>>>        * cfgrtl.c (rtl_create_basic_block): Use default value for
>>>        growth vector function.
>>>        * gimple.c (gimple_set_bb): Likewise.
>>>        * symbol-summary.h: Likewise.
>>>        * tree-cfg.c (init_empty_tree_cfg_for_function): Likewise.
>>>        (build_gimple_cfg): Likewise.
>>>        (create_bb): Likewise.
>>>        (move_block_to_fn): Likewise.
>> I'll note that in some cases we were avoiding exponential growth in our new size
>> computations.  Presumably the inexact growth support will do something similar,
>> even if it's not exactly the same.  Right?  Assuming that's the case this is OK
>> too.
> 
> @@ -183,12 +183,12 @@ init_empty_tree_cfg_for_function (struct function *fn)
>     last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
>     vec_alloc (basic_block_info_for_fn (fn), initial_cfg_capacity);
>     vec_safe_grow_cleared (basic_block_info_for_fn (fn),
> -                        initial_cfg_capacity, true);
> +                        initial_cfg_capacity);
> 
>     /* Build a mapping of labels to their associated blocks.  */
>     vec_alloc (label_to_block_map_for_fn (fn), initial_cfg_capacity);
>     vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
> -                        initial_cfg_capacity, true);
> +                        initial_cfg_capacity);
> 
> this is odd now at least since we explicitely alloc initial_cfg_capacity.
> IMHO we should instead use
> 
>   basic_block_info_for_fn (fn)->quick_grow_cleared (initial_cfg_capacity)
> 
> here?

Yes, with the following small change:

+  vec_safe_grow_cleared (basic_block_info_for_fn (fn),
+                        initial_cfg_capacity, true);

as basic_block_info_for_fn (fn) is NULL.

Thanks for review,
Martin

> 
> The rest looks OK and along the plan.
> 
> Thanks,
> Richard.
> 
>> jeff
>>


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/3] vec: use inexact growth where possible.
  2020-09-01 11:25                           ` Martin Liška
@ 2020-09-01 13:00                             ` Richard Biener
  0 siblings, 0 replies; 40+ messages in thread
From: Richard Biener @ 2020-09-01 13:00 UTC (permalink / raw)
  To: Martin Liška; +Cc: Jeff Law, GCC Patches, Jan Hubicka

On Tue, Sep 1, 2020 at 1:26 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 8/27/20 10:54 AM, Richard Biener wrote:
> > On Wed, Aug 26, 2020 at 11:02 PM Jeff Law <law@redhat.com> wrote:
> >>
> >> On Tue, 2020-08-11 at 13:37 +0200, Martin Liška wrote:
> >>>  From cc1d41a469d76f2f8e4f44bed788ace77a1c6d62 Mon Sep 17 00:00:00 2001
> >>> From: Martin Liska <mliska@suse.cz>
> >>> Date: Mon, 10 Aug 2020 12:09:19 +0200
> >>> Subject: [PATCH 3/3] vec: use inexact growth where possible.
> >>>
> >>> gcc/ChangeLog:
> >>>
> >>>        * cfgrtl.c (rtl_create_basic_block): Use default value for
> >>>        growth vector function.
> >>>        * gimple.c (gimple_set_bb): Likewise.
> >>>        * symbol-summary.h: Likewise.
> >>>        * tree-cfg.c (init_empty_tree_cfg_for_function): Likewise.
> >>>        (build_gimple_cfg): Likewise.
> >>>        (create_bb): Likewise.
> >>>        (move_block_to_fn): Likewise.
> >> I'll note that in some cases we were avoiding exponential growth in our new size
> >> computations.  Presumably the inexact growth support will do something similar,
> >> even if it's not exactly the same.  Right?  Assuming that's the case this is OK
> >> too.
> >
> > @@ -183,12 +183,12 @@ init_empty_tree_cfg_for_function (struct function *fn)
> >     last_basic_block_for_fn (fn) = NUM_FIXED_BLOCKS;
> >     vec_alloc (basic_block_info_for_fn (fn), initial_cfg_capacity);
> >     vec_safe_grow_cleared (basic_block_info_for_fn (fn),
> > -                        initial_cfg_capacity, true);
> > +                        initial_cfg_capacity);
> >
> >     /* Build a mapping of labels to their associated blocks.  */
> >     vec_alloc (label_to_block_map_for_fn (fn), initial_cfg_capacity);
> >     vec_safe_grow_cleared (label_to_block_map_for_fn (fn),
> > -                        initial_cfg_capacity, true);
> > +                        initial_cfg_capacity);
> >
> > this is odd now at least since we explicitely alloc initial_cfg_capacity.
> > IMHO we should instead use
> >
> >   basic_block_info_for_fn (fn)->quick_grow_cleared (initial_cfg_capacity)
> >
> > here?
>
> Yes, with the following small change:
>
> +  vec_safe_grow_cleared (basic_block_info_for_fn (fn),
> +                        initial_cfg_capacity, true);
>
> as basic_block_info_for_fn (fn) is NULL.

But we alloc it previously to exact size?  OK, you can drop
the vec_alloc calls of course.

> Thanks for review,
> Martin
>
> >
> > The rest looks OK and along the plan.
> >
> > Thanks,
> > Richard.
> >
> >> jeff
> >>
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2020-09-01 13:00 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-25 12:22 [PATCH] Use vec::reserve before vec_safe_grow_cleared is called Martin Liška
2020-07-27  7:11 ` Richard Biener
2020-07-27  7:14   ` Martin Liška
2020-07-27  9:51     ` Jan Hubicka
2020-07-27 10:29       ` Martin Liška
2020-07-27 10:48         ` Jan Hubicka
2020-07-27 11:00           ` Martin Liška
2020-07-27 11:03             ` Jan Hubicka
2020-07-27 11:22               ` Martin Liška
2020-07-27 12:49                 ` Andreas Schwab
2020-07-27 12:51                   ` Richard Biener
2020-07-27 12:54                     ` Martin Liška
2020-07-27 12:58                       ` Richard Biener
2020-07-27 11:07           ` Richard Biener
2020-07-27 11:11     ` Jan Hubicka
2020-07-27 11:24       ` Martin Liška
2020-07-27 11:31         ` Richard Biener
2020-07-28 10:23           ` [PATCH] Use exact=false for vec_safe_grow{,_cleared} functions Martin Liška
2020-07-29 13:47             ` Richard Biener
2020-07-30 13:22               ` Martin Liška
2020-08-03 13:47                 ` Richard Biener
2020-08-11 11:36                   ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Liška
2020-08-11 11:37                     ` [PATCH 2/3] vec: default exact = false in " Martin Liška
2020-08-26 21:00                       ` Jeff Law
2020-08-11 11:37                     ` [PATCH 3/3] vec: use inexact growth where possible Martin Liška
2020-08-26 21:02                       ` Jeff Law
2020-08-27  8:54                         ` Richard Biener
2020-09-01 11:25                           ` Martin Liška
2020-09-01 13:00                             ` Richard Biener
2020-08-11 14:58                     ` [PATCH 1/3] vec: add exact argument for various grow functions Martin Sebor
2020-08-12 12:28                       ` Martin Liška
2020-08-13  0:18                         ` Martin Sebor
2020-08-26 13:54                         ` Martin Liška
2020-08-27 23:29                           ` Martin Sebor
2020-08-28  6:49                             ` Martin Liška
2020-08-28 14:35                               ` Martin Sebor
2020-08-26 20:59                     ` Jeff Law
2020-08-28 14:24                     ` Andrew Stubbs
2020-08-28 14:26                       ` Martin Liška
2020-08-28 14:44                         ` Andrew Stubbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).