On 01/08/2014 10:34 AM, Jakub Jelinek wrote: > struct target_globals *g; > - > - g = ggc_alloc_target_globals (); > - g->flag_state = XCNEW (struct target_flag_state); > - g->regs = XCNEW (struct target_regs); > + struct target_globals_extra { > + struct target_globals g; > + struct target_flag_state flag_state; > + struct target_regs regs; > + struct target_hard_regs hard_regs; > + struct target_reload reload; > + struct target_expmed expmed; > + struct target_optabs optabs; > + struct target_cfgloop cfgloop; > + struct target_ira ira; > + struct target_ira_int ira_int; > + struct target_lra_int lra_int; > + struct target_builtins builtins; > + struct target_gcse gcse; > + struct target_bb_reorder bb_reorder; > + struct target_lower_subreg lower_subreg; > + } *p; > + p = (struct target_globals_extra *) > + ggc_internal_cleared_alloc_stat (sizeof (struct target_globals_extra) > + PASS_MEM_STAT); > + g = (struct target_globals *) p; > + g->flag_state = &p->flag_state; > + g->regs = &p->regs; > g->rtl = ggc_alloc_cleared_target_rtl ();
So, we're relying on something pointing to G, thus keeping the whole P alive? I suppose that works but it's fairly ugly that's for sure. As for the extra ~500k wasted on x86_64, we can either fix our gc allocator to do something sensible with these high-order allocations, or we can do nearly this same trick only with libc. I.e. struct target_globals_extra { struct target_flag_state flag_state; struct target_regs regs; struct target_hard_regs hard_regs; struct target_reload reload; struct target_expmed expmed; struct target_optabs optabs; struct target_cfgloop cfgloop; struct target_ira ira; struct target_ira_int ira_int; struct target_lra_int lra_int; struct target_builtins builtins; struct target_gcse gcse; struct target_bb_reorder bb_reorder; struct target_lower_subreg lower_subreg; } *p; g = ggc_alloc_target_globals (); p = XCNEW (target_globals_extra); ... r~