This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

[PATCH 0/3] Support some cases of inheritance in gengtype; use it for symtab


There have been various discussions about how to handle inheritance
within ggc and PCH: whether to extend gengtype to support C++ syntax
such as templates, or to require people to use GTY((user)) and manually
write field-traversal.

I've attempted to introduce class hierarchies in a few places recently,
for example for the symtab types: 
  http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00668.html

and the gimple types:
  http://gcc.gnu.org/ml/gcc-patches/2013-08/msg01788.html

In each case the GTY((user)) is always the most painful part: it
requires ugly hand-written code which must be kept up-to-date with
changes to the underlying types, lest we run into
difficult-to-track-down crashes inside the GC and PCH.

I got sick of writing and debugging these GTY((user)) traversal
functions, for IMHO quite modest use of C++ (no templates etc), so I had
a go at implementing support for inheritance in gengtype, as seen in the
following patch series.

The key compromise I'm introducing, as I see it, is to require the user
to "opt in" to the support for the inheritance, on a class-by-class
basis, and not attempt to support all of C++, but only single
inheritance, without templates.

The idea is that if you add a GTY marker to a subclass, you are
"opting in" to gengtype, and on any restrictions on the base class that
gengtype needs to impose to avoid having to deal with all of C++ syntax:
specifically, no multiple inheritance, and the base class can't be a
template.

If those restrictions are too much, e.g. you have something like:

   struct alloc_pool_hasher : typed_noop_remove <alloc_pool_descriptor>

then don't GTY-mark the class, and gengtype won't attempt to parse the
base class (as per the current parser).

I can tweak things so that GTY((user)) classes are also excluded.

This compromise allows gengtype to autogenerate traversal functions for
simple uses of inheritance, avoiding the need for hand-maintaining them,
whilst allowing all of C++ for places that need it, without having to
support parsing all of that C++ syntax in gengtype - IMHO the best of
both approaches.

You put a "desc" GTY option on the base class to signify how to
discriminate between subclasses in the marker function.  Every concrete
subclass should have a "tag" GTY option, and gengtype builds a single
set of traversal functions, for the base class of the hierarchy, with
a big switch statement on the desc, using the tag values as the cases.
This is of course very similar to how unions are handled, and is similar
to the first part of this proposal from Lawrence Crowl:
  http://gcc.gnu.org/ml/gcc/2012-08/msg00267.html
Within such a hierarchy, traversal functions are only generated for the
base class.

I was able to use this to reimplement my port of the symtab types to a
C++ class hierarchy.  The old, ugly version of the patch can be seen at:

  http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00672.html

I've attached an updated version of the above patch to the following
patch series, which uses the new gengtype inheritance support to
eliminate all of the horrible hand-written traversal functions, and the
ugly dummy GTY roots that are needed to workaround bugs in GTY((user)).

Successfully bootstrapped and regtested this (plus the followup
autogenerated symtab refactoring from:
  http://gcc.gnu.org/ml/gcc-patches/2013-09/msg00669.html )

OK for trunk?  IMHO this is a much simpler approach; it avoids
having to deal with GTY((user)) and manually-written markers.

Presumably I would also need to update the docs.

For reference, here's what one of the generated functions looks like (I
believe this is not significantly uglier that what gtype-desc.c already
contains).  Note how the fields appear in reverse order of *types*
(i.e. from deepest subclass up to parent), within a field they appear in
natural order.  So, for example, in "case SYMTAB_FUNCTION:" the cgraph
fields appear, then the base symtab fields.  The two pch functions are
similar.

