This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PCH [Was: Re: Target FUNCTION_{PRO,EPI}LOGUE question]


Neil Booth <neil@daikokuya.demon.co.uk> writes:

> Geoff Keating wrote:-
> 
> > I wouldn't worry too much about the GC parts of this, as all that code
> > will go away as soon as the PCH work is contributed (and you'll have a
> > different and more complicated set of problems).
> 
> Geoff,
> 
> Are you willing to give us any information about this and your PCH
> work?  I'd really like to know more about it (without downloading a
> separate branch and poring over it...)

OK, here's a high-level overview.

The precompiled header mechanism works by:

- `compiling' a header ('foo.h'), as if it was a normal .c file
- just before finishing the compilation, saving GCC's state
  (including all interesting global variables, the contents of the .s
  file so far, and lots of other stuff) to a file named foo.h.pch

- when a file is compiled, and cpplib looks for foo.h, if it also
  finds foo.h.pch, and if this is (more or less) the first thing
  in the compilation, it restores GCC's state to where it was before
- and continues without including foo.h.

The tricky part, of course, is the saving and restoring.  This is done
by having the PCH machinery know where all the global variables are,
and what type of thing they point to.  A structure is saved by
replacing all its pointers with indices into a table; reading back the
.pch file is done by reading in all the structures and replacing
the pointers.

It turns out that knowing where all the global variables are, and
about where all the pointers in all the data structures are, is
already done in the current compiler by the GC mechanism.
Unfortunately, it is not quite general enough---it doesn't always mark
all the pointers, and more annoyingly it is currently implemented as a
bunch of routines that call 'ggc_mark', which is not very flexible.

So all that code is replaced by an equivalent bunch of data
structures.  For instance, the one for 'struct function' looks like:

static const struct field_definition_s function_field_defs[] = {
  { 0, 0, offsetof (struct function, next_global), function_type_def },
  { 0, 0, offsetof (struct function, next), function_type_def },
...
  { 0, 0, offsetof (struct function, language), lang_function_type_def },
  { 0, 0, offsetof (struct function, epilogue_delay_list), rtx_type_def },
  NO_MORE_FIELDS
};

This completely replaces the routine 'mark_function_status' in
function.c, which no longer exists.  The actual 'function_type_def'
structure is defined like:

  {  /* struct function */
    NULL,
    constant_size_fetcher, 
    sizeof (struct function), 
    function_field_defs,
    NULL,
    NULL,
    0
  }

which is probably not very helpful, but all the NULLs are optional
procedures for those weird cases that are so popular in GCC :-).

There are then routines for doing things with these data structures,
for instance there is a routine that, given a type (like
'function_type_def'), and an address, will mark for GC all the
pointers in the thing at that address.

So, in this context, if a frontend wishes to specify its own 'struct
lang_function', it needs to fill in lang_function_type_def with
information about the structure of the type, at startup time.

-- 
- Geoffrey Keating <geoffk@geoffk.org>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]