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~