On Fri, 2013-08-02 at 10:01 -1000, Richard Henderson wrote: > On 08/02/2013 09:08 AM, David Malcolm wrote: > > For opt_pass and pass_manager, something different is going on. > > I'd wondered about that. > > > For some reason gengtype doesn't generate the triad of gt_ggc_mx_FOO, > > gt_pch_nx_FOO, gt_pch_p_NFOO functions in gtype-desc.c, for types > > FOO=opt_pass and pass_manager. Presumably this is because the types are > > only visited by code in context.c > > > > So the global functions for opt_pass and pass_manager are a hand-written > > implementation of what gengtype would write; they are called *each time* > > the entity is reached during a traversal. The member functions are > > called only the *first time* the entity is visited. > > I wonder if we can reduce the amount of boiler-plate for this. Perhaps, > > ------------------------------------------------------------------- > // > // These templates assume the presence of several member functions. > // > > template<class T> > inline void gt_ggc_mx (T *p) > { > if (ggc_test_and_set_mark (p)) > p->gt_ggc_mx (); > } > > template<class T> > void gt_pch_nx_with_obj(void *this_obj, void *p, > gt_pointer_operator op, void *cookie) > { > if (p == this_obj) > { > T *t = static_cast<T *>(p); > t->gt_pch_nx_with_obj (op, cookie); > } > } > > template<class T> > inline void gt_pch_nx (T *p) > { > if (gt_pch_note_object (p, p, gt_pch_nx_with_obj<T>)) > p->gt_pch_nx (); > } > > --------------------------------------------------------------------- > > I had thought about an abstract base class instead of the templates, but > that would unnecessarily force the use of vtables in places that don't > need them. In some cases this would be relatively harmless (e.g. the > very few pass_manager objects), but in others it might be a no-go. > > The use of the template obviates that. It ought only be instantiated when > necessary for gty user objects that don't have their own specialization.
I like this approach, and I'm trying a bootstrap now with the templates. I changed the "with_obj" to "with_op", on the grounds that you always have an obj, but you don't always have an op. FWIW I had a go at avoiding templates by attempting to tell gengtype to write out functions for all GTY((user)) types, regardless of whether it thinks they're referenced, with this: @@ -3697,7 +3697,8 @@ write_types (outf_p output_header, type_p structures, type_p param_structs, /* At last we emit the functions code. */ oprintf (output_header, "\n/* functions code */\n"); for (s = structures; s; s = s->next) - if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO) + if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO + || s->kind == TYPE_USER_STRUCT) { options_p opt; but I ran into various "incomplete structure" errors due to gengtype's lack of a full C/C++ parser. Hence templates seem the sanest option.