Richard Sandiford <rdsandif...@googlemail.com> writes: > Jan Hubicka <hubi...@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. */