Jan Hubicka <[email protected]> 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.
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. */