public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Fix PR41573, remove pass_remove_useless_stmts
@ 2009-10-10 10:49 Uros Bizjak
  2009-10-11 17:58 ` Michael Matz
  0 siblings, 1 reply; 13+ messages in thread
From: Uros Bizjak @ 2009-10-10 10:49 UTC (permalink / raw)
  To: GCC Patches; +Cc: Michael Matz, Olatunji Ruwase

Hello!

> 	PR middle-end/41573
> 	* builtins.c (fold_builtin_isascii): Use fold_build2.
> 	(fold_builtin_isdigit): Ditto.
> 	* except.c (duplicate_eh_regions_1): Tolerate NULL labels.
> 	* tree-cfg.c (struct rus_data, remove_useless_stmts_warn_notreached,
> 	remove_useless_stmts_cond, remove_useless_stmts_tf,
> 	remove_useless_stmts_tc, remove_useless_stmts_bind,
> 	remove_useless_stmts_goto, remove_useless_stmts_label,
> 	remove_useless_stmts_1, remove_useless_stmts,
> 	pass_remove_useless_stmts): Remove.
> 	* tree-pass.h (pass_remove_useless_stmts): Don't declare.
> 	* passes.c (init_optimization_passes): Don't add
> 	pass_remove_useless_stmts.
> 	* tree-eh.c (lower_eh_constructs_2): Handle empty cleanups.
> 	* tree.c (free_lang_data_in_decl): Don't clear DECL_INITIAL of
> 	static constants.
> 	* lto-symtab.c (lto_symtab_merge_decl): Accepts DECL_INITIAL
> 	for static constants.
> 	* lto-streamer-out.c (output_gimple_stmt): Handle GIMPLE_NOP.
> 	* lto-streamer-in.c (input_gimple_stmt): Handle GIMPLE_NOP.
>
> testsuite/
> 	* gcc.dg/tree-ssa/foldstring-1.c: Use fre dump.
> 	* gcc.dg/tree-ssa/useless-1.c: Use gimple dump.
> 	* gcc.dg/pr41573.c: New test.
>    


This patch introduced following testsuite failures [1]:

FAIL: gcc.dg/plugin/one_time-test-1.c -fplugin=./one_time_plugin.so (internal compiler error)
FAIL: gcc.dg/plugin/one_time-test-1.c -fplugin=./one_time_plugin.so (test for excess errors)


Regstrapped on x86_64-linux, no regressions, all languages+Ada.  Okay for
trunk?

Hm...


The problem is, that the plugin wants to plug itself after now removed 
"useless" pass, so the test needs to be updated (author CC'd).

IMO, gcc should exit with some kind of descriptive error instead of 
abort with ICE:

cc1: internal compiler error: in register_pass, at passes.c:620
...

which happens to be triggered at:

   /* Try to insert the new pass to the pass lists. We need to check all
      three lists as the reference pass could be in one (or all) of 
them.  */
   if (!position_pass (pass_info, &all_lowering_passes)
&& !position_pass (pass_info, &all_small_ipa_passes)
&& !position_pass (pass_info, &all_regular_ipa_passes)
&& !position_pass (pass_info, &all_lto_gen_passes)
&& !position_pass (pass_info, &all_passes))
     gcc_unreachable ();
   else
     ...

[1] http://gcc.gnu.org/ml/gcc-testresults/2009-10/msg00837.html

Uros.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-10 10:49 Fix PR41573, remove pass_remove_useless_stmts Uros Bizjak
@ 2009-10-11 17:58 ` Michael Matz
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Matz @ 2009-10-11 17:58 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: GCC Patches, Olatunji Ruwase

Hi,

On Sat, 10 Oct 2009, Uros Bizjak wrote:

> This patch introduced following testsuite failures [1]:
> 
> FAIL: gcc.dg/plugin/one_time-test-1.c -fplugin=./one_time_plugin.so (internal
> FAIL: compiler error)
> FAIL: gcc.dg/plugin/one_time-test-1.c -fplugin=./one_time_plugin.so (test for
> FAIL: excess errors)
> 
> Regstrapped on x86_64-linux, no regressions, all languages+Ada.  Okay for
> trunk?

Sorry for this, I misread/-remembered the results of the unpatched 
compiler which had:

UNRESOLVED: one_time_plugin.c compilation, ... blabla ...

vs. the above FAIL.  It was just "one_time_plugin.c had an issue before 
too" in my mind :)

