diff mbox

make has_gate and has_execute useless

Message ID 20131111161345.GA17167@tsaunders-iceball.corp.tor1.mozilla.com
State New
Headers show

Commit Message

Trevor Saunders Nov. 11, 2013, 4:13 p.m. UTC
On Mon, Nov 11, 2013 at 12:58:36PM +0100, Richard Biener wrote:
> On Mon, Nov 11, 2013 at 1:39 AM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> > On Fri, Nov 08, 2013 at 10:37:00AM +0100, Richard Biener wrote:
> >> On Thu, Nov 7, 2013 at 5:00 PM,  <tsaunders@mozilla.com> wrote:
> >> > From: Trevor Saunders <tsaunders@mozilla.com>
> >> >
> >> > Hi,
> >> >
> >> >  This is the result of seeing what it would take to get rid of the has_gate and
> >> > has_execute flags on pass_data.  It turns out not much, but I wanted
> >> > confirmation this part is ok before I go deal with all the places that
> >> > initialize the fields.
> >> >
> >> > I bootstrapped this part on x86_64-unknown-linux-gnu and saw no new test suite
> >> > regressions (ignoring the silk stuff because the full paths in its test names
> >> > break my test script for now) Any reason this patch with the actual removal of the flags wouldn't be ok?
> >>
> >> The has_gate flag is easy to remove (without a TODO_ hack), right?
> >> No gate simply means that the gate returns always true.  The only
> >> weird thing is
> >>
> >>       /* If we have a gate, combine the properties that we could have with
> >>          and without the pass being examined.  */
> >>       if (pass->has_gate)
> >>         properties &= new_properties;
> >>       else
> >>         properties = new_properties;
> >>
> >> which I don't understand (and you just removed all properties handling there).
> >>
> >> So can you split out removing has_gate?  This part is obviously ok.
> >>
> >> Then, for ->execute () I'd have refactored the code to make
> >> ->sub passes explicitely executed by the default ->execute ()
> >> implementation only.  That is, passes without overriding execute
> >> are containers only.  Can you quickly check whether that would
> >> work out?
> >
> > Ok, I've now given this a shot and wasn't terribly successful, if I just
> > change execute_pass_list and execute_ipa_pass_list to handle container
> > passes executing their sub passes I get the following ICE
> >
> > ./gt-passes.h:77:2: internal compiler error: Segmentation fault
> >  };
> >    ^
> >    0xd43d96 crash_signal
> >            /src/gcc/gcc/toplev.c:334
> >            0xd901a9 ssa_default_def(function*, tree_node*)
> >                    /src/gcc/gcc/tree-dfa.c:318
> >                    0xb56d77 ipa_analyze_params_uses
> >                            /src/gcc/gcc/ipa-prop.c:2094
> >                            0xb57275 ipa_analyze_node(cgraph_node*)
> >                                    /src/gcc/gcc/ipa-prop.c:2179
> >                                    0x13e2b6d ipcp_generate_summary
> >                                            /src/gcc/gcc/ipa-cp.c:3615
> >                                            0xc55a2a
> >                                            execute_ipa_summary_passes(ipa_opt_pass_d*)
> >                                                    /src/gcc/gcc/passes.c:1991
> >                                                    0x943341 ipa_passes
> >                                                            /src/gcc/gcc/cgraphunit.c:2011
> >                                                            0x943675
> >                                                            compile()
> >                                                                    /src/gcc/gcc/cgraphunit.c:2118
> >
> >                                                                    now
> >  Which is because fn->gimple_df is null.  I expect that's because pass
> >  ordering changed somehow, but I'm not sure off hand how or ifthat's
> >  something worth figuring out right now.
> 
> Yeah, some of the walking doesn't seem to work ... probably a
> pass with sub-passes already has an execute member function ;)

Sounds like a reasonable guess.

> >  Another issue I realized is that doing this will change the order of
> >  plugin events from
> >  start container pass a
> >  end container pass a
> >  start contained pass b
> >  end contained pass b
> >  ...
> >
> >  to
> >
> >  start container pass a
> >  start contained pass b
> >  end contained pass b
> >  end container pass a
> >
> >  Arguably that's an improvement, but I'm not sure if changing that APi
> >  like that is acceptable.
> 
> Indeed an improvement.  Can you attach your patch?

ok, done

thanks

Trev

