On Wed, 13 Nov 2013, Jakub Jelinek wrote:

> Hi!
> 
> void f1 (void) {}
> __attribute__((target ("avx"))) void f2 (void) {}
> __attribute__((target ("avx2"))) void f3 (void) {}
> __attribute__((target ("sse3"))) void f4 (void) {}
> __attribute__((target ("ssse3"))) void f5 (void) {}
> __attribute__((target ("sse4"))) void f6 (void) {}
> takes about 3 seconds to compile at -O2, because set_cfun is terribly
> expensive and there are hundreds of such calls.
> The following patch is just a quick change to avoid some of them:
> execute_function_todo starts with:
>   unsigned int flags = (size_t)data;
>   flags &= ~cfun->last_verified;
>   if (!flags)
>     return;
> and if flags is initially zero, it does nothing.
> Similarly, execute_function_dump has the whole body surrounded by
>   if (dump_file && current_function_decl)
> and thus if dump_file is NULL, there is nothing to do.
> So IMHO in neither case (which happens pretty frequently) we need to
> set_cfun to every function during IPA.

Ok, but eventually all the TODO-called stuff should be made work
with a NULL cfun (and execute () get a struct function argument).

> Also, I wonder if we couldn't defer the expensive ira_init, if the info
> computed by it is used only during RTL optimization passes (haven't verified
> it yet), then supposedly we could just remember using some target hook
> what the last state was when we did ira_init last time, and call ira_init
> again at the start of expansion or so if it is different from the last time.
> For i?86/x86_64/ppc* this would be whether the current function's
> DECL_FUNCTION_SPECIFIC_TARGET is the same as one for which ira_init has been
> called, for rx whether interrupt attribute is the same and for mips whatever
> is needed.

I wonder why we cannot move all the stuff we re-init to a member
of struct function (or rather have a pointer to that info there
to cache it across functions with the same options).  That is,
get rid of more global state?  That would make switching back
and forth cheaper.

Thanks,
Richard.

> 2013-11-13  Jakub Jelinek  <ja...@redhat.com>
> 
>       * passes.c (execute_todo): Don't call do_per_function if
>       flags are zero.
>       (execute_one_ipa_transform_pass, execute_one_pass): Don't call
>       execute_function_dump if dump_file is NULL.
> 
> --- gcc/passes.c.jj   2013-11-12 11:31:30.000000000 +0100
> +++ gcc/passes.c      2013-11-12 18:52:40.590727542 +0100
> @@ -1875,7 +1875,8 @@ execute_todo (unsigned int flags)
>  
>    statistics_fini_pass ();
>  
> -  do_per_function (execute_function_todo, (void *)(size_t) flags);
> +  if (flags)
> +    do_per_function (execute_function_todo, (void *)(size_t) flags);
>  
>    /* Always remove functions just as before inlining: IPA passes might be
>       interested to see bodies of extern inline functions that are not inlined
> @@ -2065,7 +2066,8 @@ execute_one_ipa_transform_pass (struct c
>    if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
>      check_profile_consistency (pass->static_pass_number, 1, true);
>  
> -  do_per_function (execute_function_dump, NULL);
> +  if (dump_file)
> +    do_per_function (execute_function_dump, NULL);
>    pass_fini_dump_file (pass);
>  
>    current_pass = NULL;
> @@ -2231,7 +2233,8 @@ execute_one_pass (struct opt_pass *pass)
>      check_profile_consistency (pass->static_pass_number, 1, true);
>  
>    verify_interpass_invariants ();
> -  do_per_function (execute_function_dump, NULL);
> +  if (dump_file)
> +    do_per_function (execute_function_dump, NULL);
>    if (pass->type == IPA_PASS)
>      {
>        struct cgraph_node *node;
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

Reply via email to