On Thu, Dec 28, 2017 at 04:53:29PM +0100, Tom de Vries wrote: > --- a/gcc/lto-cgraph.c > +++ b/gcc/lto-cgraph.c > @@ -1111,6 +1111,16 @@ output_offload_tables (void) > struct lto_simple_output_block *ob > = lto_create_simple_output_block (LTO_section_offload_table); > > + for (unsigned i = 0; i < vec_safe_length (offload_funcs);) > + { > + if (!cgraph_node::get ((*offload_funcs)[i])) > + { > + offload_funcs->ordered_remove (i); > + continue; > + } > + i++; > + }
This has O(n^2) complexity for n == vec_safe_length (offload_funcs). Can't you instead just have 2 IVs, one for where we read the vector elt and one for where we write it if the 2 are different, then truncate the vector if needed at the end? Another thing, I think you can safely remove elts from the vector (== from the host and offloading target arrays) only when !flag_lto, because we rely on the two arrays being the same. So you can't remove elts only on the host and not on the device, or vice versa. The output_offload_tables function has: /* In WHOPR mode during the WPA stage the joint offload tables need to be streamed to one partition only. That's why we free offload_funcs and offload_vars after the first call of output_offload_tables. */ if (flag_wpa) { vec_free (offload_funcs); vec_free (offload_vars); } so at least with flag_wpa, if we remove anything in there, it won't be reflected by the other tables. So, can we do something different in case we can't easily remove stuff from the vector anymore? Either store some placeholder in the tables (dunno if NULL would work or what), or instead ensure corresponding functions can't be removed? Jakub