void
gt_ggc_mx_symtab_node_base (void *x_p)
{
  struct symtab_node_base * const x = (struct symtab_node_base *)x_p;
  if (ggc_test_and_set_mark (x))
    {
      switch (((*x)).type)
        {
        case SYMTAB_SYMBOL:
          gt_ggc_m_9tree_node ((*x).decl);
          gt_ggc_m_16symtab_node_base ((*x).next);
          gt_ggc_m_16symtab_node_base ((*x).previous);
          gt_ggc_m_16symtab_node_base ((*x).next_sharing_asm_name);
          gt_ggc_m_16symtab_node_base ((*x).previous_sharing_asm_name);
          gt_ggc_m_16symtab_node_base ((*x).same_comdat_group);
          gt_ggc_m_20vec_ipa_ref_t_va_gc_ ((*x).ref_list.references);
          gt_ggc_m_9tree_node ((*x).alias_target);
          gt_ggc_m_18lto_file_decl_data ((*x).lto_file_data);
          break;
        case SYMTAB_VARIABLE:
          {
            varpool_node *sub = static_cast <varpool_node *> (x);
            gt_ggc_m_9tree_node ((*sub).decl);
            gt_ggc_m_16symtab_node_base ((*sub).next);
            gt_ggc_m_16symtab_node_base ((*sub).previous);
            gt_ggc_m_16symtab_node_base ((*sub).next_sharing_asm_name);
            gt_ggc_m_16symtab_node_base ((*sub).previous_sharing_asm_name);
            gt_ggc_m_16symtab_node_base ((*sub).same_comdat_group);
            gt_ggc_m_20vec_ipa_ref_t_va_gc_ ((*sub).ref_list.references);
            gt_ggc_m_9tree_node ((*sub).alias_target);
            gt_ggc_m_18lto_file_decl_data ((*sub).lto_file_data);
          }
          break;
        case SYMTAB_FUNCTION:
          {
            cgraph_node *sub = static_cast <cgraph_node *> (x);
            gt_ggc_m_11cgraph_edge ((*sub).callers);
            gt_ggc_m_11cgraph_edge ((*sub).indirect_calls);
            gt_ggc_m_16symtab_node_base ((*sub).origin);
            gt_ggc_m_16symtab_node_base ((*sub).nested);
            gt_ggc_m_16symtab_node_base ((*sub).next_nested);
            gt_ggc_m_16symtab_node_base ((*sub).next_sibling_clone);
            gt_ggc_m_16symtab_node_base ((*sub).prev_sibling_clone);
            gt_ggc_m_16symtab_node_base ((*sub).clones);
            gt_ggc_m_16symtab_node_base ((*sub).clone_of);
            gt_ggc_m_P11cgraph_edge4htab ((*sub).call_site_hash);
            gt_ggc_m_9tree_node ((*sub).former_clone_of);
            gt_ggc_m_16symtab_node_base ((*sub).global.inlined_to);
            gt_ggc_m_28vec_ipa_replace_map_p_va_gc_ ((*sub).clone.tree_map);
            gt_ggc_m_15bitmap_head_def ((*sub).clone.args_to_skip);
            gt_ggc_m_15bitmap_head_def ((*sub).clone.combined_args_to_skip);
            gt_ggc_m_9tree_node ((*sub).thunk.alias);
            gt_ggc_m_9tree_node ((*sub).decl);
            gt_ggc_m_16symtab_node_base ((*sub).next);
            gt_ggc_m_16symtab_node_base ((*sub).previous);
            gt_ggc_m_16symtab_node_base ((*sub).next_sharing_asm_name);
            gt_ggc_m_16symtab_node_base ((*sub).previous_sharing_asm_name);
            gt_ggc_m_16symtab_node_base ((*sub).same_comdat_group);
            gt_ggc_m_20vec_ipa_ref_t_va_gc_ ((*sub).ref_list.references);
            gt_ggc_m_9tree_node ((*sub).alias_target);
            gt_ggc_m_18lto_file_decl_data ((*sub).lto_file_data);
          }
          break;
        }
    }
}

David Malcolm (3):
  Parse base classes for GTY-marked types
  Handle simple inheritance in gengtype.
  Convert symtab, cgraph and varpool nodes into a real class hierarchy

 gcc/cgraph.h         |  38 +++++------------
 gcc/gengtype-parse.c |  47 +++++++++++++++++++--
 gcc/gengtype-state.c |   2 +
 gcc/gengtype.c       | 115 +++++++++++++++++++++++++++++++++++++++++++++------
 gcc/gengtype.h       |   9 +++-
 gcc/ipa-ref.h        |   6 +--
 gcc/is-a.h           |   6 +--
 gcc/symtab.c         |   4 +-
 8 files changed, 175 insertions(+), 52 deletions(-)

-- 
1.7.11.7


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