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

Reply via email to