This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Examples of gimple statement API (was Re: [PATCH 03/89] Introduce gimple_bind and use it for accessors.)
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: David Malcolm <dmalcolm at redhat dot com>
- Cc: Andrew MacLeod <amacleod at redhat dot com>, Jeff Law <law at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 25 Apr 2014 10:37:06 +0200
- Subject: Re: Examples of gimple statement API (was Re: [PATCH 03/89] Introduce gimple_bind and use it for accessors.)
- Authentication-results: sourceware.org; auth=none
- References: <1398099480-49147-1-git-send-email-dmalcolm at redhat dot com> <1398099480-49147-4-git-send-email-dmalcolm at redhat dot com> <53582AF1 dot 7010201 at redhat dot com> <1398287639 dot 26834 dot 142 dot camel at surprise> <53582F37 dot 1040202 at redhat dot com> <CAFiYyc2fTC4ysPkODyAOA3obrc6MifL87vfjY=vfB=JvaVC_Zw at mail dot gmail dot com> <53590CF1 dot 2090504 at redhat dot com> <1398351547 dot 26834 dot 171 dot camel at surprise>
On Thu, Apr 24, 2014 at 4:59 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Thu, 2014-04-24 at 09:09 -0400, Andrew MacLeod wrote:
>> On 04/24/2014 04:33 AM, Richard Biener wrote:
>> > On Wed, Apr 23, 2014 at 11:23 PM, Jeff Law <law@redhat.com> wrote:
>> >> On 04/23/14 15:13, David Malcolm wrote:
>> >>> On Wed, 2014-04-23 at 15:04 -0600, Jeff Law wrote:
>> >>>> On 04/21/14 10:56, David Malcolm wrote:
>> >>>>> This updates all of the gimple_bind_* accessors in gimple.h from taking
>> >>>>> a
>> >>>>> plain gimple to taking a gimple_bind (or const_gimple_bind), with the
>> >>>>> checking happening at the point of cast.
>> >>>>>
>> >>>>> Various other types are strengthened from gimple to gimple_bind, and
>> >>>>> from
>> >>>>> plain vec<gimple> to vec<gimple_bind>.
>> >>>
>> >>> [...]
>> >>>
>> >>>> This is fine, with the same requested changes as #2; specifically using
>> >>>> an explicit cast rather than hiding the conversion in a method. Once
>> >>>> those changes are in place, it's good for 4.9.1.
>> >>> Thanks - presumably you mean
>> >>> "good for *trunk* after 4.9.1 is released"
>> >> Right. Sorry for the confusion.
>> > Note I still want that less-typedefs (esp. the const_*) variants to be explored.
>> > Changing this will touch all the code again, so I'd like to avoid that.
>> >
>> > That is, shouldn't we go back to 'gimple' being 'gimple_statement_base'
>> > and not 'gimple_statement_base *'? The main reason that we have so
>> > many typedefs is that in C you had to use 'struct foo' each time you
>> > refer to foo as a type - I suppose it was then convenient to do the
>> > typedef to the pointer type. With 'gimple' being not a pointer type
>> > we get const correctness in the way people would expect it to work.
>> > [no, I don't suggest you change 'tree' or 'const_tree' at this point, just
>> > gimple (and maybe gimple_seq) as you are working on the 'gimple'
>> > type anyway].
>> >
>> >
>>
>> So if we change 'gimple' everywhere to be 'gimple *', can we just
>> abandon the 'gimple' typedef completely and go directly to using
>> something like gimple_stmt, or some other agreeable name instead?
>>
>> I think its more descriptive and then frees up the generic 'gimple' name
>> should we decide to do something more with namespaces in the future...
>
> There have been a few different proposals as to what the resulting
> gimple API might look like, in various subthreads of this discusssion,
> so I thought it might help the discussion to gather up the proposals,
> and to apply them to some specific code examples, to see what the
> results might look like.
>
> So here are a couple of code fragments, from gcc/graphite-sese-to-poly.c
> and gcc/tree-ssa-uninit.c respectively:
>
> Status quo
> ==========
>
> static gimple
> detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> vec<gimple> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> gimple def, loop_phi, phi, close_phi = stmt;
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> gimple_stmt_iterator gsi;
> vec<gimple> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> The currently-posted patch series
> =================================
> Here's the cumulative effect of the patch series I posted, using the
> casting methods of the base class (the "stmt->as_a_gimple_phi" call):
>
> -static gimple
> +static gimple_phi
> detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> vec<gimple> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> + gimple def;
> + gimple_phi loop_phi, phi, close_phi = stmt->as_a_gimple_phi ();
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + gimple_phi_iterator gsi;
> + vec<gimple_phi> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> Direct use of is-a.h, retaining typedefs of pointers
> ====================================================
> The following patch shows what the above might look like using the patch
> series as posted, but eliminating the casting methods in favor of
> direct use of the is-a.h API (but still using lots of typedefs of
> pointers):
>
> -static gimple
> +static gimple_phi
> detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> vec<gimple> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> + gimple def;
> + gimple_phi loop_phi, phi, close_phi = as_a <gimple_phi> (stmt);
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + gimple_phi_iterator gsi;
> + vec<gimple_phi> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> I posted an example of porting a patch in the series to this approach as:
> http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01549.html
>
> Explicit pointers, rather than typedefs
> =======================================
> Richi suggested making pointers be explicit rather than hidden in the
> typedefs in:
> http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01520.html
> which might give something like this:
>
> -static gimple
> -detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> - vec<gimple> *out)
> +static gimple_phi *
> +detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple *> *in,
> + vec<gimple *> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> + gimple *def;
> + gimple_phi *loop_phi, *phi, *close_phi = as_a <gimple_phi *> (stmt);
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + gimple_phi_iterator gsi;
> + vec<gimple_phi *> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> Changing the meaning of "gimple" makes this a much bigger patch IMHO
> than what I've currently posted. One way to achieve this could be a
> mega-patch (ugh) which ports the whole middle-end at once to change the
> "pointerness" of "gimple", probably auto-generated and, once that's in
> place, then look at introducing subclass usage.
>
> Note: it's more fiddly than a simply sed of "gimple" to "gimple *" (or
> whatever); consider the gimple_phi decls above, which would change
> thusly:
> - gimple def, loop_phi, phi, close_phi = stmt;
> + gimple *def, *loop_phi, *phi, *close_phi = stmt;
>
> Implicit naming
> ===============
> Several people have suggested that the "gimple_" prefix is redundant.
>
> Andrew MacLeod suggested in:
> http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01297.html
> that we could simple drop the "gimple_" prefix. Combining this with the
> pointer approach, for example, gives:
>
> -static gimple
> -detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> - vec<gimple> *out)
> +static phi *
> +detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple *> *in,
> + vec<gimple *> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> + gimple *def;
> + phi *loop_phi, *phi, *close_phi = as_a <phi *> (stmt);
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + phi_iterator gsi;
> + vec<phi *> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> though it could also be done with typedefs of pointers, rather than the
> "explicit pointers" above.
>
>
> Namespaces (explicit)
> =====================
> Continuing with the idea that the "gimple_" prefix is redundant, Andrew
> MacLeod also suggested in:
> http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01297.html
> that we could repurpose "gimple" to be a namespace. Here's what things
> might look like written out in full (perhaps using gimple::stmt to be
> the base class):
>
> -static gimple
> -detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> - vec<gimple> *out)
> +static gimple::phi *
> +detect_commutative_reduction (scop_p scop, gimple::stmt *stmt,
> + vec<gimple::stmt *> *in,
> + vec<gimple::stmt *> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> + gimple::stmt *def;
> + gimple::phi loop_phi, phi, close_phi = as_a <gimple::phi *> (stmt);
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + gimple::phi_iterator gsi;
> + vec<gimple::phi *> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> This may require some gengtype support, for the case of fields within
> structs.
>
> Andrew suggested renaming "gimple" to "gimple_stmt" in:
> http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01297.html
> as a possible migration path towards this.
>
> Namespaces (implicit)
> =====================
> The above is, of course, verbose - I'm mostly posting it to clarify the
> following, which uses a "using" decl to eliminate all of the "gimple::"
> from the above:
>
> using gimple;
>
> -static gimple
> -detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> - vec<gimple> *out)
> +static phi *
> +detect_commutative_reduction (scop_p scop, stmt *stmt,
> + vec<stmt *> *in,
> + vec<stmt *> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> + stmt *def;
> + phi *loop_phi, phi, close_phi = as_a <phi *> (stmt);
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + phi_iterator gsi;
> + vec<phi *> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> This would require some gengtype support (again, for the case of fields
> within structs).
>
> C++ references (without namespaces)
> ===================================
> Richi suggested the use of references rather than pointers when the
> address is required to be non-NULL:
> http://gcc.gnu.org/ml/gcc-patches/2014-04/msg01427.html
> though there's been some pushback on C++ references in the past e.g.
> from Jeff:
> http://gcc.gnu.org/ml/gcc-patches/2013-07/msg01430.html
>
> Here's what the "Explicit pointers, rather than typedefs" might look
> like, but with references rather than ptrs for some vars where NULL
> isn't valid:
>
> -static gimple
> -detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> - vec<gimple> *out)
> +static gimple_phi *
> +detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple &> *in,
> + vec<gimple &> *out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> + gimple *def;
> + gimple_phi *loop_phi, *phi, *close_phi = as_a <gimple_phi *> (stmt);
> tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + gimple_phi_iterator gsi;
> + vec<gimple_phi &> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
> ...though arguably there's plenty more conversion of the above that
> could be done: "def" is initialized once, with a non-NULL ptr, so
> arguably could be reference, but that would require moving the decl down
> to the point of initialization so I didn't touch it above. I think use
> of references would tend to break up such declarations of locals.
>
> C++ references (with implicit namespaces)
> =========================================
> ...and here's what the above "namespaces with a using decl" approach
> might look like with references:
>
> using gimple;
>
> -static gimple
> -detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
> - vec<gimple> *out)
> +static phi *
> +detect_commutative_reduction (scop_p scop, stmt &stmt,
> + vec<stmt &> &in,
> + vec<stmt &> &out)
> {
> if (scalar_close_phi_node_p (stmt))
> {
> - gimple def, loop_phi, phi, close_phi = stmt;
> - tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
> - tree init, lhs, arg = gimple_phi_arg_def (*close_phi, 0);
> + stmt *def;
> + phi *loop_phi, phi, close_phi = as_a <phi *> (stmt);
> + tree init, lhs, arg = gimple_phi_arg_def (*close_phi, 0);
>
> if (TREE_CODE (arg) != SSA_NAME)
>
> /* ...etc... */
>
> static unsigned int
> execute_late_warn_uninitialized (void)
> {
> basic_block bb;
> - gimple_stmt_iterator gsi;
> - vec<gimple> worklist = vNULL;
> + phi_iterator gsi;
> + vec<phi *> worklist = vNULL;
> pointer_set_t *added_to_worklist;
>
>
> So the above hopefully gives an idea of what a more compile-time
> type-safe gimple API might look like; sorry if I've mischaracterized any
> of the ideas. I believe they're roughly sorted by increasing
> invasiveness, and by increasing "C++ ness" (both of which give me
> pause).
>
> Thoughts?
The 'should gimple be a pointer typedef' issue is rather orthogonal
and it merely affects how we do const-correctness
(but it affects your ongoing work, thus I brought it up - also because
you address the const correctness issue).
It's convenient to do such change first IMHO. And I never liked the
const_ typedef variants that were introduced. The main reason for
them was probably to avoid all the churn of replacing the tree pointer
typedef with a tree (non-pointer) typedef. The mistake was to
repeat that for 'gimple' ...
I have no strong opinion on const correctness in general, but I do
have a strong opinion against introducing more of the const_*
typedefs. Those simply feel completely bogus (and alienate the new
GCC developers we want to attract with C++ and all these changes (uh? heh!?)).
So if you turn gimple up-side-down (which you do with more static
type checking) then please fix const correctness first.
As of namespaces - yes, ideally we'd move the various prefixes
to namespaces (that a gimple pass can simply use for example).
But that's again an orthogonal issue. You could always add the
namespace with your work and add typedefs like
typedef gimple::phi gimple_phi;
(though that invites inconsistent coding-style, using gimple::phi
vs. gimple_phi throughout the code)
Richard.
> FWIW, my own preference is for "Direct use of is-a.h, retaining typedefs
> of pointers" but that may be because it would be less work for me ;)
>
> Andrew: I know you've been working on improving the typesafety of
> expressions vs types in the middle-end. I'm curious as to what the
> above code fragments look like with just your changes?
>
> Hope this is useful.
> Dave
>
>