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]

Re: [PATCH 00/89] Compile-time gimple-checking


On Tue, 2014-04-22 at 09:05 -0400, Andrew MacLeod wrote:
> On 04/22/2014 04:03 AM, Richard Sandiford wrote:
> > First of all, thanks a lot for doing this.  Maybe one day we'll have
> > the same in rtl :-)
> >
> > But...
> >
> > David Malcolm <dmalcolm@redhat.com> writes:
> >> In doing the checked downcasts I ran into the verbosity of the as_a <>
> >> API (in our "is-a.h").  I first tried simplifying them with custom
> >> functions e.g.:
> >>
> >>     static inline gimple_bind as_a_gimple_bind (gimple gs)
> >>     {
> >>       return as_a <gimple_statement_bind> (gs);
> >>     }
> >>
> >> but the approach I've gone with makes these checked casts be *methods* of
> >> the gimple_statement_base class, so that e.g. in a switch statement you
> >> can write:
> >>
> >>      case GIMPLE_SWITCH:
> >>        dump_gimple_switch (buffer, gs->as_a_gimple_switch (), spc, flags);
> >>        break;
> >>
> >> where the ->as_a_gimple_switch is a no-op cast from "gimple" to the more
> >> concrete "gimple_switch" in a release build, with runtime checking for
> >> code == GIMPLE_SWITCH added in a checked build (it uses as_a <>
> >> internally).
> >>
> >> This is much less verbose than trying to do it with as_a <> directly, and
> >> I think doing it as a method reads better aloud (to my English-speaking
> >> mind, at-least):
> >>    "gs as a gimple switch",
> >> as opposed to:
> >>    "as a gimple switch... gs",
> >> which I find clunky.
> >>
> >> It makes the base class a little cluttered, but IMHO it hits a sweet-spot
> >> of readability and type-safety with relatively little verbosity (only 8
> >> more characters than doing it with a raw C-style cast).   Another
> >> advantage of having the checked cast as a *method* is that it implicitly
> >> documents the requirement that the input must be non-NULL.
> > ...FWIW I really don't like these cast members.  The counterarguments are:
> >
> > - as_a <...> (...) and dyn_cast <...> (...) follow the C++ syntax
> >    for other casts.
> >
> > - the type you get is obvious, rather than being a contraction of
> >    the type name.
> >
> > - having them as methods means that the base class needs to aware of
> >    all subclasses.  I realise that's probably inherently true of gimple
> >    due to the enum, but it seems like bad design.  You could potentially
> >    have different subclasses for the same enum, selected by a secondary field.
> I'm not particularly fond of this aspect as well...  I fear that someday 
> down the road we would regret this decision, and end up changing it all 
> back to is_a<> and friends....      These kind of sweeping changes we 
> ought to try very hard to make sure we only have to do it once.
> 
> If this is purely for verbosity, I think we can find better ways to 
> reduce it...  Is there any other reason?

There was also the idea that a method carries with it the implication
that the ptr is non-NULL... but the main reason was verbosity.

I think that with a change to is-a.h to better support typedefs, we can
achieve a relatively terse API; see:
http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01334.html

> > Maybe I've just been reading C code too long, but "as a gimple switch...gs"
> > doesn't seem any less natural than "is constant...address".
> >
> > Another way of reducing the verbosity of as_a would be to shorten the
> > type names.  E.g. "gimple_statement" contracts to "gimple_stmt" in some
> > places, so "gimple_statement_bind" could become "gimple_stmt_bind" or
> > just "gimple_bind".  "gimple_bind" is probably better since it matches
> > the names of the accessors.
> >
> > If the thing after "as_a_" matches the type name, the "X->as_a_foo ()"
> > takes the same number of characters as "as_a <foo> (X)".
> >
> 
> I was running into similar issues with the gimple re-arch work...
> 
> One thing I was going to bring up at some point was the possibility of 
> some renaming of types.    In the context of these gimple statements,  I 
> would propose that we drop the "gimple_" prefix completely, and end up 
> with maybe something more concise like
> 
> bind_stmt,
> switch_stmt,
> assign_stmt,
> etc.
> 
> There will be places in the code where we have used something like
>    gimple switch_stmt = blah();
> so those variables would have to be renamed...   and probably other 
> dribble effects...  but it would make the code look cleaner. and then  
> as_a<>, is_a<> and dyn_cast<> wouldn't look so bad.
> 
> I see the gimple part of the name as being redundant.   If we're really 
> concerned about it, put the whole thing inside a namespace, say  
> 'Gimple' and then all the gimple source files can simply start with  
> "using namespace Gimple;" and then use 'bind_stmt' throughout.  Non 
> gimple source files could then refer to it directly as 
> Gimple::bind_stmt...     This would tie in well with what I'm planning 
> to propose for gimple types and values.

That would require teaching gengtype about namespaces (rather than the
current hack), which I'd prefer to avoid.

> Of course, it would be ideal if we could use 'gimple' as the namespace, 
> but that is currently taken by the gimple statement type... I'd even go 
> so far as to propose that 'gimple' should  be renamed 'gimple::stmt'.. 
> but that is much more work :-)

I'm not at all keen on that further suggestion: I wanted to make this
patch series as minimal as possible whilst giving us the compile-time
tracking of gimple codes.  Although people's inboxes may find this
surprising, I was trying to be conservative with the patch series :) [1]

We're both working on large changes that improve the type-safety of the
middle-end: this patch series affects statements, whereas AIUI you have
a branch working on expressions and types.   How do we best co-ordinate
this so that we don't bitrot each other's work, so that the result is
reviewable, and the changes are understandable in, say, 5 years time?
My plan was to do the statement work as a (large) series of small
patches against trunk, trying to minimize the number of lines I touch,
mostly function and variable decls with a few lines adding is_a and
dyn_cast, whereas your change AIUI by necessity involves more
substantial changes to function bodies.  I think we can only have zero
or one such "touch every line" change(s) landing at once.

Dave

[1] for example, a more aggressive cleanup would be to convert the
accessors to be methods of the underlying statement classes, and make
all the data fields be private.  But the cost/benefit tradeoff doesn't
appeal: doing so would touch basically every line of code in the middle
end, and it isn't necessary to give us the compile-time checking
benefits that motivates this patch series  [potentially we could use
"friend" decls to allow the data fields to be private whilst granting
access to the existing accessors, I guess].


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