> The problem is, that the plugin wants to plug itself after now removed
> "useless" pass, so the test needs to be updated (author CC'd).

I'd suggest to use the "cfg" name, which is unlikely to go away soon 
(pass_build_cfg).  In fact the below patch solves the problem, I'm going 
to check it in as obvious tomorrow if nobody stops me.


Ciao,
Michael.
-- 
	* gcc.dg/plugin/one_time_plugin.c: Update test to use the cfg 
	pass.

Index: testsuite/gcc.dg/plugin/one_time_plugin.c
===================================================================
--- testsuite/gcc.dg/plugin/one_time_plugin.c   (Revision 152643)
+++ testsuite/gcc.dg/plugin/one_time_plugin.c   (Arbeitskopie)
@@ -31,7 +31,7 @@ struct gimple_opt_pass one_pass =
 {
   {
   GIMPLE_PASS,
-  "useless",                           /* name */
+  "cfg",                           /* name */
   one_pass_gate,                         /* gate */
   one_pass_exec,       /* execute */
   NULL,                                 /* sub */
@@ -53,7 +53,7 @@ int plugin_init (struct plugin_name_args
   struct register_pass_info p;

   p.pass = &one_pass.pass;
-  p.reference_pass_name = "useless";
+  p.reference_pass_name = "cfg";
   p.ref_pass_instance_number = 1;
   p.pos_op = PASS_POS_INSERT_AFTER;

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 13:09 Michael Matz
  2009-10-07 13:24 ` Richard Guenther
  2009-10-07 13:34 ` Eric Botcazou
@ 2010-01-13  3:20 ` H.J. Lu
  2 siblings, 0 replies; 13+ messages in thread
From: H.J. Lu @ 2010-01-13  3:20 UTC (permalink / raw)
  To: Michael Matz; +Cc: gcc-patches

On Wed, Oct 7, 2009 at 4:29 AM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> remove_useless_stmts folds statements at a time where not the whole
> optimization engine is initialized yet, which causes the segfault of the
> above bugreport.  Now, instead of just fixing the symptom I thought maybe
> we can get rid of the whole pass instead.  Digging around it seems to have
> been rotting away for some years already, while occasionally making it
> remove less stmts or fixing other bugs, somewhen being split into
> cfg_remove_useless_stmts, which shortly after was removed again.  It
> survived tuplification living its meagre life on and on.
>
> To determine its meagreness I added some statistics code to see what it
> actually still removes and measured a whole bootstrap cycle with testsuite
> (all languages+Ada), and this is the result:
>
> number of compiler invocations: 70332
> overall number of repeats:     214136
>  (When something is changed by r_u_s it repeats the scan of all insns
>  again)
> overall insns visited:   1025945788
>  of those changed at all:   1111266 (a whopping promille)
> nr of conditional insns:    4136111
>  of those trivial true:       84084
>         trivial false:      152987
>        same destination:         8 (wow)
> nr unconditional gotos:   244390760
>  of those fallthru:          478812
> nr of GIMPLE_BIND:          2268987
>  of those removed:           304083
> nr of TRY_FINALLY:           201032
>  of those empty eval:         17130
>          empty cleanup:       2090
>         nonbranching body:    7095
> nr of TRY_CATCH:             178155
>  of those empty cleanup:          0
>    or non-throwing body:     61094
> nr of stale GIMPLE_NOP:        3883
> nr of other insns:        774766860
>
> So, it removes a few gotos, but that will also be done shortly after this
> pass in optimization (and could be done in the gimplifier already).  It
> removes some GIMPLE_BIND, where all of them will go away two passes later
> anyway.  It does some cleanup on the exception constructs, but with rths
> rewrite to expand them on trees something equivalent will be done three
> passes later.
>
> So, I removed the whole thing.  tramp3d compiles even a bit faster on -O0
> now.  Bootstrap times are unaffected.
>
> Doing this without regressions requires some minor surgery, mostly due to
> the pass formerly calling fold on all statements:
> * the builtin folders should use, well fold, not buildX directly, where
>  applicable
> * exception lowering should accept empty cleanups and do the obvious thing
> * exception region copying (used by omp lowering) should deal gracefully
>  with empty labels (left over when expanding trivial regions sometimes,
>  until cleanup_eh)
> * free_lang_data shouldn't null out DECL_INITIAL for static constants
>  (and the LTO streamer then needs to accept this)
> * LTO streamer should deal with GIMPLE_NOP (they're left until expand
>  with -O0)
>
> Regstrapped on x86_64-linux, no regressions, all languages+Ada.  Okay for
> trunk?
>

This patch caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42716

-- 
H.J.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-08 15:41   ` Jeff Law
@ 2009-10-08 16:13     ` Michael Matz
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Matz @ 2009-10-08 16:13 UTC (permalink / raw)
  To: Jeff Law; +Cc: Richard Guenther, gcc-patches

Hi,

On Thu, 8 Oct 2009, Jeff Law wrote:

> I don't think there's any reason to wait -- r_u_s is mostly a holdover 
> from a point prior to flattening the IR.  The kinds of things it finds 
> (or better stated, found) aren't terribly important, it was always of 
> marginal value given the compile time cost.

Oh, I thought at least you would have some love for it ;-))
r152563.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 13:24 ` Richard Guenther
@ 2009-10-08 15:41   ` Jeff Law
  2009-10-08 16:13     ` Michael Matz
  0 siblings, 1 reply; 13+ messages in thread
From: Jeff Law @ 2009-10-08 15:41 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Michael Matz, gcc-patches

On 10/07/2009 07:24 AM, Richard Guenther wrote:
> On Wed, Oct 7, 2009 at 2:29 PM, Michael Matz<matz@suse.de>  wrote:
>    
>> Hi,
>>
>> remove_useless_stmts folds statements at a time where not the whole
>> optimization engine is initialized yet, which causes the segfault of the
>> above bugreport.  Now, instead of just fixing the symptom I thought maybe
>> we can get rid of the whole pass instead.  Digging around it seems to have
>> been rotting away for some years already, while occasionally making it
>> remove less stmts or fixing other bugs, somewhen being split into
>> cfg_remove_useless_stmts, which shortly after was removed again.  It
>> survived tuplification living its meagre life on and on.
>>
>> To determine its meagreness I added some statistics code to see what it
>> actually still removes and measured a whole bootstrap cycle with testsuite
>> (all languages+Ada), and this is the result:
>>
>> number of compiler invocations: 70332
>> overall number of repeats:     214136
>>   (When something is changed by r_u_s it repeats the scan of all insns
>>   again)
>> overall insns visited:   1025945788
>>   of those changed at all:   1111266 (a whopping promille)
>> nr of conditional insns:    4136111
>>   of those trivial true:       84084
>>          trivial false:      152987
>>         same destination:         8 (wow)
>> nr unconditional gotos:   244390760
>>   of those fallthru:          478812
>> nr of GIMPLE_BIND:          2268987
>>   of those removed:           304083
>> nr of TRY_FINALLY:           201032
>>   of those empty eval:         17130
>>           empty cleanup:       2090
>>          nonbranching body:    7095
>> nr of TRY_CATCH:             178155
>>   of those empty cleanup:          0
>>     or non-throwing body:     61094
>> nr of stale GIMPLE_NOP:        3883
>> nr of other insns:        774766860
>>
>> So, it removes a few gotos, but that will also be done shortly after this
>> pass in optimization (and could be done in the gimplifier already).  It
>> removes some GIMPLE_BIND, where all of them will go away two passes later
>> anyway.  It does some cleanup on the exception constructs, but with rths
>> rewrite to expand them on trees something equivalent will be done three
>> passes later.
>>
>> So, I removed the whole thing.  tramp3d compiles even a bit faster on -O0
>> now.  Bootstrap times are unaffected.
>>
>> Doing this without regressions requires some minor surgery, mostly due to
>> the pass formerly calling fold on all statements:
>> * the builtin folders should use, well fold, not buildX directly, where
>>   applicable
>> * exception lowering should accept empty cleanups and do the obvious thing
>> * exception region copying (used by omp lowering) should deal gracefully
>>   with empty labels (left over when expanding trivial regions sometimes,
>>   until cleanup_eh)
>> * free_lang_data shouldn't null out DECL_INITIAL for static constants
>>   (and the LTO streamer then needs to accept this)
>> * LTO streamer should deal with GIMPLE_NOP (they're left until expand
>>   with -O0)
>>
>> Regstrapped on x86_64-linux, no regressions, all languages+Ada.  Okay for
>> trunk?
>>      
> Ok with ...
>
>    
>> --- testsuite/gcc.dg/tree-ssa/foldstring-1.c    (revision 152447)
>> +++ testsuite/gcc.dg/tree-ssa/foldstring-1.c    (working copy)
>> @@ -1,5 +1,5 @@
>>   /* { dg-do compile } */
>> -/* { dg-options "-O1 -fdump-tree-useless" } */
>> +/* { dg-options "-O1 -fdump-tree-fre" } */
>>
>>   void
>>   arf ()
>> @@ -7,5 +7,5 @@ arf ()
>>    if (""[0] == 0)
>>      blah ();
>>   }
>> -/* { dg-final { scan-tree-dump-times "= 0;" 1 "useless"} } */
>> -/* { dg-final { cleanup-tree-dump "useless" } } */
>> +/* { dg-final { scan-tree-dump-times "= 0;" 1 "fre"} } */
>> +/* { dg-final { cleanup-tree-dump "fre" } } */
>>      
> Changing that to scan the gimple dump, XFAILing it and file
> a missed-optimization PR for fold / gimplification.
>
> Oh, and please wait some 24h in case somebody has strong
> reasons to keep that pass.
>    
I don't think there's any reason to wait -- r_u_s is mostly a holdover 
from a point prior to flattening the IR.    The kinds of things it finds 
(or better stated, found) aren't terribly important, it was always of 
marginal value given the compile time cost.

jeff


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 15:16         ` Richard Guenther
@ 2009-10-07 15:33           ` Michael Matz
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Matz @ 2009-10-07 15:33 UTC (permalink / raw)
  To: Richard Guenther; +Cc: Eric Botcazou, gcc-patches

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1328 bytes --]

Hi,

On Wed, 7 Oct 2009, Richard Guenther wrote:

> >> > Same code.  Even at -O0 we run cleanup_cfg, which uses gimple_fold 
> >> > on conditions, so the jumps are cleaned up in the same way that 
> >> > also r_u_s did.
> >>
> >> Nice, thanks.
> >
> > Strictly speaking I lied, there are (on all of tramp3d) 88 instances 
> > of (- is before patch, + is after)
> > -       movl    $0, %eax
> > +       movl    $2, %eax
> > +       andl    $1, %eax
> >        testb   %al, %al
> >        je      .Lxxx
> 
> Heh.  I wonder where that comes from.  My guess would be
> gimplifying x != 0 to (x != 0) != 0 as I have seen this before.

Not really.

    struct Runnable
      {
        virtual ~Runnable() {}
      };
    Runnable x;

The problem is the cloned in-charge/not-in-charge dtors:

003t.original:
....
<D.2104>:;
if ((bool) (__in_chrg & 1))
  {
   ....
  }

004t.gimple (after cloning and constant substitution of __in_chrg, which 
doesn't fold):
  <D.2110>:
  D.2151 = 2 & 1;
  D.2152 = (bool) D.2151;
  if (D.2152 != 0) goto <D.2153>; else goto <D.2154>;
  <D.2153>:

Recursive folding in the gimplifier would fix this, as would folding from 
the frontends (though we try to go away from the frontends folding too 
much).


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 15:00       ` Michael Matz
@ 2009-10-07 15:16         ` Richard Guenther
  2009-10-07 15:33           ` Michael Matz
  0 siblings, 1 reply; 13+ messages in thread
From: Richard Guenther @ 2009-10-07 15:16 UTC (permalink / raw)
  To: Michael Matz; +Cc: Eric Botcazou, gcc-patches

On Wed, Oct 7, 2009 at 4:50 PM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> On Wed, 7 Oct 2009, Eric Botcazou wrote:
>
>> > Same code.  Even at -O0 we run cleanup_cfg, which uses gimple_fold on
>> > conditions, so the jumps are cleaned up in the same way that also r_u_s
>> > did.
>>
>> Nice, thanks.
>
> Strictly speaking I lied, there are (on all of tramp3d) 88 instances of
> (- is before patch, + is after)
> -       movl    $0, %eax
> +       movl    $2, %eax
> +       andl    $1, %eax
>        testb   %al, %al
>        je      .Lxxx

Heh.  I wonder where that comes from.  My guess would be
gimplifying x != 0 to (x != 0) != 0 as I have seen this before.

Richard.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 14:34     ` Eric Botcazou
@ 2009-10-07 15:00       ` Michael Matz
  2009-10-07 15:16         ` Richard Guenther
  0 siblings, 1 reply; 13+ messages in thread
From: Michael Matz @ 2009-10-07 15:00 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

Hi,

On Wed, 7 Oct 2009, Eric Botcazou wrote:

> > Same code.  Even at -O0 we run cleanup_cfg, which uses gimple_fold on
> > conditions, so the jumps are cleaned up in the same way that also r_u_s
> > did.
> 
> Nice, thanks.

Strictly speaking I lied, there are (on all of tramp3d) 88 instances of
(- is before patch, + is after)
-       movl    $0, %eax
+       movl    $2, %eax
+       andl    $1, %eax
        testb   %al, %al
        je      .Lxxx

So, a too complicated expression to fold with r_u_s remains too 
complicated, just one more level.  I'm not concerned about this, if we 
were to really worry about code quality at -O0 we should run some simple 
optimization passes properly instead of relying on folding having happened 
in random places.  Overall codesize for tramp3d changes from 1137850 to 
1138226 at -O0.  Pff ;-)


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 14:01   ` Michael Matz
@ 2009-10-07 14:34     ` Eric Botcazou
  2009-10-07 15:00       ` Michael Matz
  0 siblings, 1 reply; 13+ messages in thread
From: Eric Botcazou @ 2009-10-07 14:34 UTC (permalink / raw)
  To: Michael Matz; +Cc: gcc-patches

> Same code.  Even at -O0 we run cleanup_cfg, which uses gimple_fold on
> conditions, so the jumps are cleaned up in the same way that also r_u_s
> did.

Nice, thanks.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 13:34 ` Eric Botcazou
@ 2009-10-07 14:01   ` Michael Matz
  2009-10-07 14:34     ` Eric Botcazou
  0 siblings, 1 reply; 13+ messages in thread
From: Michael Matz @ 2009-10-07 14:01 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

Hi,

On Wed, 7 Oct 2009, Eric Botcazou wrote:

> > So, I removed the whole thing.  tramp3d compiles even a bit faster on -O0
> > now.  Bootstrap times are unaffected.
> 
> What about code size at -O0?

Same code.  Even at -O0 we run cleanup_cfg, which uses gimple_fold on 
conditions, so the jumps are cleaned up in the same way that also r_u_s 
did.  There are some renumberings in the exception labels.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 13:09 Michael Matz
  2009-10-07 13:24 ` Richard Guenther
@ 2009-10-07 13:34 ` Eric Botcazou
  2009-10-07 14:01   ` Michael Matz
  2010-01-13  3:20 ` H.J. Lu
  2 siblings, 1 reply; 13+ messages in thread
From: Eric Botcazou @ 2009-10-07 13:34 UTC (permalink / raw)
  To: Michael Matz; +Cc: gcc-patches

> So, I removed the whole thing.  tramp3d compiles even a bit faster on -O0
> now.  Bootstrap times are unaffected.

What about code size at -O0?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: Fix PR41573, remove pass_remove_useless_stmts
  2009-10-07 13:09 Michael Matz
@ 2009-10-07 13:24 ` Richard Guenther
  2009-10-08 15:41   ` Jeff Law
  2009-10-07 13:34 ` Eric Botcazou
  2010-01-13  3:20 ` H.J. Lu
  2 siblings, 1 reply; 13+ messages in thread
From: Richard Guenther @ 2009-10-07 13:24 UTC (permalink / raw)
  To: Michael Matz; +Cc: gcc-patches

On Wed, Oct 7, 2009 at 2:29 PM, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> remove_useless_stmts folds statements at a time where not the whole
> optimization engine is initialized yet, which causes the segfault of the
> above bugreport.  Now, instead of just fixing the symptom I thought maybe
> we can get rid of the whole pass instead.  Digging around it seems to have
> been rotting away for some years already, while occasionally making it
> remove less stmts or fixing other bugs, somewhen being split into
> cfg_remove_useless_stmts, which shortly after was removed again.  It
> survived tuplification living its meagre life on and on.
>
> To determine its meagreness I added some statistics code to see what it
> actually still removes and measured a whole bootstrap cycle with testsuite
> (all languages+Ada), and this is the result:
>
> number of compiler invocations: 70332
> overall number of repeats:     214136
>  (When something is changed by r_u_s it repeats the scan of all insns
>  again)
> overall insns visited:   1025945788
>  of those changed at all:   1111266 (a whopping promille)
> nr of conditional insns:    4136111
>  of those trivial true:       84084
>         trivial false:      152987
>        same destination:         8 (wow)
> nr unconditional gotos:   244390760
>  of those fallthru:          478812
> nr of GIMPLE_BIND:          2268987
>  of those removed:           304083
> nr of TRY_FINALLY:           201032
>  of those empty eval:         17130
>          empty cleanup:       2090
>         nonbranching body:    7095
> nr of TRY_CATCH:             178155
>  of those empty cleanup:          0
>    or non-throwing body:     61094
> nr of stale GIMPLE_NOP:        3883
> nr of other insns:        774766860
>
> So, it removes a few gotos, but that will also be done shortly after this
> pass in optimization (and could be done in the gimplifier already).  It
> removes some GIMPLE_BIND, where all of them will go away two passes later
> anyway.  It does some cleanup on the exception constructs, but with rths
> rewrite to expand them on trees something equivalent will be done three
> passes later.
>
> So, I removed the whole thing.  tramp3d compiles even a bit faster on -O0
> now.  Bootstrap times are unaffected.
>
> Doing this without regressions requires some minor surgery, mostly due to
> the pass formerly calling fold on all statements:
> * the builtin folders should use, well fold, not buildX directly, where
>  applicable
> * exception lowering should accept empty cleanups and do the obvious thing
> * exception region copying (used by omp lowering) should deal gracefully
>  with empty labels (left over when expanding trivial regions sometimes,
>  until cleanup_eh)
> * free_lang_data shouldn't null out DECL_INITIAL for static constants
>  (and the LTO streamer then needs to accept this)
> * LTO streamer should deal with GIMPLE_NOP (they're left until expand
>  with -O0)
>
> Regstrapped on x86_64-linux, no regressions, all languages+Ada.  Okay for
> trunk?

Ok with ...

> --- testsuite/gcc.dg/tree-ssa/foldstring-1.c    (revision 152447)
> +++ testsuite/gcc.dg/tree-ssa/foldstring-1.c    (working copy)
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O1 -fdump-tree-useless" } */
> +/* { dg-options "-O1 -fdump-tree-fre" } */
>
>  void
>  arf ()
> @@ -7,5 +7,5 @@ arf ()
>   if (""[0] == 0)
>     blah ();
>  }
> -/* { dg-final { scan-tree-dump-times "= 0;" 1 "useless"} } */
> -/* { dg-final { cleanup-tree-dump "useless" } } */
> +/* { dg-final { scan-tree-dump-times "= 0;" 1 "fre"} } */
> +/* { dg-final { cleanup-tree-dump "fre" } } */

Changing that to scan the gimple dump, XFAILing it and file
a missed-optimization PR for fold / gimplification.

Oh, and please wait some 24h in case somebody has strong
reasons to keep that pass.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Fix PR41573, remove pass_remove_useless_stmts
@ 2009-10-07 13:09 Michael Matz
  2009-10-07 13:24 ` Richard Guenther
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Michael Matz @ 2009-10-07 13:09 UTC (permalink / raw)
  To: gcc-patches

Hi,

remove_useless_stmts folds statements at a time where not the whole 
optimization engine is initialized yet, which causes the segfault of the 
above bugreport.  Now, instead of just fixing the symptom I thought maybe 
we can get rid of the whole pass instead.  Digging around it seems to have 
been rotting away for some years already, while occasionally making it 
remove less stmts or fixing other bugs, somewhen being split into 
cfg_remove_useless_stmts, which shortly after was removed again.  It 
survived tuplification living its meagre life on and on.

To determine its meagreness I added some statistics code to see what it 
actually still removes and measured a whole bootstrap cycle with testsuite 
(all languages+Ada), and this is the result:

number of compiler invocations: 70332
overall number of repeats:     214136
  (When something is changed by r_u_s it repeats the scan of all insns 
  again)
overall insns visited:   1025945788
 of those changed at all:   1111266 (a whopping promille)
nr of conditional insns:    4136111
 of those trivial true:       84084
         trivial false:      152987
        same destination:         8 (wow)
nr unconditional gotos:   244390760
 of those fallthru:          478812
nr of GIMPLE_BIND:          2268987
 of those removed:           304083
nr of TRY_FINALLY:           201032
 of those empty eval:         17130
          empty cleanup:       2090
         nonbranching body:    7095
nr of TRY_CATCH:             178155
 of those empty cleanup:          0
    or non-throwing body:     61094
nr of stale GIMPLE_NOP:        3883
nr of other insns:        774766860

So, it removes a few gotos, but that will also be done shortly after this 
pass in optimization (and could be done in the gimplifier already).  It 
removes some GIMPLE_BIND, where all of them will go away two passes later 
anyway.  It does some cleanup on the exception constructs, but with rths 
rewrite to expand them on trees something equivalent will be done three 
passes later.

So, I removed the whole thing.  tramp3d compiles even a bit faster on -O0 
now.  Bootstrap times are unaffected.

Doing this without regressions requires some minor surgery, mostly due to 
the pass formerly calling fold on all statements:
* the builtin folders should use, well fold, not buildX directly, where
  applicable
* exception lowering should accept empty cleanups and do the obvious thing
* exception region copying (used by omp lowering) should deal gracefully
  with empty labels (left over when expanding trivial regions sometimes,
  until cleanup_eh)
* free_lang_data shouldn't null out DECL_INITIAL for static constants
  (and the LTO streamer then needs to accept this)
* LTO streamer should deal with GIMPLE_NOP (they're left until expand 
  with -O0)

Regstrapped on x86_64-linux, no regressions, all languages+Ada.  Okay for 
trunk?


Ciao,
Michael.
-- 
	PR middle-end/41573
	* builtins.c (fold_builtin_isascii): Use fold_build2.
	(fold_builtin_isdigit): Ditto.
	* except.c (duplicate_eh_regions_1): Tolerate NULL labels.
	* tree-cfg.c (struct rus_data, remove_useless_stmts_warn_notreached,
	remove_useless_stmts_cond, remove_useless_stmts_tf,
	remove_useless_stmts_tc, remove_useless_stmts_bind,
	remove_useless_stmts_goto, remove_useless_stmts_label,
	remove_useless_stmts_1, remove_useless_stmts,
	pass_remove_useless_stmts): Remove.
	* tree-pass.h (pass_remove_useless_stmts): Don't declare.
	* passes.c (init_optimization_passes): Don't add
	pass_remove_useless_stmts.
	* tree-eh.c (lower_eh_constructs_2): Handle empty cleanups.
	* tree.c (free_lang_data_in_decl): Don't clear DECL_INITIAL of
	static constants.
	* lto-symtab.c (lto_symtab_merge_decl): Accepts DECL_INITIAL
	for static constants.
	* lto-streamer-out.c (output_gimple_stmt): Handle GIMPLE_NOP.
	* lto-streamer-in.c (input_gimple_stmt): Handle GIMPLE_NOP.

testsuite/
	* gcc.dg/tree-ssa/foldstring-1.c: Use fre dump.
	* gcc.dg/tree-ssa/useless-1.c: Use gimple dump.
	* gcc.dg/pr41573.c: New test.

Index: builtins.c
===================================================================
--- builtins.c	(Revision 152447)
+++ builtins.c	(Arbeitskopie)
@@ -9238,9 +9238,9 @@ fold_builtin_isascii (location_t loc, tr
   else
     {
       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
-      arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
-		    build_int_cst (NULL_TREE,
-				   ~ (unsigned HOST_WIDE_INT) 0x7f));
+      arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
+			 build_int_cst (NULL_TREE,
+					~ (unsigned HOST_WIDE_INT) 0x7f));
       return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
 			  arg, integer_zero_node);
     }
@@ -9278,8 +9278,8 @@ fold_builtin_isdigit (location_t loc, tr
 	return NULL_TREE;
 
       arg = fold_convert_loc (loc, unsigned_type_node, arg);
-      arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
-		    build_int_cst (unsigned_type_node, target_digit0));
+      arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
+			 build_int_cst (unsigned_type_node, target_digit0));
       return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
 			  build_int_cst (unsigned_type_node, 9));
     }
Index: except.c
===================================================================
--- except.c	(Revision 152447)
+++ except.c	(Arbeitskopie)
@@ -552,8 +552,11 @@ duplicate_eh_regions_1 (struct duplicate
 
     case ERT_ALLOWED_EXCEPTIONS:
       new_r->u.allowed.type_list = old_r->u.allowed.type_list;
-      new_r->u.allowed.label
-	= data->label_map (old_r->u.allowed.label, data->label_map_data);
+      if (old_r->u.allowed.label)
+	new_r->u.allowed.label
+	    = data->label_map (old_r->u.allowed.label, data->label_map_data);
+      else
+	new_r->u.allowed.label = NULL_TREE;
       break;
 
     case ERT_MUST_NOT_THROW:
Index: passes.c
===================================================================
--- passes.c	(Revision 152447)
+++ passes.c	(Arbeitskopie)
@@ -683,7 +683,6 @@ init_optimization_passes (void)
   p = &all_lowering_passes;
   NEXT_PASS (pass_warn_unused_result);
   NEXT_PASS (pass_diagnose_omp_blocks);
-  NEXT_PASS (pass_remove_useless_stmts);
   NEXT_PASS (pass_mudflap_1);
   NEXT_PASS (pass_lower_omp);
   NEXT_PASS (pass_lower_cf);
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(Revision 152447)
+++ tree-cfg.c	(Arbeitskopie)
@@ -1715,423 +1715,6 @@ single_noncomplex_succ (basic_block bb)
   return bb;
 }
 
-
-/* Walk the function tree removing unnecessary statements.
-
-     * Empty statement nodes are removed
-
-     * Unnecessary TRY_FINALLY and TRY_CATCH blocks are removed
-
-     * Unnecessary COND_EXPRs are removed
-
-     * Some unnecessary BIND_EXPRs are removed
-
-     * GOTO_EXPRs immediately preceding destination are removed.
-
-   Clearly more work could be done.  The trick is doing the analysis
-   and removal fast enough to be a net improvement in compile times.
-
-   Note that when we remove a control structure such as a COND_EXPR
-   BIND_EXPR, or TRY block, we will need to repeat this optimization pass
-   to ensure we eliminate all the useless code.  */
-
-struct rus_data
-{
-  bool repeat;
-  bool may_throw;
-  bool may_branch;
-  bool has_label;
-  bool last_was_goto;
-  gimple_stmt_iterator last_goto_gsi;
-};
-
-
-static void remove_useless_stmts_1 (gimple_stmt_iterator *gsi, struct rus_data *);
-
-/* Given a statement sequence, find the first executable statement with
-   location information, and warn that it is unreachable.  When searching,
-   descend into containers in execution order.  */
-
-static bool
-remove_useless_stmts_warn_notreached (gimple_seq stmts)
-{
-  gimple_stmt_iterator gsi;
-
-  for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
-    {
-      gimple stmt = gsi_stmt (gsi);
-
-      if (gimple_no_warning_p (stmt)) return false;
-
-      if (gimple_has_location (stmt))
-        {
-          location_t loc = gimple_location (stmt);
-          if (LOCATION_LINE (loc) > 0)
-	    {
-              warning_at (loc, OPT_Wunreachable_code, "will never be executed");
-              return true;
-            }
-        }
-
-      switch (gimple_code (stmt))
-        {
-        /* Unfortunately, we need the CFG now to detect unreachable
-           branches in a conditional, so conditionals are not handled here.  */
-
-        case GIMPLE_TRY:
-          if (remove_useless_stmts_warn_notreached (gimple_try_eval (stmt)))
-            return true;
-          if (remove_useless_stmts_warn_notreached (gimple_try_cleanup (stmt)))
-            return true;
-          break;
-
-        case GIMPLE_CATCH:
-          return remove_useless_stmts_warn_notreached (gimple_catch_handler (stmt));
-
-        case GIMPLE_EH_FILTER:
-          return remove_useless_stmts_warn_notreached (gimple_eh_filter_failure (stmt));
-
-        case GIMPLE_BIND:
-          return remove_useless_stmts_warn_notreached (gimple_bind_body (stmt));
-
-        default:
-          break;
-        }
-    }
-
-  return false;
-}
-
-/* Helper for remove_useless_stmts_1.  Handle GIMPLE_COND statements.  */
-
-static void
-remove_useless_stmts_cond (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
-  gimple stmt = gsi_stmt (*gsi);
-
-  /* The folded result must still be a conditional statement.  */
-  fold_stmt (gsi);
-  gcc_assert (gsi_stmt (*gsi) == stmt);
-
-  data->may_branch = true;
-
-  /* Replace trivial conditionals with gotos. */
-  if (gimple_cond_true_p (stmt))
-    {
-      /* Goto THEN label.  */
-      tree then_label = gimple_cond_true_label (stmt);
-
-      gsi_replace (gsi, gimple_build_goto (then_label), false);
-      data->last_goto_gsi = *gsi;
-      data->last_was_goto = true;
-      data->repeat = true;
-    }
-  else if (gimple_cond_false_p (stmt))
-    {
-      /* Goto ELSE label.  */
-      tree else_label = gimple_cond_false_label (stmt);
-
-      gsi_replace (gsi, gimple_build_goto (else_label), false);
-      data->last_goto_gsi = *gsi;
-      data->last_was_goto = true;
-      data->repeat = true;
-    }
-  else
-    {
-      tree then_label = gimple_cond_true_label (stmt);
-      tree else_label = gimple_cond_false_label (stmt);
-
-      if (then_label == else_label)
-        {
-          /* Goto common destination.  */
-          gsi_replace (gsi, gimple_build_goto (then_label), false);
-          data->last_goto_gsi = *gsi;
-          data->last_was_goto = true;
-	  data->repeat = true;
-	}
-    }
-
-  gsi_next (gsi);
-
-  data->last_was_goto = false;
-}
-
-/* Helper for remove_useless_stmts_1. 
-   Handle the try-finally case for GIMPLE_TRY statements.  */
-
-static void
-remove_useless_stmts_tf (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
-  bool save_may_branch, save_may_throw;
-  bool this_may_branch, this_may_throw;
-
-  gimple_seq eval_seq, cleanup_seq;
-  gimple_stmt_iterator eval_gsi, cleanup_gsi;
-
-  gimple stmt = gsi_stmt (*gsi);
-
-  /* Collect may_branch and may_throw information for the body only.  */
-  save_may_branch = data->may_branch;
-  save_may_throw = data->may_throw;
-  data->may_branch = false;
-  data->may_throw = false;
-  data->last_was_goto = false;
-
-  eval_seq = gimple_try_eval (stmt);
-  eval_gsi = gsi_start (eval_seq);
-  remove_useless_stmts_1 (&eval_gsi, data);
-
-  this_may_branch = data->may_branch;
-  this_may_throw = data->may_throw;
-  data->may_branch |= save_may_branch;
-  data->may_throw |= save_may_throw;
-  data->last_was_goto = false;
-
-  cleanup_seq = gimple_try_cleanup (stmt);
-  cleanup_gsi = gsi_start (cleanup_seq);
-  remove_useless_stmts_1 (&cleanup_gsi, data);
-
-  /* If the body is empty, then we can emit the FINALLY block without
-     the enclosing TRY_FINALLY_EXPR.  */
-  if (gimple_seq_empty_p (eval_seq))
-    {
-      gsi_insert_seq_before (gsi, cleanup_seq, GSI_SAME_STMT);
-      gsi_remove (gsi, false);
-      data->repeat = true;
-    }
-
-  /* If the handler is empty, then we can emit the TRY block without
-     the enclosing TRY_FINALLY_EXPR.  */
-  else if (gimple_seq_empty_p (cleanup_seq))
-    {
-      gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
-      gsi_remove (gsi, false);
-      data->repeat = true;
-    }
-
-  /* If the body neither throws, nor branches, then we can safely
-     string the TRY and FINALLY blocks together.  */
-  else if (!this_may_branch && !this_may_throw)
-    {
-      gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
-      gsi_insert_seq_before (gsi, cleanup_seq, GSI_SAME_STMT);
-      gsi_remove (gsi, false);
-      data->repeat = true;
-    }
-  else
-    gsi_next (gsi);
-}
-
-/* Helper for remove_useless_stmts_1. 
-   Handle the try-catch case for GIMPLE_TRY statements.  */
-
-static void
-remove_useless_stmts_tc (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
-  bool save_may_throw, this_may_throw;
-
-  gimple_seq eval_seq, cleanup_seq, handler_seq, failure_seq;
-  gimple_stmt_iterator eval_gsi, cleanup_gsi, handler_gsi, failure_gsi;
-
-  gimple stmt = gsi_stmt (*gsi);
-
-  /* Collect may_throw information for the body only.  */
-  save_may_throw = data->may_throw;
-  data->may_throw = false;
-  data->last_was_goto = false;
-
-  eval_seq = gimple_try_eval (stmt);
-  eval_gsi = gsi_start (eval_seq);
-  remove_useless_stmts_1 (&eval_gsi, data);
-
-  this_may_throw = data->may_throw;
-  data->may_throw = save_may_throw;
-
-  cleanup_seq = gimple_try_cleanup (stmt);
-
-  /* If the body cannot throw, then we can drop the entire TRY_CATCH_EXPR.  */
-  if (!this_may_throw)
-    {
-      if (warn_notreached)
-        {
-          remove_useless_stmts_warn_notreached (cleanup_seq);
-        }
-      gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
-      gsi_remove (gsi, false);
-      data->repeat = true;
-      return;
-    }
-
-  /* Process the catch clause specially.  We may be able to tell that
-     no exceptions propagate past this point.  */
-
-  this_may_throw = true;
-  cleanup_gsi = gsi_start (cleanup_seq);
-  stmt = gsi_stmt (cleanup_gsi);
-  data->last_was_goto = false;
-
-  switch (gimple_code (stmt))
-    {
-    case GIMPLE_CATCH:
-      /* If the first element is a catch, they all must be.  */
-      while (!gsi_end_p (cleanup_gsi))
-        {
-	  stmt = gsi_stmt (cleanup_gsi);
-	  /* If we catch all exceptions, then the body does not
-	     propagate exceptions past this point.  */
-	  if (gimple_catch_types (stmt) == NULL)
-	    this_may_throw = false;
-	  data->last_was_goto = false;
-          handler_seq = gimple_catch_handler (stmt);
-          handler_gsi = gsi_start (handler_seq);
-	  remove_useless_stmts_1 (&handler_gsi, data);
-          gsi_next (&cleanup_gsi);
-	}
-      gsi_next (gsi);
-      break;
-
-    case GIMPLE_EH_FILTER:
-      if (gimple_eh_filter_types (stmt) == NULL)
-	this_may_throw = false;
-      failure_seq = gimple_eh_filter_failure (stmt);
-      failure_gsi = gsi_start (failure_seq);
-      remove_useless_stmts_1 (&failure_gsi, data);
-      gsi_next (gsi);
-      break;
-
-    case GIMPLE_EH_MUST_NOT_THROW:
-      this_may_throw = false;
-      gsi_next (gsi);
-      break;
-
-    default:
-      /* Otherwise this is a list of cleanup statements.  */
-      remove_useless_stmts_1 (&cleanup_gsi, data);
-
-      /* If the cleanup is empty, then we can emit the TRY block without
-	 the enclosing TRY_CATCH_EXPR.  */
-      if (gimple_seq_empty_p (cleanup_seq))
-	{
-          gsi_insert_seq_before (gsi, eval_seq, GSI_SAME_STMT);
-          gsi_remove(gsi, false);
-	  data->repeat = true;
-	}
-      else
-        gsi_next (gsi);
-      break;
-    }
-
-  data->may_throw |= this_may_throw;
-}
-
-/* Helper for remove_useless_stmts_1.  Handle GIMPLE_BIND statements.  */
-
-static void
-remove_useless_stmts_bind (gimple_stmt_iterator *gsi, struct rus_data *data ATTRIBUTE_UNUSED)
-{
-  tree block;
-  gimple_seq body_seq, fn_body_seq;
-  gimple_stmt_iterator body_gsi;
-
-  gimple stmt = gsi_stmt (*gsi);
-
-  /* First remove anything underneath the BIND_EXPR.  */
-  
-  body_seq = gimple_bind_body (stmt);
-  body_gsi = gsi_start (body_seq);
-  remove_useless_stmts_1 (&body_gsi, data);
-
-  /* If the GIMPLE_BIND has no variables, then we can pull everything
-     up one level and remove the GIMPLE_BIND, unless this is the toplevel
-     GIMPLE_BIND for the current function or an inlined function.
-
-     When this situation occurs we will want to apply this
-     optimization again.  */
-  block = gimple_bind_block (stmt);
-  fn_body_seq = gimple_body (current_function_decl);
-  if (gimple_bind_vars (stmt) == NULL_TREE
-      && (gimple_seq_empty_p (fn_body_seq)
-          || stmt != gimple_seq_first_stmt (fn_body_seq))
-      && (! block
-	  || ! BLOCK_ABSTRACT_ORIGIN (block)
-	  || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block))
-	      != FUNCTION_DECL)))
-    {
-      tree var = NULL_TREE;
-      /* Even if there are no gimple_bind_vars, there might be other
-	 decls in BLOCK_VARS rendering the GIMPLE_BIND not useless.  */
-      if (block && !BLOCK_NUM_NONLOCALIZED_VARS (block))
-	for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var))
-	  if (TREE_CODE (var) == IMPORTED_DECL)
-	    break;
-      if (var || (block && BLOCK_NUM_NONLOCALIZED_VARS (block)))
-	gsi_next (gsi);
-      else
-	{
-	  gsi_insert_seq_before (gsi, body_seq, GSI_SAME_STMT);
-	  gsi_remove (gsi, false);
-	  data->repeat = true;
-	}
-    }
-  else
-    gsi_next (gsi);
-}
-
-/* Helper for remove_useless_stmts_1.  Handle GIMPLE_GOTO statements.  */
-
-static void
-remove_useless_stmts_goto (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
-  gimple stmt = gsi_stmt (*gsi);
-
-  tree dest = gimple_goto_dest (stmt);
-
-  data->may_branch = true;
-  data->last_was_goto = false;
-
-  /* Record iterator for last goto expr, so that we can delete it if unnecessary.  */
-  if (TREE_CODE (dest) == LABEL_DECL)
-    {
-      data->last_goto_gsi = *gsi;
-      data->last_was_goto = true;
-    }
-
-  gsi_next(gsi);
-}
-
-/* Helper for remove_useless_stmts_1.  Handle GIMPLE_LABEL statements.  */
-
-static void
-remove_useless_stmts_label (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
-  gimple stmt = gsi_stmt (*gsi);
-
-  tree label = gimple_label_label (stmt);
-
-  data->has_label = true;
-
-  /* We do want to jump across non-local label receiver code.  */
-  if (DECL_NONLOCAL (label))
-    data->last_was_goto = false;
-
-  else if (data->last_was_goto
-           && gimple_goto_dest (gsi_stmt (data->last_goto_gsi)) == label)
-    {
-      /* Replace the preceding GIMPLE_GOTO statement with
-         a GIMPLE_NOP, which will be subsequently removed.
-         In this way, we avoid invalidating other iterators
-         active on the statement sequence.  */
-      gsi_replace(&data->last_goto_gsi, gimple_build_nop(), false);
-      data->last_was_goto = false;
-      data->repeat = true;
-    }
-
-  /* ??? Add something here to delete unused labels.  */
-
-  gsi_next (gsi);
-}
-
-
 /* T is CALL_EXPR.  Set current_function_calls_* flags.  */
 
 void
@@ -2156,188 +1739,6 @@ clear_special_calls (void)
   cfun->calls_setjmp = false;
 }
 
-/* Remove useless statements from a statement sequence, and perform
-   some preliminary simplifications.  */
-
-static void
-remove_useless_stmts_1 (gimple_stmt_iterator *gsi, struct rus_data *data)
-{
-  while (!gsi_end_p (*gsi))
-    {
-      gimple stmt = gsi_stmt (*gsi);
-
-      switch (gimple_code (stmt))
-        {
-        case GIMPLE_COND:
-          remove_useless_stmts_cond (gsi, data);
-          break;
-
-        case GIMPLE_GOTO:
-          remove_useless_stmts_goto (gsi, data);
-          break;
-
-        case GIMPLE_LABEL:
-          remove_useless_stmts_label (gsi, data);
-          break;
-
-        case GIMPLE_ASSIGN:
-          fold_stmt (gsi);
-          stmt = gsi_stmt (*gsi);
-          data->last_was_goto = false;
-          if (stmt_could_throw_p (stmt))
-            data->may_throw = true;
-          gsi_next (gsi);
-          break;
-
-        case GIMPLE_ASM:
-          fold_stmt (gsi);
-          data->last_was_goto = false;
-          gsi_next (gsi);
-          break;
-
-        case GIMPLE_CALL:
-          fold_stmt (gsi);
-          stmt = gsi_stmt (*gsi);
-          data->last_was_goto = false;
-          if (is_gimple_call (stmt))
-            notice_special_calls (stmt);
-
-          /* We used to call update_gimple_call_flags here,
-             which copied side-effects and nothrows status
-             from the function decl to the call.  In the new
-             tuplified GIMPLE, the accessors for this information
-             always consult the function decl, so this copying
-             is no longer necessary.  */
-          if (stmt_could_throw_p (stmt))
-            data->may_throw = true;
-          gsi_next (gsi);
-          break;
-
-        case GIMPLE_RETURN:
-          fold_stmt (gsi);
-          data->last_was_goto = false;
-          data->may_branch = true;
-          gsi_next (gsi);
-          break;
-
-        case GIMPLE_BIND:
-          remove_useless_stmts_bind (gsi, data);
-          break;
-
-        case GIMPLE_TRY:
-          if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
-            remove_useless_stmts_tc (gsi, data);
-          else if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
-            remove_useless_stmts_tf (gsi, data);
-          else
-            gcc_unreachable ();
-          break;
-
-        case GIMPLE_CATCH:
-          gcc_unreachable ();
-          break;
-
-        case GIMPLE_NOP:
-          gsi_remove (gsi, false);
-          break;
-
-        case GIMPLE_OMP_FOR:
-          {
-            gimple_seq pre_body_seq = gimple_omp_for_pre_body (stmt);
-            gimple_stmt_iterator pre_body_gsi = gsi_start (pre_body_seq);
-
-            remove_useless_stmts_1 (&pre_body_gsi, data);
-	    data->last_was_goto = false;
-          }
-          /* FALLTHROUGH */
-        case GIMPLE_OMP_CRITICAL:
-        case GIMPLE_OMP_CONTINUE:
-        case GIMPLE_OMP_MASTER:
-        case GIMPLE_OMP_ORDERED:
-        case GIMPLE_OMP_SECTION:
-        case GIMPLE_OMP_SECTIONS:
-        case GIMPLE_OMP_SINGLE:
-          {
-            gimple_seq body_seq = gimple_omp_body (stmt);
-            gimple_stmt_iterator body_gsi = gsi_start (body_seq);
-
-            remove_useless_stmts_1 (&body_gsi, data);
-	    data->last_was_goto = false;
-	    gsi_next (gsi);
-          }
-          break;
-
-        case GIMPLE_OMP_PARALLEL:
-	case GIMPLE_OMP_TASK:
-          {
-	    /* Make sure the outermost GIMPLE_BIND isn't removed
-	       as useless.  */
-            gimple_seq body_seq = gimple_omp_body (stmt);
-            gimple bind = gimple_seq_first_stmt (body_seq);
-            gimple_seq bind_seq = gimple_bind_body (bind);
-            gimple_stmt_iterator bind_gsi = gsi_start (bind_seq);
-
-            remove_useless_stmts_1 (&bind_gsi, data);
-	    data->last_was_goto = false;
-	    gsi_next (gsi);
-          }
-          break;
-
-        default:
-          data->last_was_goto = false;
-          gsi_next (gsi);
-          break;
-        }
-    }
-}
-
-/* Walk the function tree, removing useless statements and performing
-   some preliminary simplifications.  */
-
-static unsigned int
-remove_useless_stmts (void)
-{
-  struct rus_data data;
-
-  clear_special_calls ();
-
-  do
-    {
-      gimple_stmt_iterator gsi;
-
-      gsi = gsi_start (gimple_body (current_function_decl));
-      memset (&data, 0, sizeof (data));
-      remove_useless_stmts_1 (&gsi, &data);
-    }
-  while (data.repeat);
-
-#ifdef ENABLE_TYPES_CHECKING
-  verify_types_in_gimple_seq (gimple_body (current_function_decl));
-#endif
-
-  return 0;
-}
-
-
-struct gimple_opt_pass pass_remove_useless_stmts =
-{
- {
-  GIMPLE_PASS,
-  "useless",				/* name */
-  NULL,					/* gate */
-  remove_useless_stmts,			/* execute */
-  NULL,					/* sub */
-  NULL,					/* next */
-  0,					/* static_pass_number */
-  TV_NONE,				/* tv_id */
-  PROP_gimple_any,			/* properties_required */
-  0,					/* properties_provided */
-  0,					/* properties_destroyed */
-  0,					/* todo_flags_start */
-  TODO_dump_func			/* todo_flags_finish */
- }
-};
-
 /* Remove PHI nodes associated with basic block BB and all edges out of BB.  */
 
 static void
Index: tree-eh.c
===================================================================
--- tree-eh.c	(Revision 152447)
+++ tree-eh.c	(Arbeitskopie)
@@ -1919,21 +1919,27 @@ lower_eh_constructs_2 (struct leh_state
       else
 	{
 	  x = gimple_seq_first_stmt (gimple_try_cleanup (stmt));
-	  switch (gimple_code (x))
+	  if (!x)
 	    {
-	    case GIMPLE_CATCH:
-	      replace = lower_catch (state, stmt);
-	      break;
-	    case GIMPLE_EH_FILTER:
-	      replace = lower_eh_filter (state, stmt);
-	      break;
-	    case GIMPLE_EH_MUST_NOT_THROW:
-	      replace = lower_eh_must_not_throw (state, stmt);
-	      break;
-	    default:
-	      replace = lower_cleanup (state, stmt);
-	      break;
+	      replace = gimple_try_eval (stmt);
+	      lower_eh_constructs_1 (state, replace);
 	    }
+	  else
+	    switch (gimple_code (x))
+	      {
+		case GIMPLE_CATCH:
+		    replace = lower_catch (state, stmt);
+		    break;
+		case GIMPLE_EH_FILTER:
+		    replace = lower_eh_filter (state, stmt);
+		    break;
+		case GIMPLE_EH_MUST_NOT_THROW:
+		    replace = lower_eh_must_not_throw (state, stmt);
+		    break;
+		default:
+		    replace = lower_cleanup (state, stmt);
+		    break;
+	      }
 	}
 
       /* Remove the old stmt and insert the transformed sequence
Index: tree.c
===================================================================
--- tree.c	(Revision 152447)
+++ tree.c	(Arbeitskopie)
@@ -4438,7 +4441,8 @@ free_lang_data_in_decl (tree decl)
 	  && !TREE_STATIC (expr) && !DECL_EXTERNAL (expr))
 	SET_DECL_DEBUG_EXPR (decl, NULL_TREE);
 
-      if (DECL_EXTERNAL (decl))
+      if (DECL_EXTERNAL (decl)
+	  && (!TREE_STATIC (decl) || !TREE_READONLY (decl)))
 	DECL_INITIAL (decl) = NULL_TREE;
     }
   else if (TREE_CODE (decl) == TYPE_DECL)
Index: tree-pass.h
===================================================================
--- tree-pass.h	(Revision 152447)
+++ tree-pass.h	(Arbeitskopie)
@@ -333,7 +333,6 @@ extern void tree_lowering_passes (tree d
 
 extern struct gimple_opt_pass pass_mudflap_1;
 extern struct gimple_opt_pass pass_mudflap_2;
-extern struct gimple_opt_pass pass_remove_useless_stmts;
 extern struct gimple_opt_pass pass_lower_cf;
 extern struct gimple_opt_pass pass_refactor_eh;
 extern struct gimple_opt_pass pass_lower_eh;
Index: lto-streamer-out.c
===================================================================
--- lto-streamer-out.c	(revision 152447)
+++ lto-streamer-out.c	(working copy)
@@ -1692,6 +1692,7 @@ output_gimple_stmt (struct output_block
 	}
       break;
 
+    case GIMPLE_NOP:
     case GIMPLE_PREDICT:
       break;
 
Index: lto-streamer-in.c
===================================================================
--- lto-streamer-in.c	(revision 152447)
+++ lto-streamer-in.c	(working copy)
@@ -942,6 +942,7 @@ input_gimple_stmt (struct lto_input_bloc
 	}
       break;
 
+    case GIMPLE_NOP:
     case GIMPLE_PREDICT:
       break;
 
Index: lto-symtab.c
===================================================================
--- lto-symtab.c	(revision 152447)
+++ lto-symtab.c	(working copy)
@@ -567,8 +567,10 @@ lto_symtab_merge_decl (tree new_decl,
      properties inconsistent with having external linkage.  If any of
      these asertions fail, then the object file reader has failed to
      detect these cases and issue appropriate error messages.  */
-  if (TREE_CODE (new_decl) == VAR_DECL)
-    gcc_assert (!(DECL_EXTERNAL (new_decl) && DECL_INITIAL (new_decl)));
+  if (TREE_CODE (new_decl) == VAR_DECL
+      && DECL_INITIAL (new_decl))
+    gcc_assert (!DECL_EXTERNAL (new_decl)
+		|| (TREE_STATIC (new_decl) && TREE_READONLY (new_decl)));
 
   /* Remember the resolution of this symbol. */
   lto_symtab_set_resolution_and_file_data (new_decl, resolution, file_data);
Index: testsuite/gcc.dg/tree-ssa/foldstring-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/foldstring-1.c	(revision 152447)
+++ testsuite/gcc.dg/tree-ssa/foldstring-1.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-useless" } */
+/* { dg-options "-O1 -fdump-tree-fre" } */
 
 void
 arf ()
@@ -7,5 +7,5 @@ arf ()
   if (""[0] == 0)
     blah ();
 }
-/* { dg-final { scan-tree-dump-times "= 0;" 1 "useless"} } */ 
-/* { dg-final { cleanup-tree-dump "useless" } } */
+/* { dg-final { scan-tree-dump-times "= 0;" 1 "fre"} } */ 
+/* { dg-final { cleanup-tree-dump "fre" } } */
Index: testsuite/gcc.dg/tree-ssa/useless-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/useless-1.c	(revision 152447)
+++ testsuite/gcc.dg/tree-ssa/useless-1.c	(working copy)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O1 -fdump-tree-useless" } */
+/* { dg-options "-O1 -fdump-tree-gimple" } */
 
 void
 foo (void)
@@ -13,5 +13,5 @@ foo (void)
    in the loop exit condition, it would be re-introduced during
    GIMPLE lowering, at the cost of an extra statement, label,
    and basic block.  */
-/* { dg-final { scan-tree-dump-times "goto" 3 "useless"} } */ 
-/* { dg-final { cleanup-tree-dump "useless" } } */
+/* { dg-final { scan-tree-dump-times "goto" 3 "gimple"} } */ 
+/* { dg-final { cleanup-tree-dump "gimple" } } */
Index: testsuite/gcc.dg/pr41573.c
===================================================================
--- testsuite/gcc.dg/pr41573.c	(revision 0)
+++ testsuite/gcc.dg/pr41573.c	(revision 0)
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+__inline __attribute__ ((__always_inline__)) char *
+strcpy (char *__dest, __const char *__src)
+{
+  return __builtin___strcpy_chk (__dest, __src, __builtin_object_size (__dest, 2 > 1));
+}
+
+const char* get_attr(unsigned attr)
+{
+    static char tmp[256];
+
+    strcpy(tmp, "");
+    return tmp;
+}

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2010-01-13  3:20 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-10 10:49 Fix PR41573, remove pass_remove_useless_stmts Uros Bizjak
2009-10-11 17:58 ` Michael Matz
  -- strict thread matches above, loose matches on Subject: below --
2009-10-07 13:09 Michael Matz
2009-10-07 13:24 ` Richard Guenther
2009-10-08 15:41   ` Jeff Law
2009-10-08 16:13     ` Michael Matz
2009-10-07 13:34 ` Eric Botcazou
2009-10-07 14:01   ` Michael Matz
2009-10-07 14:34     ` Eric Botcazou
2009-10-07 15:00       ` Michael Matz
2009-10-07 15:16         ` Richard Guenther
2009-10-07 15:33           ` Michael Matz
2010-01-13  3:20 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).