PR61629 (was Re: Delay RTL initialization until it is really needed)
Richard Sandiford
rdsandiford@googlemail.com
Thu Jul 17 19:36:00 GMT 2014
Richard Sandiford <rdsandiford@googlemail.com> writes:
> Jan Hubicka <hubicka@ucw.cz> writes:
>> Hi,
>
>> IRA initialization shows high in profiles even when building lto
>> objects. This patch simply delays RTL backend initialization until we
>> really decide to output a function. In some cases this avoids the
>> initialization completely (like in the case of LTO but also user
>> target attributes) and there is some hope for better cache locality.
>>
>> Basic idea is to have two flags saying whether lang and target
>> dependent bits needs initialization and check it when starting
>> function codegen.
>>
>> Bootstrapped/regtested x86_64-linux, testing also at AIX. Ok if it passes?
>>
>> Honza
>>
>> * toplev.c (backend_init_target): Move init_emit_regs and init_regs to...
>> (backend_init) ... here; skip ira_init_once and backend_init_target.
>> (target_reinit) ... and here; clear this_target_rtl->lang_dependent_initialized.
>> (lang_dependent_init_target): Clear this_target_rtl->lang_dependent_initialized;
>> break out rtl initialization to ...
>> (initialize_rtl): ... here; call also backend_init_target and ira_init_once.
>> * toplev.h (initialize_rtl): New function.
>> * function.c: Include toplev.h
>> (init_function_start): Call initialize_rtl.
>> * rtl.h (target_rtl): Add target_specific_initialized,
>> lang_dependent_initialized.
>> Index: toplev.c
>> ===================================================================
>> --- toplev.c (revision 211837)
>> +++ toplev.c (working copy)
>> @@ -1583,14 +1583,6 @@ backend_init_target (void)
>> /* Initialize alignment variables. */
>> init_alignments ();
>>
>> - /* This reinitializes hard_frame_pointer, and calls init_reg_modes_target()
>> - to initialize reg_raw_mode[]. */
>> - init_emit_regs ();
>> -
>> - /* This invokes target hooks to set fixed_reg[] etc, which is
>> - mode-dependent. */
>> - init_regs ();
>> -
>> /* This depends on stack_pointer_rtx. */
>> init_fake_stack_mems ();
>>
>> @@ -1632,9 +1624,13 @@ backend_init (void)
>> init_varasm_once ();
>> save_register_info ();
>>
>> - /* Initialize the target-specific back end pieces. */
>> - ira_init_once ();
>> - backend_init_target ();
>> + /* Middle end needs this initialization for default mem attributes
>> + used by early calls to make_decl_rtl. */
>> + init_emit_regs ();
>> +
>> + /* Middle end needs this initialization for mode tables used to assign
>> + modes to vector variables. */
>> + init_regs ();
>
> This causes a segfault on gcc.target/mips/umips-store16-1.c. The register
> asm:
>
> register unsigned int global asm ("$16");
>
> causes us to globalise $16 and call reinit_regs. reinit_regs in turn
> calls ira_init, but IRA hasn't been initialised at this point and
> prerequisites like init_fake_stack_mems haven't yet been called.
>
> Does the patch below look OK?
>
>> @@ -1686,6 +1682,31 @@ lang_dependent_init_target (void)
>> front end is initialized. It also depends on the HAVE_xxx macros
>> generated from the target machine description. */
>> init_optabs ();
>> + this_target_rtl->lang_dependent_initialized = false;
>> +}
>> +
>> +/* Perform initializations that are lang-dependent or target-dependent.
>> + but matters only for late optimizations and RTL generation. */
>> +
>> +void
>> +initialize_rtl (void)
>> +{
>> + static int initialized_once;
>> +
>> + /* Initialization done just once per compilation, but delayed
>> + till code generation. */
>> + if (!initialized_once)
>> + ira_init_once ();
>> + initialized_once = true;
>> +
>> + /* Target specific RTL backend initialization. */
>> + if (!this_target_rtl->target_specific_initialized)
>> + backend_init_target ();
>> + this_target_rtl->target_specific_initialized = true;
>> +
>> + if (this_target_rtl->lang_dependent_initialized)
>> + return;
>> + this_target_rtl->lang_dependent_initialized = true;
>>
>> /* The following initialization functions need to generate rtl, so
>> provide a dummy function context for them. */
>
> Why do you need both these flags? We only call this function once
> the language has been initialised, so we should always be initialising
> both sets of information (backend_init_target and the stuff after
> the comment above, from the old lang_dependent_init_target).
>
> How about the second patch below, still under testing? The new assert
> is OK for target_reinit because it has:
>
> this_target_rtl->target_specific_initialized = false;
>
> /* This initializes hard_frame_pointer, and calls init_reg_modes_target()
> to initialize reg_raw_mode[]. */
> init_emit_regs ();
>
> /* This invokes target hooks to set fixed_reg[] etc, which is
> mode-dependent. */
> init_regs ();
>
> /* Reinitialize lang-dependent parts. */
> lang_dependent_init_target ();
>
> i.e. it sets the flag to say that the RTL stuff hasn't been initialised
> and then goes on to initialise everything that needs to be deferred.
Now tested on mips64-linux-gnu. OK for both patches?
> Thanks,
> Richard
>
>
> gcc/
> PR rtl-optimization/61629
> * reginfo.c (reinit_regs): Only call ira_init and recog_init if
> they have already been initialized.
>
> Index: gcc/reginfo.c
> ===================================================================
> --- gcc/reginfo.c 2014-07-16 07:59:00.039669668 +0100
> +++ gcc/reginfo.c 2014-07-16 07:59:00.397672987 +0100
> @@ -533,8 +533,11 @@ reinit_regs (void)
> init_regs ();
> /* caller_save needs to be re-initialized. */
> caller_save_initialized_p = false;
> - ira_init ();
> - recog_init ();
> + if (this_target_rtl->target_specific_initialized)
> + {
> + ira_init ();
> + recog_init ();
> + }
> }
>
> /* Initialize some fake stack-frame MEM references for use in
>
>
> gcc/
> * rtl.h (target_rtl): Remove lang_dependent_initialized.
> * toplev.c (initialize_rtl): Don't use it. Move previously
> "language-dependent" calls to...
> (backend_init): ...here.
> (lang_dependent_init_target): Don't set lang_dependent_initialized.
> Assert that RTL initialization hasn't happend yet.
>
> Index: gcc/rtl.h
> ===================================================================
> --- gcc/rtl.h 2014-07-11 11:55:14.265158363 +0100
> +++ gcc/rtl.h 2014-07-16 08:16:23.245370141 +0100
> @@ -2517,7 +2517,6 @@ struct GTY(()) target_rtl {
>
> /* Track if RTL has been initialized. */
> bool target_specific_initialized;
> - bool lang_dependent_initialized;
> };
>
> extern GTY(()) struct target_rtl default_target_rtl;
> Index: gcc/toplev.c
> ===================================================================
> --- gcc/toplev.c 2014-07-11 11:54:41.604838961 +0100
> +++ gcc/toplev.c 2014-07-16 08:22:36.226034738 +0100
> @@ -1604,6 +1604,10 @@ backend_init_target (void)
> on a mode change. */
> init_expmed ();
> init_lower_subreg ();
> + init_set_costs ();
> +
> + init_expr_target ();
> + ira_init ();
>
> /* We may need to recompute regno_save_code[] and regno_restore_code[]
> after a mode change as well. */
> @@ -1682,7 +1686,8 @@ lang_dependent_init_target (void)
> front end is initialized. It also depends on the HAVE_xxx macros
> generated from the target machine description. */
> init_optabs ();
> - this_target_rtl->lang_dependent_initialized = false;
> +
> + gcc_assert (!this_target_rtl->target_specific_initialized);
> }
>
> /* Perform initializations that are lang-dependent or target-dependent.
> @@ -1701,26 +1706,10 @@ initialize_rtl (void)
>
> /* Target specific RTL backend initialization. */
> if (!this_target_rtl->target_specific_initialized)
> - backend_init_target ();
> - this_target_rtl->target_specific_initialized = true;
> -
> - if (this_target_rtl->lang_dependent_initialized)
> - return;
> - this_target_rtl->lang_dependent_initialized = true;
> -
> - /* The following initialization functions need to generate rtl, so
> - provide a dummy function context for them. */
> - init_dummy_function_start ();
> -
> - /* Do the target-specific parts of expr initialization. */
> - init_expr_target ();
> -
> - /* Although the actions of these functions are language-independent,
> - they use optabs, so we cannot call them from backend_init. */
> - init_set_costs ();
> - ira_init ();
> -
> - expand_dummy_function_end ();
> + {
> + backend_init_target ();
> + this_target_rtl->target_specific_initialized = true;
> + }
> }
>
> /* Language-dependent initialization. Returns nonzero on success. */
More information about the Gcc-patches
mailing list