> 
> Thanks,
> Richard.
> 
> >  Trev
> >
> >>
> >> Thanks,
> >> Richard.
> >>
> >> > Trev
> >> >
> >> > 2013-11-06  Trevor Saunders  <tsaunders@mozilla.com>
> >> >
> >> >         * pass_manager.h (pass_manager): Adjust.
> >> >         * passes.c (opt_pass::execute): Tell the pass manager it doesn't need
> >> >         to do anything for this pass.
> >> >         (pass_manager::register_dump_files_1): Don't uselessly deal with
> >> >         properties of passes.
> >> >         (pass_manager::register_dump_files): Adjust.
> >> >         (dump_one_pass): Just call pass->gate ().
> >> >         (execute_ipa_summary_passes): Likewise.
> >> >         (execute_one_pass): Don't check pass->has_execute flag.
> >> >         (ipa_write_summaries_2): Don't check pass->has_gate flag.
> >> >         (ipa_write_optimization_summaries_1): Likewise.
> >> >         (ipa_read_summaries_1): Likewise.
> >> >         (ipa_read_optimization_summaries_1): Likewise.
> >> >         (execute_ipa_stmt_fixups): Likewise.
> >> >         * tree-pass.h (pass_data): Rename has_gate to useless_has_gate and
> >> >         has_execute to useless_has_execute to be sure they're unused.
> >> >         (TODO_absolutely_nothing): New constant.
> >> >
> >> >
> >> > diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
> >> > index 77d78eb..3bc0a99 100644
> >> > --- a/gcc/pass_manager.h
> >> > +++ b/gcc/pass_manager.h
> >> > @@ -93,7 +93,7 @@ public:
> >> >
> >> >  private:
> >> >    void set_pass_for_id (int id, opt_pass *pass);
> >> > -  int register_dump_files_1 (struct opt_pass *pass, int properties);
> >> > +  void register_dump_files_1 (struct opt_pass *pass);
> >> >    void register_dump_files (struct opt_pass *pass, int properties);
> >> >
> >> >  private:
> >> > diff --git a/gcc/passes.c b/gcc/passes.c
> >> > index 19e5869..3b28dc9 100644
> >> > --- a/gcc/passes.c
> >> > +++ b/gcc/passes.c
> >> > @@ -112,7 +112,7 @@ opt_pass::gate ()
> >> >  unsigned int
> >> >  opt_pass::execute ()
> >> >  {
> >> > -  return 0;
> >> > +  return TODO_absolutely_nothing;
> >> >  }
> >> >
> >> >  opt_pass::opt_pass (const pass_data &data, context *ctxt)
> >> > @@ -701,33 +701,21 @@ pass_manager::register_one_dump_file (struct opt_pass *pass)
> >> >
> >> >  /* Recursive worker function for register_dump_files.  */
> >> >
> >> > -int
> >> > +void
> >> >  pass_manager::
> >> > -register_dump_files_1 (struct opt_pass *pass, int properties)
> >> > +register_dump_files_1 (struct opt_pass *pass)
> >> >  {
> >> >    do
> >> >      {
> >> > -      int new_properties = (properties | pass->properties_provided)
> >> > -                          & ~pass->properties_destroyed;
> >> > -
> >> >        if (pass->name && pass->name[0] != '*')
> >> >          register_one_dump_file (pass);
> >> >
> >> >        if (pass->sub)
> >> > -        new_properties = register_dump_files_1 (pass->sub, new_properties);
> >> > -
> >> > -      /* If we have a gate, combine the properties that we could have with
> >> > -         and without the pass being examined.  */
> >> > -      if (pass->has_gate)
> >> > -        properties &= new_properties;
> >> > -      else
> >> > -        properties = new_properties;
> >> > +        register_dump_files_1 (pass->sub);
> >> >
> >> >        pass = pass->next;
> >> >      }
> >> >    while (pass);
> >> > -
> >> > -  return properties;
> >> >  }
> >> >
> >> >  /* Register the dump files for the pass_manager starting at PASS.
> >> > @@ -739,7 +727,7 @@ pass_manager::
> >> >  register_dump_files (struct opt_pass *pass,int properties)
> >> >  {
> >> >    pass->properties_required |= properties;
> >> > -  register_dump_files_1 (pass, properties);
> >> > +  register_dump_files_1 (pass);
> >> >  }
> >> >
> >> >  struct pass_registry
> >> > @@ -847,7 +835,7 @@ dump_one_pass (struct opt_pass *pass, int pass_indent)
> >> >    const char *pn;
> >> >    bool is_on, is_really_on;
> >> >
> >> > -  is_on = pass->has_gate ? pass->gate () : true;
> >> > +  is_on = pass->gate ();
> >> >    is_really_on = override_gate_status (pass, current_function_decl, is_on);
> >> >
> >> >    if (pass->static_pass_number <= 0)
> >> > @@ -2002,7 +1990,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
> >> >
> >> >        /* Execute all of the IPA_PASSes in the list.  */
> >> >        if (ipa_pass->type == IPA_PASS
> >> > -         && ((!pass->has_gate) || pass->gate ())
> >> > +         && pass->gate ()
> >> >           && ipa_pass->generate_summary)
> >> >         {
> >> >           pass_init_dump_file (pass);
> >> > @@ -2153,7 +2141,7 @@ execute_one_pass (struct opt_pass *pass)
> >> >
> >> >    /* Check whether gate check should be avoided.
> >> >       User controls the value of the gate through the parameter "gate_status". */
> >> > -  gate_status = pass->has_gate ? pass->gate () : true;
> >> > +  gate_status = pass->gate ();
> >> >    gate_status = override_gate_status (pass, current_function_decl, gate_status);
> >> >
> >> >    /* Override gate with plugin.  */
> >> > @@ -2210,11 +2198,11 @@ execute_one_pass (struct opt_pass *pass)
> >> >      timevar_push (pass->tv_id);
> >> >
> >> >    /* Do it!  */
> >> > -  if (pass->has_execute)
> >> > -    {
> >> > -      todo_after = pass->execute ();
> >> > -      do_per_function (clear_last_verified, NULL);
> >> > -    }
> >> > +  todo_after = pass->execute ();
> >> > +  if (todo_after != TODO_absolutely_nothing)
> >> > +    do_per_function (clear_last_verified, NULL);
> >> > +  else
> >> > +    todo_after &= ~TODO_absolutely_nothing;
> >> >
> >> >    /* Stop timevar.  */
> >> >    if (pass->tv_id != TV_NONE)
> >> > @@ -2286,7 +2274,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >        if (pass->type == IPA_PASS
> >> >           && ipa_pass->write_summary
> >> > -         && ((!pass->has_gate) || pass->gate ()))
> >> > +         && pass->gate ())
> >> >         {
> >> >           /* If a timevar is present, start it.  */
> >> >           if (pass->tv_id)
> >> > @@ -2402,7 +2390,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, struct lto_out_decl_s
> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >        if (pass->type == IPA_PASS
> >> >           && ipa_pass->write_optimization_summary
> >> > -         && ((!pass->has_gate) || pass->gate ()))
> >> > +         && pass->gate ())
> >> >         {
> >> >           /* If a timevar is present, start it.  */
> >> >           if (pass->tv_id)
> >> > @@ -2479,7 +2467,7 @@ ipa_read_summaries_1 (struct opt_pass *pass)
> >> >        gcc_assert (!cfun);
> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >
> >> > -      if ((!pass->has_gate) || pass->gate ())
> >> > +      if (pass->gate ())
> >> >         {
> >> >           if (pass->type == IPA_PASS && ipa_pass->read_summary)
> >> >             {
> >> > @@ -2530,7 +2518,7 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
> >> >        gcc_assert (!cfun);
> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >
> >> > -      if ((!pass->has_gate) || pass->gate ())
> >> > +      if (pass->gate ())
> >> >         {
> >> >           if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
> >> >             {
> >> > @@ -2608,7 +2596,7 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
> >> >      {
> >> >        /* Execute all of the IPA_PASSes in the list.  */
> >> >        if (pass->type == IPA_PASS
> >> > -         && ((!pass->has_gate) || pass->gate ()))
> >> > +         && pass->gate ())
> >> >         {
> >> >           struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
> >> >
> >> > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> >> > index 9efee1e..bed639e 100644
> >> > --- a/gcc/tree-pass.h
> >> > +++ b/gcc/tree-pass.h
> >> > @@ -49,11 +49,11 @@ struct pass_data
> >> >
> >> >    /* If true, this pass has its own implementation of the opt_pass::gate
> >> >       method.  */
> >> > -  bool has_gate;
> >> > +  bool useless_has_gate;
> >> >
> >> >    /* If true, this pass has its own implementation of the opt_pass::execute
> >> >       method.  */
> >> > -  bool has_execute;
> >> > +  bool useless_has_execute;
> >> >
> >> >    /* The timevar id associated with this pass.  */
> >> >    /* ??? Ideally would be dynamically assigned.  */
> >> > @@ -299,6 +299,10 @@ protected:
> >> >  /* Rebuild the callgraph edges.  */
> >> >  #define TODO_rebuild_cgraph_edges       (1 << 22)
> >> >
> >> > +/* Should only be used by opt_pass::execute to tell the pass manager the pass
> >> > +   did absolutely nothing. */
> >> > +#define TODO_absolutely_nothing 1 << 23
> >> > +
> >> >  /* Internally used in execute_function_todo().  */
> >> >  #define TODO_update_ssa_any            \
> >> >      (TODO_update_ssa                   \
> >> > --
> >> > 1.8.4.2
> >> >

Comments

Richard Biener Nov. 15, 2013, 11:54 a.m. UTC | #1
On Mon, Nov 11, 2013 at 5:13 PM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> On Mon, Nov 11, 2013 at 12:58:36PM +0100, Richard Biener wrote:
>> On Mon, Nov 11, 2013 at 1:39 AM, Trevor Saunders <tsaunders@mozilla.com> wrote:
>> > On Fri, Nov 08, 2013 at 10:37:00AM +0100, Richard Biener wrote:
>> >> On Thu, Nov 7, 2013 at 5:00 PM,  <tsaunders@mozilla.com> wrote:
>> >> > From: Trevor Saunders <tsaunders@mozilla.com>
>> >> >
>> >> > Hi,
>> >> >
>> >> >  This is the result of seeing what it would take to get rid of the has_gate and
>> >> > has_execute flags on pass_data.  It turns out not much, but I wanted
>> >> > confirmation this part is ok before I go deal with all the places that
>> >> > initialize the fields.
>> >> >
>> >> > I bootstrapped this part on x86_64-unknown-linux-gnu and saw no new test suite
>> >> > regressions (ignoring the silk stuff because the full paths in its test names
>> >> > break my test script for now) Any reason this patch with the actual removal of the flags wouldn't be ok?
>> >>
>> >> The has_gate flag is easy to remove (without a TODO_ hack), right?
>> >> No gate simply means that the gate returns always true.  The only
>> >> weird thing is
>> >>
>> >>       /* If we have a gate, combine the properties that we could have with
>> >>          and without the pass being examined.  */
>> >>       if (pass->has_gate)
>> >>         properties &= new_properties;
>> >>       else
>> >>         properties = new_properties;
>> >>
>> >> which I don't understand (and you just removed all properties handling there).
>> >>
>> >> So can you split out removing has_gate?  This part is obviously ok.
>> >>
>> >> Then, for ->execute () I'd have refactored the code to make
>> >> ->sub passes explicitely executed by the default ->execute ()
>> >> implementation only.  That is, passes without overriding execute
>> >> are containers only.  Can you quickly check whether that would
>> >> work out?
>> >
>> > Ok, I've now given this a shot and wasn't terribly successful, if I just
>> > change execute_pass_list and execute_ipa_pass_list to handle container
>> > passes executing their sub passes I get the following ICE
>> >
>> > ./gt-passes.h:77:2: internal compiler error: Segmentation fault
>> >  };
>> >    ^
>> >    0xd43d96 crash_signal
>> >            /src/gcc/gcc/toplev.c:334
>> >            0xd901a9 ssa_default_def(function*, tree_node*)
>> >                    /src/gcc/gcc/tree-dfa.c:318
>> >                    0xb56d77 ipa_analyze_params_uses
>> >                            /src/gcc/gcc/ipa-prop.c:2094
>> >                            0xb57275 ipa_analyze_node(cgraph_node*)
>> >                                    /src/gcc/gcc/ipa-prop.c:2179
>> >                                    0x13e2b6d ipcp_generate_summary
>> >                                            /src/gcc/gcc/ipa-cp.c:3615
>> >                                            0xc55a2a
>> >                                            execute_ipa_summary_passes(ipa_opt_pass_d*)
>> >                                                    /src/gcc/gcc/passes.c:1991
>> >                                                    0x943341 ipa_passes
>> >                                                            /src/gcc/gcc/cgraphunit.c:2011
>> >                                                            0x943675
>> >                                                            compile()
>> >                                                                    /src/gcc/gcc/cgraphunit.c:2118
>> >
>> >                                                                    now
>> >  Which is because fn->gimple_df is null.  I expect that's because pass
>> >  ordering changed somehow, but I'm not sure off hand how or ifthat's
>> >  something worth figuring out right now.
>>
>> Yeah, some of the walking doesn't seem to work ... probably a
>> pass with sub-passes already has an execute member function ;)
>
> Sounds like a reasonable guess.
>
>> >  Another issue I realized is that doing this will change the order of
>> >  plugin events from
>> >  start container pass a
>> >  end container pass a
>> >  start contained pass b
>> >  end contained pass b
>> >  ...
>> >
>> >  to
>> >
>> >  start container pass a
>> >  start contained pass b
>> >  end contained pass b
>> >  end container pass a
>> >
>> >  Arguably that's an improvement, but I'm not sure if changing that APi
>> >  like that is acceptable.
>>
>> Indeed an improvement.  Can you attach your patch?
>
> ok, done

It's pass_early_local_passes which has sub-passes and adjusts
cgraph state in its execute.

The following works for me (not really tested of course).

Richard.

> thanks
>
> Trev
>
>>
>> Thanks,
>> Richard.
>>
>> >  Trev
>> >
>> >>
>> >> Thanks,
>> >> Richard.
>> >>
>> >> > Trev
>> >> >
>> >> > 2013-11-06  Trevor Saunders  <tsaunders@mozilla.com>
>> >> >
>> >> >         * pass_manager.h (pass_manager): Adjust.
>> >> >         * passes.c (opt_pass::execute): Tell the pass manager it doesn't need
>> >> >         to do anything for this pass.
>> >> >         (pass_manager::register_dump_files_1): Don't uselessly deal with
>> >> >         properties of passes.
>> >> >         (pass_manager::register_dump_files): Adjust.
>> >> >         (dump_one_pass): Just call pass->gate ().
>> >> >         (execute_ipa_summary_passes): Likewise.
>> >> >         (execute_one_pass): Don't check pass->has_execute flag.
>> >> >         (ipa_write_summaries_2): Don't check pass->has_gate flag.
>> >> >         (ipa_write_optimization_summaries_1): Likewise.
>> >> >         (ipa_read_summaries_1): Likewise.
>> >> >         (ipa_read_optimization_summaries_1): Likewise.
>> >> >         (execute_ipa_stmt_fixups): Likewise.
>> >> >         * tree-pass.h (pass_data): Rename has_gate to useless_has_gate and
>> >> >         has_execute to useless_has_execute to be sure they're unused.
>> >> >         (TODO_absolutely_nothing): New constant.
>> >> >
>> >> >
>> >> > diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
>> >> > index 77d78eb..3bc0a99 100644
>> >> > --- a/gcc/pass_manager.h
>> >> > +++ b/gcc/pass_manager.h
>> >> > @@ -93,7 +93,7 @@ public:
>> >> >
>> >> >  private:
>> >> >    void set_pass_for_id (int id, opt_pass *pass);
>> >> > -  int register_dump_files_1 (struct opt_pass *pass, int properties);
>> >> > +  void register_dump_files_1 (struct opt_pass *pass);
>> >> >    void register_dump_files (struct opt_pass *pass, int properties);
>> >> >
>> >> >  private:
>> >> > diff --git a/gcc/passes.c b/gcc/passes.c
>> >> > index 19e5869..3b28dc9 100644
>> >> > --- a/gcc/passes.c
>> >> > +++ b/gcc/passes.c
>> >> > @@ -112,7 +112,7 @@ opt_pass::gate ()
>> >> >  unsigned int
>> >> >  opt_pass::execute ()
>> >> >  {
>> >> > -  return 0;
>> >> > +  return TODO_absolutely_nothing;
>> >> >  }
>> >> >
>> >> >  opt_pass::opt_pass (const pass_data &data, context *ctxt)
>> >> > @@ -701,33 +701,21 @@ pass_manager::register_one_dump_file (struct opt_pass *pass)
>> >> >
>> >> >  /* Recursive worker function for register_dump_files.  */
>> >> >
>> >> > -int
>> >> > +void
>> >> >  pass_manager::
>> >> > -register_dump_files_1 (struct opt_pass *pass, int properties)
>> >> > +register_dump_files_1 (struct opt_pass *pass)
>> >> >  {
>> >> >    do
>> >> >      {
>> >> > -      int new_properties = (properties | pass->properties_provided)
>> >> > -                          & ~pass->properties_destroyed;
>> >> > -
>> >> >        if (pass->name && pass->name[0] != '*')
>> >> >          register_one_dump_file (pass);
>> >> >
>> >> >        if (pass->sub)
>> >> > -        new_properties = register_dump_files_1 (pass->sub, new_properties);
>> >> > -
>> >> > -      /* If we have a gate, combine the properties that we could have with
>> >> > -         and without the pass being examined.  */
>> >> > -      if (pass->has_gate)
>> >> > -        properties &= new_properties;
>> >> > -      else
>> >> > -        properties = new_properties;
>> >> > +        register_dump_files_1 (pass->sub);
>> >> >
>> >> >        pass = pass->next;
>> >> >      }
>> >> >    while (pass);
>> >> > -
>> >> > -  return properties;
>> >> >  }
>> >> >
>> >> >  /* Register the dump files for the pass_manager starting at PASS.
>> >> > @@ -739,7 +727,7 @@ pass_manager::
>> >> >  register_dump_files (struct opt_pass *pass,int properties)
>> >> >  {
>> >> >    pass->properties_required |= properties;
>> >> > -  register_dump_files_1 (pass, properties);
>> >> > +  register_dump_files_1 (pass);
>> >> >  }
>> >> >
>> >> >  struct pass_registry
>> >> > @@ -847,7 +835,7 @@ dump_one_pass (struct opt_pass *pass, int pass_indent)
>> >> >    const char *pn;
>> >> >    bool is_on, is_really_on;
>> >> >
>> >> > -  is_on = pass->has_gate ? pass->gate () : true;
>> >> > +  is_on = pass->gate ();
>> >> >    is_really_on = override_gate_status (pass, current_function_decl, is_on);
>> >> >
>> >> >    if (pass->static_pass_number <= 0)
>> >> > @@ -2002,7 +1990,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
>> >> >
>> >> >        /* Execute all of the IPA_PASSes in the list.  */
>> >> >        if (ipa_pass->type == IPA_PASS
>> >> > -         && ((!pass->has_gate) || pass->gate ())
>> >> > +         && pass->gate ()
>> >> >           && ipa_pass->generate_summary)
>> >> >         {
>> >> >           pass_init_dump_file (pass);
>> >> > @@ -2153,7 +2141,7 @@ execute_one_pass (struct opt_pass *pass)
>> >> >
>> >> >    /* Check whether gate check should be avoided.
>> >> >       User controls the value of the gate through the parameter "gate_status". */
>> >> > -  gate_status = pass->has_gate ? pass->gate () : true;
>> >> > +  gate_status = pass->gate ();
>> >> >    gate_status = override_gate_status (pass, current_function_decl, gate_status);
>> >> >
>> >> >    /* Override gate with plugin.  */
>> >> > @@ -2210,11 +2198,11 @@ execute_one_pass (struct opt_pass *pass)
>> >> >      timevar_push (pass->tv_id);
>> >> >
>> >> >    /* Do it!  */
>> >> > -  if (pass->has_execute)
>> >> > -    {
>> >> > -      todo_after = pass->execute ();
>> >> > -      do_per_function (clear_last_verified, NULL);
>> >> > -    }
>> >> > +  todo_after = pass->execute ();
>> >> > +  if (todo_after != TODO_absolutely_nothing)
>> >> > +    do_per_function (clear_last_verified, NULL);
>> >> > +  else
>> >> > +    todo_after &= ~TODO_absolutely_nothing;
>> >> >
>> >> >    /* Stop timevar.  */
>> >> >    if (pass->tv_id != TV_NONE)
>> >> > @@ -2286,7 +2274,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
>> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >        if (pass->type == IPA_PASS
>> >> >           && ipa_pass->write_summary
>> >> > -         && ((!pass->has_gate) || pass->gate ()))
>> >> > +         && pass->gate ())
>> >> >         {
>> >> >           /* If a timevar is present, start it.  */
>> >> >           if (pass->tv_id)
>> >> > @@ -2402,7 +2390,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, struct lto_out_decl_s
>> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >        if (pass->type == IPA_PASS
>> >> >           && ipa_pass->write_optimization_summary
>> >> > -         && ((!pass->has_gate) || pass->gate ()))
>> >> > +         && pass->gate ())
>> >> >         {
>> >> >           /* If a timevar is present, start it.  */
>> >> >           if (pass->tv_id)
>> >> > @@ -2479,7 +2467,7 @@ ipa_read_summaries_1 (struct opt_pass *pass)
>> >> >        gcc_assert (!cfun);
>> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >
>> >> > -      if ((!pass->has_gate) || pass->gate ())
>> >> > +      if (pass->gate ())
>> >> >         {
>> >> >           if (pass->type == IPA_PASS && ipa_pass->read_summary)
>> >> >             {
>> >> > @@ -2530,7 +2518,7 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
>> >> >        gcc_assert (!cfun);
>> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >
>> >> > -      if ((!pass->has_gate) || pass->gate ())
>> >> > +      if (pass->gate ())
>> >> >         {
>> >> >           if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
>> >> >             {
>> >> > @@ -2608,7 +2596,7 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
>> >> >      {
>> >> >        /* Execute all of the IPA_PASSes in the list.  */
>> >> >        if (pass->type == IPA_PASS
>> >> > -         && ((!pass->has_gate) || pass->gate ()))
>> >> > +         && pass->gate ())
>> >> >         {
>> >> >           struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
>> >> >
>> >> > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
>> >> > index 9efee1e..bed639e 100644
>> >> > --- a/gcc/tree-pass.h
>> >> > +++ b/gcc/tree-pass.h
>> >> > @@ -49,11 +49,11 @@ struct pass_data
>> >> >
>> >> >    /* If true, this pass has its own implementation of the opt_pass::gate
>> >> >       method.  */
>> >> > -  bool has_gate;
>> >> > +  bool useless_has_gate;
>> >> >
>> >> >    /* If true, this pass has its own implementation of the opt_pass::execute
>> >> >       method.  */
>> >> > -  bool has_execute;
>> >> > +  bool useless_has_execute;
>> >> >
>> >> >    /* The timevar id associated with this pass.  */
>> >> >    /* ??? Ideally would be dynamically assigned.  */
>> >> > @@ -299,6 +299,10 @@ protected:
>> >> >  /* Rebuild the callgraph edges.  */
>> >> >  #define TODO_rebuild_cgraph_edges       (1 << 22)
>> >> >
>> >> > +/* Should only be used by opt_pass::execute to tell the pass manager the pass
>> >> > +   did absolutely nothing. */
>> >> > +#define TODO_absolutely_nothing 1 << 23
>> >> > +
>> >> >  /* Internally used in execute_function_todo().  */
>> >> >  #define TODO_update_ssa_any            \
>> >> >      (TODO_update_ssa                   \
>> >> > --
>> >> > 1.8.4.2
>> >> >
Trevor Saunders Nov. 15, 2013, 12:11 p.m. UTC | #2
On Fri, Nov 15, 2013 at 12:54:05PM +0100, Richard Biener wrote:
> On Mon, Nov 11, 2013 at 5:13 PM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> > On Mon, Nov 11, 2013 at 12:58:36PM +0100, Richard Biener wrote:
> >> On Mon, Nov 11, 2013 at 1:39 AM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> >> > On Fri, Nov 08, 2013 at 10:37:00AM +0100, Richard Biener wrote:
> >> >> On Thu, Nov 7, 2013 at 5:00 PM,  <tsaunders@mozilla.com> wrote:
> >> >> > From: Trevor Saunders <tsaunders@mozilla.com>
> >> >> >
> >> >> > Hi,
> >> >> >
> >> >> >  This is the result of seeing what it would take to get rid of the has_gate and
> >> >> > has_execute flags on pass_data.  It turns out not much, but I wanted
> >> >> > confirmation this part is ok before I go deal with all the places that
> >> >> > initialize the fields.
> >> >> >
> >> >> > I bootstrapped this part on x86_64-unknown-linux-gnu and saw no new test suite
> >> >> > regressions (ignoring the silk stuff because the full paths in its test names
> >> >> > break my test script for now) Any reason this patch with the actual removal of the flags wouldn't be ok?
> >> >>
> >> >> The has_gate flag is easy to remove (without a TODO_ hack), right?
> >> >> No gate simply means that the gate returns always true.  The only
> >> >> weird thing is
> >> >>
> >> >>       /* If we have a gate, combine the properties that we could have with
> >> >>          and without the pass being examined.  */
> >> >>       if (pass->has_gate)
> >> >>         properties &= new_properties;
> >> >>       else
> >> >>         properties = new_properties;
> >> >>
> >> >> which I don't understand (and you just removed all properties handling there).
> >> >>
> >> >> So can you split out removing has_gate?  This part is obviously ok.
> >> >>
> >> >> Then, for ->execute () I'd have refactored the code to make
> >> >> ->sub passes explicitely executed by the default ->execute ()
> >> >> implementation only.  That is, passes without overriding execute
> >> >> are containers only.  Can you quickly check whether that would
> >> >> work out?
> >> >
> >> > Ok, I've now given this a shot and wasn't terribly successful, if I just
> >> > change execute_pass_list and execute_ipa_pass_list to handle container
> >> > passes executing their sub passes I get the following ICE
> >> >
> >> > ./gt-passes.h:77:2: internal compiler error: Segmentation fault
> >> >  };
> >> >    ^
> >> >    0xd43d96 crash_signal
> >> >            /src/gcc/gcc/toplev.c:334
> >> >            0xd901a9 ssa_default_def(function*, tree_node*)
> >> >                    /src/gcc/gcc/tree-dfa.c:318
> >> >                    0xb56d77 ipa_analyze_params_uses
> >> >                            /src/gcc/gcc/ipa-prop.c:2094
> >> >                            0xb57275 ipa_analyze_node(cgraph_node*)
> >> >                                    /src/gcc/gcc/ipa-prop.c:2179
> >> >                                    0x13e2b6d ipcp_generate_summary
> >> >                                            /src/gcc/gcc/ipa-cp.c:3615
> >> >                                            0xc55a2a
> >> >                                            execute_ipa_summary_passes(ipa_opt_pass_d*)
> >> >                                                    /src/gcc/gcc/passes.c:1991
> >> >                                                    0x943341 ipa_passes
> >> >                                                            /src/gcc/gcc/cgraphunit.c:2011
> >> >                                                            0x943675
> >> >                                                            compile()
> >> >                                                                    /src/gcc/gcc/cgraphunit.c:2118
> >> >
> >> >                                                                    now
> >> >  Which is because fn->gimple_df is null.  I expect that's because pass
> >> >  ordering changed somehow, but I'm not sure off hand how or ifthat's
> >> >  something worth figuring out right now.
> >>
> >> Yeah, some of the walking doesn't seem to work ... probably a
> >> pass with sub-passes already has an execute member function ;)
> >
> > Sounds like a reasonable guess.
> >
> >> >  Another issue I realized is that doing this will change the order of
> >> >  plugin events from
> >> >  start container pass a
> >> >  end container pass a
> >> >  start contained pass b
> >> >  end contained pass b
> >> >  ...
> >> >
> >> >  to
> >> >
> >> >  start container pass a
> >> >  start contained pass b
> >> >  end contained pass b
> >> >  end container pass a
> >> >
> >> >  Arguably that's an improvement, but I'm not sure if changing that APi
> >> >  like that is acceptable.
> >>
> >> Indeed an improvement.  Can you attach your patch?
> >
> > ok, done
> 
> It's pass_early_local_passes which has sub-passes and adjusts
> cgraph state in its execute.
> 
> The following works for me (not really tested of course).

ok, thanks a lot for looking, I'll test with the removal of the flags
and repost the full patch.

Trev

> 
> Richard.
> 
> > thanks
> >
> > Trev
> >
> >>
> >> Thanks,
> >> Richard.
> >>
> >> >  Trev
> >> >
> >> >>
> >> >> Thanks,
> >> >> Richard.
> >> >>
> >> >> > Trev
> >> >> >
> >> >> > 2013-11-06  Trevor Saunders  <tsaunders@mozilla.com>
> >> >> >
> >> >> >         * pass_manager.h (pass_manager): Adjust.
> >> >> >         * passes.c (opt_pass::execute): Tell the pass manager it doesn't need
> >> >> >         to do anything for this pass.
> >> >> >         (pass_manager::register_dump_files_1): Don't uselessly deal with
> >> >> >         properties of passes.
> >> >> >         (pass_manager::register_dump_files): Adjust.
> >> >> >         (dump_one_pass): Just call pass->gate ().
> >> >> >         (execute_ipa_summary_passes): Likewise.
> >> >> >         (execute_one_pass): Don't check pass->has_execute flag.
> >> >> >         (ipa_write_summaries_2): Don't check pass->has_gate flag.
> >> >> >         (ipa_write_optimization_summaries_1): Likewise.
> >> >> >         (ipa_read_summaries_1): Likewise.
> >> >> >         (ipa_read_optimization_summaries_1): Likewise.
> >> >> >         (execute_ipa_stmt_fixups): Likewise.
> >> >> >         * tree-pass.h (pass_data): Rename has_gate to useless_has_gate and
> >> >> >         has_execute to useless_has_execute to be sure they're unused.
> >> >> >         (TODO_absolutely_nothing): New constant.
> >> >> >
> >> >> >
> >> >> > diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
> >> >> > index 77d78eb..3bc0a99 100644
> >> >> > --- a/gcc/pass_manager.h
> >> >> > +++ b/gcc/pass_manager.h
> >> >> > @@ -93,7 +93,7 @@ public:
> >> >> >
> >> >> >  private:
> >> >> >    void set_pass_for_id (int id, opt_pass *pass);
> >> >> > -  int register_dump_files_1 (struct opt_pass *pass, int properties);
> >> >> > +  void register_dump_files_1 (struct opt_pass *pass);
> >> >> >    void register_dump_files (struct opt_pass *pass, int properties);
> >> >> >
> >> >> >  private:
> >> >> > diff --git a/gcc/passes.c b/gcc/passes.c
> >> >> > index 19e5869..3b28dc9 100644
> >> >> > --- a/gcc/passes.c
> >> >> > +++ b/gcc/passes.c
> >> >> > @@ -112,7 +112,7 @@ opt_pass::gate ()
> >> >> >  unsigned int
> >> >> >  opt_pass::execute ()
> >> >> >  {
> >> >> > -  return 0;
> >> >> > +  return TODO_absolutely_nothing;
> >> >> >  }
> >> >> >
> >> >> >  opt_pass::opt_pass (const pass_data &data, context *ctxt)
> >> >> > @@ -701,33 +701,21 @@ pass_manager::register_one_dump_file (struct opt_pass *pass)
> >> >> >
> >> >> >  /* Recursive worker function for register_dump_files.  */
> >> >> >
> >> >> > -int
> >> >> > +void
> >> >> >  pass_manager::
> >> >> > -register_dump_files_1 (struct opt_pass *pass, int properties)
> >> >> > +register_dump_files_1 (struct opt_pass *pass)
> >> >> >  {
> >> >> >    do
> >> >> >      {
> >> >> > -      int new_properties = (properties | pass->properties_provided)
> >> >> > -                          & ~pass->properties_destroyed;
> >> >> > -
> >> >> >        if (pass->name && pass->name[0] != '*')
> >> >> >          register_one_dump_file (pass);
> >> >> >
> >> >> >        if (pass->sub)
> >> >> > -        new_properties = register_dump_files_1 (pass->sub, new_properties);
> >> >> > -
> >> >> > -      /* If we have a gate, combine the properties that we could have with
> >> >> > -         and without the pass being examined.  */
> >> >> > -      if (pass->has_gate)
> >> >> > -        properties &= new_properties;
> >> >> > -      else
> >> >> > -        properties = new_properties;
> >> >> > +        register_dump_files_1 (pass->sub);
> >> >> >
> >> >> >        pass = pass->next;
> >> >> >      }
> >> >> >    while (pass);
> >> >> > -
> >> >> > -  return properties;
> >> >> >  }
> >> >> >
> >> >> >  /* Register the dump files for the pass_manager starting at PASS.
> >> >> > @@ -739,7 +727,7 @@ pass_manager::
> >> >> >  register_dump_files (struct opt_pass *pass,int properties)
> >> >> >  {
> >> >> >    pass->properties_required |= properties;
> >> >> > -  register_dump_files_1 (pass, properties);
> >> >> > +  register_dump_files_1 (pass);
> >> >> >  }
> >> >> >
> >> >> >  struct pass_registry
> >> >> > @@ -847,7 +835,7 @@ dump_one_pass (struct opt_pass *pass, int pass_indent)
> >> >> >    const char *pn;
> >> >> >    bool is_on, is_really_on;
> >> >> >
> >> >> > -  is_on = pass->has_gate ? pass->gate () : true;
> >> >> > +  is_on = pass->gate ();
> >> >> >    is_really_on = override_gate_status (pass, current_function_decl, is_on);
> >> >> >
> >> >> >    if (pass->static_pass_number <= 0)
> >> >> > @@ -2002,7 +1990,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
> >> >> >
> >> >> >        /* Execute all of the IPA_PASSes in the list.  */
> >> >> >        if (ipa_pass->type == IPA_PASS
> >> >> > -         && ((!pass->has_gate) || pass->gate ())
> >> >> > +         && pass->gate ()
> >> >> >           && ipa_pass->generate_summary)
> >> >> >         {
> >> >> >           pass_init_dump_file (pass);
> >> >> > @@ -2153,7 +2141,7 @@ execute_one_pass (struct opt_pass *pass)
> >> >> >
> >> >> >    /* Check whether gate check should be avoided.
> >> >> >       User controls the value of the gate through the parameter "gate_status". */
> >> >> > -  gate_status = pass->has_gate ? pass->gate () : true;
> >> >> > +  gate_status = pass->gate ();
> >> >> >    gate_status = override_gate_status (pass, current_function_decl, gate_status);
> >> >> >
> >> >> >    /* Override gate with plugin.  */
> >> >> > @@ -2210,11 +2198,11 @@ execute_one_pass (struct opt_pass *pass)
> >> >> >      timevar_push (pass->tv_id);
> >> >> >
> >> >> >    /* Do it!  */
> >> >> > -  if (pass->has_execute)
> >> >> > -    {
> >> >> > -      todo_after = pass->execute ();
> >> >> > -      do_per_function (clear_last_verified, NULL);
> >> >> > -    }
> >> >> > +  todo_after = pass->execute ();
> >> >> > +  if (todo_after != TODO_absolutely_nothing)
> >> >> > +    do_per_function (clear_last_verified, NULL);
> >> >> > +  else
> >> >> > +    todo_after &= ~TODO_absolutely_nothing;
> >> >> >
> >> >> >    /* Stop timevar.  */
> >> >> >    if (pass->tv_id != TV_NONE)
> >> >> > @@ -2286,7 +2274,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >> >        if (pass->type == IPA_PASS
> >> >> >           && ipa_pass->write_summary
> >> >> > -         && ((!pass->has_gate) || pass->gate ()))
> >> >> > +         && pass->gate ())
> >> >> >         {
> >> >> >           /* If a timevar is present, start it.  */
> >> >> >           if (pass->tv_id)
> >> >> > @@ -2402,7 +2390,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, struct lto_out_decl_s
> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >> >        if (pass->type == IPA_PASS
> >> >> >           && ipa_pass->write_optimization_summary
> >> >> > -         && ((!pass->has_gate) || pass->gate ()))
> >> >> > +         && pass->gate ())
> >> >> >         {
> >> >> >           /* If a timevar is present, start it.  */
> >> >> >           if (pass->tv_id)
> >> >> > @@ -2479,7 +2467,7 @@ ipa_read_summaries_1 (struct opt_pass *pass)
> >> >> >        gcc_assert (!cfun);
> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >> >
> >> >> > -      if ((!pass->has_gate) || pass->gate ())
> >> >> > +      if (pass->gate ())
> >> >> >         {
> >> >> >           if (pass->type == IPA_PASS && ipa_pass->read_summary)
> >> >> >             {
> >> >> > @@ -2530,7 +2518,7 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
> >> >> >        gcc_assert (!cfun);
> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
> >> >> >
> >> >> > -      if ((!pass->has_gate) || pass->gate ())
> >> >> > +      if (pass->gate ())
> >> >> >         {
> >> >> >           if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
> >> >> >             {
> >> >> > @@ -2608,7 +2596,7 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
> >> >> >      {
> >> >> >        /* Execute all of the IPA_PASSes in the list.  */
> >> >> >        if (pass->type == IPA_PASS
> >> >> > -         && ((!pass->has_gate) || pass->gate ()))
> >> >> > +         && pass->gate ())
> >> >> >         {
> >> >> >           struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
> >> >> >
> >> >> > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
> >> >> > index 9efee1e..bed639e 100644
> >> >> > --- a/gcc/tree-pass.h
> >> >> > +++ b/gcc/tree-pass.h
> >> >> > @@ -49,11 +49,11 @@ struct pass_data
> >> >> >
> >> >> >    /* If true, this pass has its own implementation of the opt_pass::gate
> >> >> >       method.  */
> >> >> > -  bool has_gate;
> >> >> > +  bool useless_has_gate;
> >> >> >
> >> >> >    /* If true, this pass has its own implementation of the opt_pass::execute
> >> >> >       method.  */
> >> >> > -  bool has_execute;
> >> >> > +  bool useless_has_execute;
> >> >> >
> >> >> >    /* The timevar id associated with this pass.  */
> >> >> >    /* ??? Ideally would be dynamically assigned.  */
> >> >> > @@ -299,6 +299,10 @@ protected:
> >> >> >  /* Rebuild the callgraph edges.  */
> >> >> >  #define TODO_rebuild_cgraph_edges       (1 << 22)
> >> >> >
> >> >> > +/* Should only be used by opt_pass::execute to tell the pass manager the pass
> >> >> > +   did absolutely nothing. */
> >> >> > +#define TODO_absolutely_nothing 1 << 23
> >> >> > +
> >> >> >  /* Internally used in execute_function_todo().  */
> >> >> >  #define TODO_update_ssa_any            \
> >> >> >      (TODO_update_ssa                   \
> >> >> > --
> >> >> > 1.8.4.2
> >> >> >
Richard Biener Nov. 15, 2013, 12:14 p.m. UTC | #3
On Fri, Nov 15, 2013 at 1:11 PM, Trevor Saunders <tsaunders@mozilla.com> wrote:
> On Fri, Nov 15, 2013 at 12:54:05PM +0100, Richard Biener wrote:
>> On Mon, Nov 11, 2013 at 5:13 PM, Trevor Saunders <tsaunders@mozilla.com> wrote:
>> > On Mon, Nov 11, 2013 at 12:58:36PM +0100, Richard Biener wrote:
>> >> On Mon, Nov 11, 2013 at 1:39 AM, Trevor Saunders <tsaunders@mozilla.com> wrote:
>> >> > On Fri, Nov 08, 2013 at 10:37:00AM +0100, Richard Biener wrote:
>> >> >> On Thu, Nov 7, 2013 at 5:00 PM,  <tsaunders@mozilla.com> wrote:
>> >> >> > From: Trevor Saunders <tsaunders@mozilla.com>
>> >> >> >
>> >> >> > Hi,
>> >> >> >
>> >> >> >  This is the result of seeing what it would take to get rid of the has_gate and
>> >> >> > has_execute flags on pass_data.  It turns out not much, but I wanted
>> >> >> > confirmation this part is ok before I go deal with all the places that
>> >> >> > initialize the fields.
>> >> >> >
>> >> >> > I bootstrapped this part on x86_64-unknown-linux-gnu and saw no new test suite
>> >> >> > regressions (ignoring the silk stuff because the full paths in its test names
>> >> >> > break my test script for now) Any reason this patch with the actual removal of the flags wouldn't be ok?
>> >> >>
>> >> >> The has_gate flag is easy to remove (without a TODO_ hack), right?
>> >> >> No gate simply means that the gate returns always true.  The only
>> >> >> weird thing is
>> >> >>
>> >> >>       /* If we have a gate, combine the properties that we could have with
>> >> >>          and without the pass being examined.  */
>> >> >>       if (pass->has_gate)
>> >> >>         properties &= new_properties;
>> >> >>       else
>> >> >>         properties = new_properties;
>> >> >>
>> >> >> which I don't understand (and you just removed all properties handling there).
>> >> >>
>> >> >> So can you split out removing has_gate?  This part is obviously ok.
>> >> >>
>> >> >> Then, for ->execute () I'd have refactored the code to make
>> >> >> ->sub passes explicitely executed by the default ->execute ()
>> >> >> implementation only.  That is, passes without overriding execute
>> >> >> are containers only.  Can you quickly check whether that would
>> >> >> work out?
>> >> >
>> >> > Ok, I've now given this a shot and wasn't terribly successful, if I just
>> >> > change execute_pass_list and execute_ipa_pass_list to handle container
>> >> > passes executing their sub passes I get the following ICE
>> >> >
>> >> > ./gt-passes.h:77:2: internal compiler error: Segmentation fault
>> >> >  };
>> >> >    ^
>> >> >    0xd43d96 crash_signal
>> >> >            /src/gcc/gcc/toplev.c:334
>> >> >            0xd901a9 ssa_default_def(function*, tree_node*)
>> >> >                    /src/gcc/gcc/tree-dfa.c:318
>> >> >                    0xb56d77 ipa_analyze_params_uses
>> >> >                            /src/gcc/gcc/ipa-prop.c:2094
>> >> >                            0xb57275 ipa_analyze_node(cgraph_node*)
>> >> >                                    /src/gcc/gcc/ipa-prop.c:2179
>> >> >                                    0x13e2b6d ipcp_generate_summary
>> >> >                                            /src/gcc/gcc/ipa-cp.c:3615
>> >> >                                            0xc55a2a
>> >> >                                            execute_ipa_summary_passes(ipa_opt_pass_d*)
>> >> >                                                    /src/gcc/gcc/passes.c:1991
>> >> >                                                    0x943341 ipa_passes
>> >> >                                                            /src/gcc/gcc/cgraphunit.c:2011
>> >> >                                                            0x943675
>> >> >                                                            compile()
>> >> >                                                                    /src/gcc/gcc/cgraphunit.c:2118
>> >> >
>> >> >                                                                    now
>> >> >  Which is because fn->gimple_df is null.  I expect that's because pass
>> >> >  ordering changed somehow, but I'm not sure off hand how or ifthat's
>> >> >  something worth figuring out right now.
>> >>
>> >> Yeah, some of the walking doesn't seem to work ... probably a
>> >> pass with sub-passes already has an execute member function ;)
>> >
>> > Sounds like a reasonable guess.
>> >
>> >> >  Another issue I realized is that doing this will change the order of
>> >> >  plugin events from
>> >> >  start container pass a
>> >> >  end container pass a
>> >> >  start contained pass b
>> >> >  end contained pass b
>> >> >  ...
>> >> >
>> >> >  to
>> >> >
>> >> >  start container pass a
>> >> >  start contained pass b
>> >> >  end contained pass b
>> >> >  end container pass a
>> >> >
>> >> >  Arguably that's an improvement, but I'm not sure if changing that APi
>> >> >  like that is acceptable.
>> >>
>> >> Indeed an improvement.  Can you attach your patch?
>> >
>> > ok, done
>>
>> It's pass_early_local_passes which has sub-passes and adjusts
>> cgraph state in its execute.
>>
>> The following works for me (not really tested of course).
>
> ok, thanks a lot for looking, I'll test with the removal of the flags
> and repost the full patch.

There seem to be similar issues elsewhere (from just running
tree-ssa.exp).

Richard.

> Trev
>
>>
>> Richard.
>>
>> > thanks
>> >
>> > Trev
>> >
>> >>
>> >> Thanks,
>> >> Richard.
>> >>
>> >> >  Trev
>> >> >
>> >> >>
>> >> >> Thanks,
>> >> >> Richard.
>> >> >>
>> >> >> > Trev
>> >> >> >
>> >> >> > 2013-11-06  Trevor Saunders  <tsaunders@mozilla.com>
>> >> >> >
>> >> >> >         * pass_manager.h (pass_manager): Adjust.
>> >> >> >         * passes.c (opt_pass::execute): Tell the pass manager it doesn't need
>> >> >> >         to do anything for this pass.
>> >> >> >         (pass_manager::register_dump_files_1): Don't uselessly deal with
>> >> >> >         properties of passes.
>> >> >> >         (pass_manager::register_dump_files): Adjust.
>> >> >> >         (dump_one_pass): Just call pass->gate ().
>> >> >> >         (execute_ipa_summary_passes): Likewise.
>> >> >> >         (execute_one_pass): Don't check pass->has_execute flag.
>> >> >> >         (ipa_write_summaries_2): Don't check pass->has_gate flag.
>> >> >> >         (ipa_write_optimization_summaries_1): Likewise.
>> >> >> >         (ipa_read_summaries_1): Likewise.
>> >> >> >         (ipa_read_optimization_summaries_1): Likewise.
>> >> >> >         (execute_ipa_stmt_fixups): Likewise.
>> >> >> >         * tree-pass.h (pass_data): Rename has_gate to useless_has_gate and
>> >> >> >         has_execute to useless_has_execute to be sure they're unused.
>> >> >> >         (TODO_absolutely_nothing): New constant.
>> >> >> >
>> >> >> >
>> >> >> > diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
>> >> >> > index 77d78eb..3bc0a99 100644
>> >> >> > --- a/gcc/pass_manager.h
>> >> >> > +++ b/gcc/pass_manager.h
>> >> >> > @@ -93,7 +93,7 @@ public:
>> >> >> >
>> >> >> >  private:
>> >> >> >    void set_pass_for_id (int id, opt_pass *pass);
>> >> >> > -  int register_dump_files_1 (struct opt_pass *pass, int properties);
>> >> >> > +  void register_dump_files_1 (struct opt_pass *pass);
>> >> >> >    void register_dump_files (struct opt_pass *pass, int properties);
>> >> >> >
>> >> >> >  private:
>> >> >> > diff --git a/gcc/passes.c b/gcc/passes.c
>> >> >> > index 19e5869..3b28dc9 100644
>> >> >> > --- a/gcc/passes.c
>> >> >> > +++ b/gcc/passes.c
>> >> >> > @@ -112,7 +112,7 @@ opt_pass::gate ()
>> >> >> >  unsigned int
>> >> >> >  opt_pass::execute ()
>> >> >> >  {
>> >> >> > -  return 0;
>> >> >> > +  return TODO_absolutely_nothing;
>> >> >> >  }
>> >> >> >
>> >> >> >  opt_pass::opt_pass (const pass_data &data, context *ctxt)
>> >> >> > @@ -701,33 +701,21 @@ pass_manager::register_one_dump_file (struct opt_pass *pass)
>> >> >> >
>> >> >> >  /* Recursive worker function for register_dump_files.  */
>> >> >> >
>> >> >> > -int
>> >> >> > +void
>> >> >> >  pass_manager::
>> >> >> > -register_dump_files_1 (struct opt_pass *pass, int properties)
>> >> >> > +register_dump_files_1 (struct opt_pass *pass)
>> >> >> >  {
>> >> >> >    do
>> >> >> >      {
>> >> >> > -      int new_properties = (properties | pass->properties_provided)
>> >> >> > -                          & ~pass->properties_destroyed;
>> >> >> > -
>> >> >> >        if (pass->name && pass->name[0] != '*')
>> >> >> >          register_one_dump_file (pass);
>> >> >> >
>> >> >> >        if (pass->sub)
>> >> >> > -        new_properties = register_dump_files_1 (pass->sub, new_properties);
>> >> >> > -
>> >> >> > -      /* If we have a gate, combine the properties that we could have with
>> >> >> > -         and without the pass being examined.  */
>> >> >> > -      if (pass->has_gate)
>> >> >> > -        properties &= new_properties;
>> >> >> > -      else
>> >> >> > -        properties = new_properties;
>> >> >> > +        register_dump_files_1 (pass->sub);
>> >> >> >
>> >> >> >        pass = pass->next;
>> >> >> >      }
>> >> >> >    while (pass);
>> >> >> > -
>> >> >> > -  return properties;
>> >> >> >  }
>> >> >> >
>> >> >> >  /* Register the dump files for the pass_manager starting at PASS.
>> >> >> > @@ -739,7 +727,7 @@ pass_manager::
>> >> >> >  register_dump_files (struct opt_pass *pass,int properties)
>> >> >> >  {
>> >> >> >    pass->properties_required |= properties;
>> >> >> > -  register_dump_files_1 (pass, properties);
>> >> >> > +  register_dump_files_1 (pass);
>> >> >> >  }
>> >> >> >
>> >> >> >  struct pass_registry
>> >> >> > @@ -847,7 +835,7 @@ dump_one_pass (struct opt_pass *pass, int pass_indent)
>> >> >> >    const char *pn;
>> >> >> >    bool is_on, is_really_on;
>> >> >> >
>> >> >> > -  is_on = pass->has_gate ? pass->gate () : true;
>> >> >> > +  is_on = pass->gate ();
>> >> >> >    is_really_on = override_gate_status (pass, current_function_decl, is_on);
>> >> >> >
>> >> >> >    if (pass->static_pass_number <= 0)
>> >> >> > @@ -2002,7 +1990,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
>> >> >> >
>> >> >> >        /* Execute all of the IPA_PASSes in the list.  */
>> >> >> >        if (ipa_pass->type == IPA_PASS
>> >> >> > -         && ((!pass->has_gate) || pass->gate ())
>> >> >> > +         && pass->gate ()
>> >> >> >           && ipa_pass->generate_summary)
>> >> >> >         {
>> >> >> >           pass_init_dump_file (pass);
>> >> >> > @@ -2153,7 +2141,7 @@ execute_one_pass (struct opt_pass *pass)
>> >> >> >
>> >> >> >    /* Check whether gate check should be avoided.
>> >> >> >       User controls the value of the gate through the parameter "gate_status". */
>> >> >> > -  gate_status = pass->has_gate ? pass->gate () : true;
>> >> >> > +  gate_status = pass->gate ();
>> >> >> >    gate_status = override_gate_status (pass, current_function_decl, gate_status);
>> >> >> >
>> >> >> >    /* Override gate with plugin.  */
>> >> >> > @@ -2210,11 +2198,11 @@ execute_one_pass (struct opt_pass *pass)
>> >> >> >      timevar_push (pass->tv_id);
>> >> >> >
>> >> >> >    /* Do it!  */
>> >> >> > -  if (pass->has_execute)
>> >> >> > -    {
>> >> >> > -      todo_after = pass->execute ();
>> >> >> > -      do_per_function (clear_last_verified, NULL);
>> >> >> > -    }
>> >> >> > +  todo_after = pass->execute ();
>> >> >> > +  if (todo_after != TODO_absolutely_nothing)
>> >> >> > +    do_per_function (clear_last_verified, NULL);
>> >> >> > +  else
>> >> >> > +    todo_after &= ~TODO_absolutely_nothing;
>> >> >> >
>> >> >> >    /* Stop timevar.  */
>> >> >> >    if (pass->tv_id != TV_NONE)
>> >> >> > @@ -2286,7 +2274,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
>> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >> >        if (pass->type == IPA_PASS
>> >> >> >           && ipa_pass->write_summary
>> >> >> > -         && ((!pass->has_gate) || pass->gate ()))
>> >> >> > +         && pass->gate ())
>> >> >> >         {
>> >> >> >           /* If a timevar is present, start it.  */
>> >> >> >           if (pass->tv_id)
>> >> >> > @@ -2402,7 +2390,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, struct lto_out_decl_s
>> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >> >        if (pass->type == IPA_PASS
>> >> >> >           && ipa_pass->write_optimization_summary
>> >> >> > -         && ((!pass->has_gate) || pass->gate ()))
>> >> >> > +         && pass->gate ())
>> >> >> >         {
>> >> >> >           /* If a timevar is present, start it.  */
>> >> >> >           if (pass->tv_id)
>> >> >> > @@ -2479,7 +2467,7 @@ ipa_read_summaries_1 (struct opt_pass *pass)
>> >> >> >        gcc_assert (!cfun);
>> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >> >
>> >> >> > -      if ((!pass->has_gate) || pass->gate ())
>> >> >> > +      if (pass->gate ())
>> >> >> >         {
>> >> >> >           if (pass->type == IPA_PASS && ipa_pass->read_summary)
>> >> >> >             {
>> >> >> > @@ -2530,7 +2518,7 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
>> >> >> >        gcc_assert (!cfun);
>> >> >> >        gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>> >> >> >
>> >> >> > -      if ((!pass->has_gate) || pass->gate ())
>> >> >> > +      if (pass->gate ())
>> >> >> >         {
>> >> >> >           if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
>> >> >> >             {
>> >> >> > @@ -2608,7 +2596,7 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
>> >> >> >      {
>> >> >> >        /* Execute all of the IPA_PASSes in the list.  */
>> >> >> >        if (pass->type == IPA_PASS
>> >> >> > -         && ((!pass->has_gate) || pass->gate ()))
>> >> >> > +         && pass->gate ())
>> >> >> >         {
>> >> >> >           struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
>> >> >> >
>> >> >> > diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
>> >> >> > index 9efee1e..bed639e 100644
>> >> >> > --- a/gcc/tree-pass.h
>> >> >> > +++ b/gcc/tree-pass.h
>> >> >> > @@ -49,11 +49,11 @@ struct pass_data
>> >> >> >
>> >> >> >    /* If true, this pass has its own implementation of the opt_pass::gate
>> >> >> >       method.  */
>> >> >> > -  bool has_gate;
>> >> >> > +  bool useless_has_gate;
>> >> >> >
>> >> >> >    /* If true, this pass has its own implementation of the opt_pass::execute
>> >> >> >       method.  */
>> >> >> > -  bool has_execute;
>> >> >> > +  bool useless_has_execute;
>> >> >> >
>> >> >> >    /* The timevar id associated with this pass.  */
>> >> >> >    /* ??? Ideally would be dynamically assigned.  */
>> >> >> > @@ -299,6 +299,10 @@ protected:
>> >> >> >  /* Rebuild the callgraph edges.  */
>> >> >> >  #define TODO_rebuild_cgraph_edges       (1 << 22)
>> >> >> >
>> >> >> > +/* Should only be used by opt_pass::execute to tell the pass manager the pass
>> >> >> > +   did absolutely nothing. */
>> >> >> > +#define TODO_absolutely_nothing 1 << 23
>> >> >> > +
>> >> >> >  /* Internally used in execute_function_todo().  */
>> >> >> >  #define TODO_update_ssa_any            \
>> >> >> >      (TODO_update_ssa                   \
>> >> >> > --
>> >> >> > 1.8.4.2
>> >> >> >
>
>
diff mbox

Patch

diff --git a/gcc/passes.c b/gcc/passes.c
index c008a7b..038bca7 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -112,6 +112,9 @@  opt_pass::gate ()
 unsigned int
 opt_pass::execute ()
 {
+  if (sub)
+    execute_pass_list (sub);
+
   return TODO_absolutely_nothing;
 }
 
@@ -2240,8 +2243,7 @@  execute_pass_list (struct opt_pass *pass)
     {
       gcc_assert (pass->type == GIMPLE_PASS
 		  || pass->type == RTL_PASS);
-      if (execute_one_pass (pass) && pass->sub)
-        execute_pass_list (pass->sub);
+      execute_one_pass (pass);
       pass = pass->next;
     }
   while (pass);
@@ -2552,21 +2554,7 @@  execute_ipa_pass_list (struct opt_pass *pass)
       gcc_assert (!current_function_decl);
       gcc_assert (!cfun);
       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
-      if (execute_one_pass (pass) && pass->sub)
-	{
-	  if (pass->sub->type == GIMPLE_PASS)
-	    {
-	      invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
-	      do_per_function_toporder ((void (*)(void *))execute_pass_list,
-					pass->sub);
-	      invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
-	    }
-	  else if (pass->sub->type == SIMPLE_IPA_PASS
-		   || pass->sub->type == IPA_PASS)
-	    execute_ipa_pass_list (pass->sub);
-	  else
-	    gcc_unreachable ();
-	}
+      execute_one_pass (pass);
       gcc_assert (!current_function_decl);
       cgraph_process_new_functions ();
       pass = pass->next;