This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n]


On Fri, 15 Aug 2008, Richard Guenther wrote:

> On Fri, 15 Aug 2008, Paolo Bonzini wrote:
> 
> > 
> > > Thus I took the opportunity to rewrite the CFG walk of VRP and
> > > to properly track SSA name liveness for the edges we insert
> > > asserts on.  This removes one of the kludges that disabled
> > > the jump-threading capabilities of VRP in some cases.  With
> > > that change the number of jump-threads performed by VRP go up
> > > a bit which compensates for the DOM removal (now the second DOM
> > > pass catches the leftovers instead).
> > 
> > Great!...
> > 
> > > The patch has not yet been benchmarked (scheduled for tonight) but
> > > it has been bootstrapped and tested on x86_64-unknown-linux-gnu.
> > 
> > ... I know that maybe we'll disagree on this, but I think that when this is
> > committed, the tree-vrp.c should be in a separate revision than the passes.c
> > changes.
> 
> Yes, I'll make sure to commit passes.c changes as separate revs.

The VRP changes cause the loop interchange no longer being performed
on SPEC CPU 2000 swim.  This is because of extra jump-threading by
VRP causing an infinite loop to appear which we insert fake exit
edges for during PRE but after splitting critical edges.  This in
turn makes PRE skip a critical transformation which leads the
interchange code to fail because it no longer can convert the loop
nest into a perfect nest.

The fix is for PRE to rely on critical edge splitting and simply
making sure to remove the fake edges before committing the edge
inserts.

A separate fix that also works would be to move the copy-prop and dce
passes we do after loop discovery to after the loop-invariant-motion
pass.  This also would fix some vectorizer issues where the vectorizer
is confused about extra copies (as is the linear transforms code for 
swim).  But that's for another patch.

Fixing the PRE issue sounds like a good idea anyway as we are
potentially missing some PRE opportunities elsewhere because of this.

So the following is an updated patch.

Bootstrap & regtest still running on x86_64-unknown-linux-gnu.

I plan to install the VRP/PRE parts tomorrow and the passes.c change
a day or two after that.

Thanks,
Richard.

2008-08-19  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (found_in_subgraph): Remove.
	(live): New global static.
	(live_on_edge): New function.
	(blocks_visited): Remove.
	(register_edge_assert_for_2): Use live_on_edge.
	(find_conditional_asserts): Remove code dealing with
	found_in_subgraph.  Do not walk the CFG.
	(find_switch_asserts): Likewise.
	(find_assert_locations_1): Renamed from find_assert_locations.
	Move finding assert locations for conditional and switch
	statements first.  Update live bitmap.  Do not walk the CFG.
	(find_assert_locations): New function.
	(insert_range_assertions): Remove entry of CFG walk.
	Adjust call to find_assert_locations.
	* tree-ssa-pre.c (do_regular_insertion): Ignore critical edges
	that only can appear because of fake exit edges but assert we
	never try to insert on those.
	(fini_pre): Do not remove fake exit edges here...
	(execute_pre): ...but here, before committing edge inserts.

	* gcc.dg/tree-ssa/pr20701.c: Scan vrp1 dump.
	* gcc.dg/tree-ssa/ssa-dom-thread-1.c: Pass -fno-tree-vrp.
	* gcc.dg/tree-ssa/ssa-pre-20.c: New testcase.

	* passes.c (init_optimization_passes): Move the second
	forwprop pass before alias computation.  Remove the second
	DCE pass.  Remove the first dominator and phi copy/const
	prop passes.

	* gcc.dg/tree-ssa/20030530-2.c: Scan dom2 dump.
	* gcc.dg/tree-ssa/20030611-1.c: Likewise.
	* gcc.dg/tree-ssa/20030703-1.c: Likewise.
	* gcc.dg/tree-ssa/20030703-2.c: Likewise.
	* gcc.dg/tree-ssa/20030708-1.c: Likewise.
	* gcc.dg/tree-ssa/20030709-3.c: Likewise.
	* gcc.dg/tree-ssa/20030710-1.c: Likewise.
	* gcc.dg/tree-ssa/20030711-1.c: Likewise.
	* gcc.dg/tree-ssa/20030711-2.c: Likewise.
	* gcc.dg/tree-ssa/20030711-3.c: Likewise.
	* gcc.dg/tree-ssa/20030714-1.c: Likewise.
	* gcc.dg/tree-ssa/20030714-2.c: Likewise.
	* gcc.dg/tree-ssa/20030729-1.c: Likewise.
	* gcc.dg/tree-ssa/20030730-1.c: Likewise.
	* gcc.dg/tree-ssa/20030730-2.c: Likewise.
	* gcc.dg/tree-ssa/20030731-1.c: Likewise.
	* gcc.dg/tree-ssa/20030807-1.c: Likewise.
	* gcc.dg/tree-ssa/20030807-11.c: Likewise.
	* gcc.dg/tree-ssa/20030807-2.c: Likewise.
	* gcc.dg/tree-ssa/20030807-3.c: Likewise.
	* gcc.dg/tree-ssa/20030807-5.c: Likewise.
	* gcc.dg/tree-ssa/20030807-8.c: Likewise.
	* gcc.dg/tree-ssa/20030807-9.c: Likewise.
	* gcc.dg/tree-ssa/20030814-1.c: Likewise.
	* gcc.dg/tree-ssa/20030814-2.c: Likewise.
	* gcc.dg/tree-ssa/20030814-3.c: Likewise.
	* gcc.dg/tree-ssa/20030814-4.c: Likewise.
	* gcc.dg/tree-ssa/20030814-5.c: Likewise.
	* gcc.dg/tree-ssa/20030814-6.c: Likewise.
	* gcc.dg/tree-ssa/20030814-7.c: Likewise.
	* gcc.dg/tree-ssa/20030922-1.c: Likewise.
	* gcc.dg/tree-ssa/20040729-1.c: Likewise.
	* gcc.dg/tree-ssa/20041122-1.c: Likewise.
	* gcc.dg/tree-ssa/pr21417.c: Likewise.
	* gcc.dg/tree-ssa/pr21829.c: Scan phicprop2 dump.
	* gcc.dg/tree-ssa/ssa-dce-1.c: Scan dce2 dump.
	* gcc.dg/tree-ssa/ssa-dce-2.c: Likewise.
	* g++.dg/tree-ssa/pr31146.C: Remove XFAIL, adjust pattern.

Index: trunk/gcc/passes.c
===================================================================
*** trunk.orig/gcc/passes.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/passes.c	2008-08-19 15:19:13.000000000 +0200
*************** init_optimization_passes (void)
*** 589,594 ****
--- 589,595 ----
        NEXT_PASS (pass_rename_ssa_copies);
        NEXT_PASS (pass_complete_unrolli);
        NEXT_PASS (pass_ccp);
+       NEXT_PASS (pass_forwprop);
        /* Ideally the function call conditional
  	 dead code elimination phase can be delayed
  	 till later where potentially more opportunities
*************** init_optimization_passes (void)
*** 605,624 ****
        NEXT_PASS (pass_return_slot);
        NEXT_PASS (pass_phiprop);
        NEXT_PASS (pass_fre);
-       NEXT_PASS (pass_dce);
-       NEXT_PASS (pass_forwprop);
        NEXT_PASS (pass_copy_prop);
        NEXT_PASS (pass_merge_phi);
        NEXT_PASS (pass_vrp);
        NEXT_PASS (pass_dce);
        NEXT_PASS (pass_cselim);
-       NEXT_PASS (pass_dominator);
-       /* The only const/copy propagation opportunities left after
- 	 DOM should be due to degenerate PHI nodes.  So rather than
- 	 run the full propagators, run a specialized pass which
- 	 only examines PHIs to discover const/copy propagation
- 	 opportunities.  */
-       NEXT_PASS (pass_phi_only_cprop);
        NEXT_PASS (pass_tree_ifcombine);
        NEXT_PASS (pass_phiopt);
        NEXT_PASS (pass_tail_recursion);
--- 606,616 ----
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
   
  
  typedef struct rs6000_stack {
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
   
  
  typedef struct rs6000_stack {
*************** rs6000_emit_prologue (int i, rs6000_stac
*** 16,27 ****
  
  /* There should be precisely one load of first_gp_reg_save.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "first_gp_reg_save" 1 "dom3"} } */
  
  /* There should be precisely one addition.  If there is more than one, then
     the dominator optimizations failed, most likely due to not handling
     commutative operands correctly.  */
! /* { dg-final { scan-tree-dump-times "\\+" 1 "dom3"} } */
   
! /* { dg-final { cleanup-tree-dump "dom3" } } */
  
--- 16,27 ----
  
  /* There should be precisely one load of first_gp_reg_save.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "first_gp_reg_save" 1 "dom2"} } */
  
  /* There should be precisely one addition.  If there is more than one, then
     the dominator optimizations failed, most likely due to not handling
     commutative operands correctly.  */
! /* { dg-final { scan-tree-dump-times "\\+" 1 "dom2"} } */
   
! /* { dg-final { cleanup-tree-dump "dom2" } } */
  
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
   
  extern int square (int) __attribute__ ((__const__));
  shit(int a)
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
   
  extern int square (int) __attribute__ ((__const__));
  shit(int a)
*************** shit(int a)
*** 10,14 ****
  
  /* There should be precisely one call to square.   If there is more than one,
     then the dominator optimizations failed to remove the redundant call.  */
! /* { dg-final { scan-tree-dump-times "square" 1 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 10,14 ----
  
  /* There should be precisely one call to square.   If there is more than one,
     then the dominator optimizations failed to remove the redundant call.  */
! /* { dg-final { scan-tree-dump-times "square" 1 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
    
  extern void abort (void);
  extern int blah[];
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
    
  extern void abort (void);
  extern int blah[];
*************** foo(int index)
*** 14,22 ****
  
  /* There should be precisely one load of blah.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "blah" 1 "dom3"} } */
   
  /* There should be exactly one IF conditional.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 14,22 ----
  
  /* There should be precisely one load of blah.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "blah" 1 "dom2"} } */
   
  /* There should be exactly one IF conditional.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  
*************** get_alias_set (t)
*** 29,44 ****
  
  /* There should be precisely one load of {t,__t}->code.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "->code" 1 "dom3"} } */
                                                                                  
  /* There should be precisely one load of tree_code_type.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "tree_code_type" 1 "dom3"} } */
  
  /* There should be one IF conditional.  If 'tree_code_type[t->code]' is
     zero, then the third if() conditional is unnecessary.  That should cause
     the call to abort() to be removed, which in turn causes the whole second
     if() to disappear.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 29,44 ----
  
  /* There should be precisely one load of {t,__t}->code.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "->code" 1 "dom2"} } */
                                                                                  
  /* There should be precisely one load of tree_code_type.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "tree_code_type" 1 "dom2"} } */
  
  /* There should be one IF conditional.  If 'tree_code_type[t->code]' is
     zero, then the third if() conditional is unnecessary.  That should cause
     the call to abort() to be removed, which in turn causes the whole second
     if() to disappear.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  extern void abort (void);
  struct rtx_def;
  typedef struct rtx_def *rtx;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  extern void abort (void);
  struct rtx_def;
  typedef struct rtx_def *rtx;
*************** nonlocal_mentioned_p (x)
*** 35,43 ****
  
  /* There should be no casts to a short unsigned int since the entire
     set of conditionals should optimize away.  */
! /* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */
                                                                                  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
                                                                                  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 35,43 ----
  
  /* There should be no casts to a short unsigned int since the entire
     set of conditionals should optimize away.  */
! /* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom2"} } */
                                                                                  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2"} } */
                                                                                  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
    
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
    
  extern void abort (void);
  
*************** record_component_aliases (type)
*** 36,48 ****
  
  /* There should be precisely one load of type.binfo.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom3"} } */
   
  /* There should be precisely one load of common.code.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "common\\.code" 1 "dom3"} } */
   
  /* There should be one IF conditional.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 36,48 ----
  
  /* There should be precisely one load of type.binfo.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom2"} } */
   
  /* There should be precisely one load of common.code.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "common\\.code" 1 "dom2"} } */
   
  /* There should be one IF conditional.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  union tree_node;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  union tree_node;
*************** record_component_aliases (type)
*** 41,55 ****
  /* The call to blah should have been eliminated.  If the call is not
     eliminated, then dominator optimizations failed and it'll be
     impossible to delete other unnecessary code.  */
! /* { dg-final { scan-tree-dump-not "blah \\(\\)" "dom3" } } */
    
  /* There should be two IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
                                                                                  
  /* There should be a single load of type.binfo.  */
! /* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom3"} } */
  
  /* There should be two loads of vec.length.  */
! /* { dg-final { scan-tree-dump-times "vec.length" 2 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 41,55 ----
  /* The call to blah should have been eliminated.  If the call is not
     eliminated, then dominator optimizations failed and it'll be
     impossible to delete other unnecessary code.  */
! /* { dg-final { scan-tree-dump-not "blah \\(\\)" "dom2" } } */
    
  /* There should be two IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom2"} } */
                                                                                  
  /* There should be a single load of type.binfo.  */
! /* { dg-final { scan-tree-dump-times "type\\.binfo" 1 "dom2"} } */
  
  /* There should be two loads of vec.length.  */
! /* { dg-final { scan-tree-dump-times "vec.length" 2 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
   
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
   
  extern void abort (void);
  
*************** record_component_aliases (type)
*** 41,55 ****
  }
  
  /* The call to blah can not be eliminated.  */
! /* { dg-final { scan-tree-dump-times "blah \\(\\)" 1 "dom3" } } */
     
  /* There should be four IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */
                                                                                  
  /* There should be two loads of type.binfo.  */
! /* { dg-final { scan-tree-dump-times "type\\.binfo" 2 "dom3"} } */
   
  /* There should be four loads of vec.length.  */
! /* { dg-final { scan-tree-dump-times "vec.length" 3 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 41,55 ----
  }
  
  /* The call to blah can not be eliminated.  */
! /* { dg-final { scan-tree-dump-times "blah \\(\\)" 1 "dom2" } } */
     
  /* There should be four IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 4 "dom2"} } */
                                                                                  
  /* There should be two loads of type.binfo.  */
! /* { dg-final { scan-tree-dump-times "type\\.binfo" 2 "dom2"} } */
   
  /* There should be four loads of vec.length.  */
! /* { dg-final { scan-tree-dump-times "vec.length" 4 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom3" } */
    
  
  struct rtx_def;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom2" } */
    
  
  struct rtx_def;
*************** get_alias_set (t,z)
*** 49,69 ****
  }
  
  /* The calls to make_decl_rtl should be eliminated
! /* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom3" } } */
      
  /* There should be three IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */
                                                                                  
  /* There should be one loads of decl.rtl.  */
! /* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom3"} } */
    
  /* There should be one load of code.  */
! /* { dg-final { scan-tree-dump-times "code" 1 "dom3"} } */
  
  /* There should be one load of rtmem.  */
! /* { dg-final { scan-tree-dump-times "rtmem" 1 "dom3"} } */
  
  /* There should be one load of alias.  */
! /* { dg-final { scan-tree-dump-times "->alias" 1 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 49,69 ----
  }
  
  /* The calls to make_decl_rtl should be eliminated
! /* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom2" } } */
      
  /* There should be three IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom2"} } */
                                                                                  
  /* There should be one loads of decl.rtl.  */
! /* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom2"} } */
    
  /* There should be one load of code.  */
! /* { dg-final { scan-tree-dump-times "code" 1 "dom2"} } */
  
  /* There should be one load of rtmem.  */
! /* { dg-final { scan-tree-dump-times "rtmem" 1 "dom2"} } */
  
  /* There should be one load of alias.  */
! /* { dg-final { scan-tree-dump-times "->alias" 1 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
    
  
  struct rtx_def;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
    
  
  struct rtx_def;
*************** get_alias_set (t)
*** 44,61 ****
  }
  
  /* The calls to make_decl_rtl should be eliminated.  */
! /* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom3" } } */
      
  /* There should be two IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
                                                                                  
  /* There should be one load of decl.rtl.  */
! /* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom3"} } */
    
  /* There should be two loads of rtmem.  */
! /* { dg-final { scan-tree-dump-times "rtmem" 2 "dom3"} } */
  
  /* There should be one load of alias.  */
! /* { dg-final { scan-tree-dump-times "->alias" 1 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 44,61 ----
  }
  
  /* The calls to make_decl_rtl should be eliminated.  */
! /* { dg-final { scan-tree-dump-not "make_decl_rtl \\(\\)" "dom2" } } */
      
  /* There should be two IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom2"} } */
                                                                                  
  /* There should be one load of decl.rtl.  */
! /* { dg-final { scan-tree-dump-times "decl\\.rtl" 1 "dom2"} } */
    
  /* There should be two loads of rtmem.  */
! /* { dg-final { scan-tree-dump-times "rtmem" 2 "dom2"} } */
  
  /* There should be one load of alias.  */
! /* { dg-final { scan-tree-dump-times "->alias" 1 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
     
  struct rtx_def;
  typedef struct rtx_def *rtx;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
     
  struct rtx_def;
  typedef struct rtx_def *rtx;
*************** find_base_value (src)
*** 35,40 ****
  
  
  /* There should be no casts to short unsigned int.  */
! /* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 35,40 ----
  
  
  /* There should be no casts to short unsigned int.  */
! /* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
     
  
  union tree_node;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
     
  
  union tree_node;
*************** get_alias_set (t)
*** 34,39 ****
  
  /* There should be exactly three IF conditionals if we thread jumps
     properly.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */
   
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 34,39 ----
  
  /* There should be exactly three IF conditionals if we thread jumps
     properly.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom2"} } */
   
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  union tree_node;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  union tree_node;
*************** readonly_fields_p (type)
*** 45,54 ****
  /* A good optimizer would realize that the cast to (unsigned int) is
     useless as the earlier cast of the same value of (unsigned char) will
     always produce the same result.  */
! /* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 0 "dom3"} } */
   
  /* There should be one load of ->common.code.  We currently fail this
     because we load from ->common.code using different types.  */
! /* { dg-final { scan-tree-dump-times "common\.code" 1 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 45,54 ----
  /* A good optimizer would realize that the cast to (unsigned int) is
     useless as the earlier cast of the same value of (unsigned char) will
     always produce the same result.  */
! /* { dg-final { scan-tree-dump-times "\\(unsigned int\\)" 0 "dom2"} } */
   
  /* There should be one load of ->common.code.  We currently fail this
     because we load from ->common.code using different types.  */
! /* { dg-final { scan-tree-dump-times "common\.code" 1 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom3" } */
       
  extern void exit (int);
  extern void *ggc_alloc (__SIZE_TYPE__);
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom2" } */
       
  extern void exit (int);
  extern void *ggc_alloc (__SIZE_TYPE__);
*************** foo (int attr_kind, unsigned long offset
*** 19,25 ****
  }
  
  /* There should be no IF conditionals, unless target has fno-delete-null-pointer-checks  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3" { target { ! keeps_null_pointer_checks } } } } */
! /* { dg-final { scan-tree-dump "if " "dom3" { target { keeps_null_pointer_checks } } } } */
       
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 19,25 ----
  }
  
  /* There should be no IF conditionals, unless target has fno-delete-null-pointer-checks  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2" { target { ! keeps_null_pointer_checks } } } } */
! /* { dg-final { scan-tree-dump "if " "dom2" { target { keeps_null_pointer_checks } } } } */
       
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom3" } */
       
  extern void exit (int);
  extern void *ggc_alloc (__SIZE_TYPE__);
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom2" } */
       
  extern void exit (int);
  extern void *ggc_alloc (__SIZE_TYPE__);
*************** foo (int attr_kind, unsigned long offset
*** 19,25 ****
  }
  
  /* There should be no IF conditionals, unless target has fno-delete-null-pointer-checks  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3" { target { ! keeps_null_pointer_checks } } } } */
! /* { dg-final { scan-tree-dump "if " "dom3" { target { keeps_null_pointer_checks } } } } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 19,25 ----
  }
  
  /* There should be no IF conditionals, unless target has fno-delete-null-pointer-checks  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2" { target { ! keeps_null_pointer_checks } } } } */
! /* { dg-final { scan-tree-dump "if " "dom2" { target { keeps_null_pointer_checks } } } } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
    
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
    
  extern void abort (void);
  
*************** store_expr (exp, target, want_value)
*** 63,67 ****
     (B) only looks at immediate dominators, and only queued_subexp_p
     immediately dominates the comparison in question.  We need something
     stronger.  */
! /* { dg-final { scan-tree-dump-times "target.*!= 0" 0 "dom3" { xfail *-*-* } } } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 63,67 ----
     (B) only looks at immediate dominators, and only queued_subexp_p
     immediately dominates the comparison in question.  We need something
     stronger.  */
! /* { dg-final { scan-tree-dump-times "target.*!= 0" 0 "dom2" { xfail *-*-* } } } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
      
  struct rtx_def;
  typedef struct rtx_def *rtx;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
      
  struct rtx_def;
  typedef struct rtx_def *rtx;
*************** bar (rtx r)
*** 41,45 ****
     are threaded to the return 0.  Which in turn means the path
     which combines the result of those two tests into a new test
     must always be true and it is optimized appropriately.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 41,45 ----
     are threaded to the return 0.  Which in turn means the path
     which combines the result of those two tests into a new test
     must always be true and it is optimized appropriately.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  struct rtx_def;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  struct rtx_def;
*************** foo (reg)
*** 17,21 ****
  }
                                                                                  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 17,21 ----
  }
                                                                                  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -ftree-vrp -fdump-tree-dom3" } */
       
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -ftree-vrp -fdump-tree-dom2" } */
       
  extern void abort (void);
  
*************** foo(int n)
*** 24,28 ****
  
                                                                                 
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3" } } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 24,28 ----
  
                                                                                 
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2" } } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
                                                                                  
  typedef unsigned int cppchar_t;
  cppchar_t
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
                                                                                  
  typedef unsigned int cppchar_t;
  cppchar_t
*************** cpp_parse_escape (pstr, limit, wide)
*** 23,27 ****
  
  /* There should be precisely three IF statements.  If there is
     more than two, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 23,27 ----
  
  /* There should be precisely three IF statements.  If there is
     more than two, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "if " 3 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  struct rtx_def;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  struct rtx_def;
*************** foo ()
*** 30,39 ****
  
  /* There should be precisely one load of ->code.  If there is
     more than, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "->code" 1 "dom3"} } */
  
  /* There should be two IF statements.  One for 'current_sym_addr->code == 42'.
     The other one for '(EXPR)->unchanging'.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom3"} } */
  
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 30,39 ----
  
  /* There should be precisely one load of ->code.  If there is
     more than, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "->code" 1 "dom2"} } */
  
  /* There should be two IF statements.  One for 'current_sym_addr->code == 42'.
     The other one for '(EXPR)->unchanging'.  */
! /* { dg-final { scan-tree-dump-times "if " 2 "dom2"} } */
  
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
                                                                                  
  struct die_struct;
  typedef struct die_struct *dw_die_ref;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
                                                                                  
  struct die_struct;
  typedef struct die_struct *dw_die_ref;
*************** output_location_lists (die)
*** 51,55 ****
  }
  
  /* There should be exactly one IF conditional, in output_location_lists.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 51,55 ----
  }
  
  /* There should be exactly one IF conditional, in output_location_lists.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  static void
  bar ()
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  static void
  bar ()
*************** ooof ()
*** 16,20 ****
  }
  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 16,20 ----
  }
  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
     
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
     
  extern void abort (void);
  
*************** com(int *blah)
*** 16,21 ****
  
  /* There should be precisely one load of blah.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "\\*blah" 1 "dom3"} } */
    
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 16,21 ----
  
  /* There should be precisely one load of blah.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "\\*blah" 1 "dom2"} } */
    
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
      
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
      
  extern void abort (void);
  
*************** foo (int value)
*** 17,22 ****
  }
  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
   
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 17,22 ----
  }
  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2"} } */
   
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
      
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
      
  extern void abort (void);
  
*************** foo (int value)
*** 18,23 ****
  }
  
  /* There should be one IF conditional.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom3"} } */
   
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 18,23 ----
  }
  
  /* There should be one IF conditional.  */
! /* { dg-final { scan-tree-dump-times "if " 1 "dom2"} } */
   
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3 -fdump-tree-optimized" } */
      
  extern void abort (void);
  union tree_node;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2 -fdump-tree-optimized" } */
      
  extern void abort (void);
  union tree_node;
*************** blah (decl, set)
*** 34,41 ****
  
  /* There should be precisely one reference to pointer_alias_set.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
  
  /* The assignment set = -1 in the ELSE clause of the last IF
     statement should be removed by the final cleanup phase.  */
--- 34,41 ----
  
  /* There should be precisely one reference to pointer_alias_set.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
  
  /* The assignment set = -1 in the ELSE clause of the last IF
     statement should be removed by the final cleanup phase.  */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3 -fdump-tree-optimized" } */
      
  extern void abort (void);
  union tree_node;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2 -fdump-tree-optimized" } */
      
  extern void abort (void);
  union tree_node;
*************** blah (decl, set)
*** 34,41 ****
  
  /* There should be precisely one reference to pointer_alias_set.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
  
  /* The assignment set = -1 in the ELSE clause of the last IF
     statement should be removed by the final cleanup phase.  */
--- 34,41 ----
  
  /* There should be precisely one reference to pointer_alias_set.  If there is
     more than one, then the dominator optimizations failed.  */
! /* { dg-final { scan-tree-dump-times "pointer_alias_set" 1 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
  
  /* The assignment set = -1 in the ELSE clause of the last IF
     statement should be removed by the final cleanup phase.  */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  union tree_node;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  union tree_node;
*************** foo (t, set)
*** 41,45 ****
     more than one, then the dominator optimizations failed.  */
  /* ??? Will fail until we properly distinguish member stores.  At
     present the write to type.alias_set kills the previous load.  */
! /* { dg-final { scan-tree-dump-times "common.code" 1 "dom3" { xfail *-*-* } } } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 41,45 ----
     more than one, then the dominator optimizations failed.  */
  /* ??? Will fail until we properly distinguish member stores.  At
     present the write to type.alias_set kills the previous load.  */
! /* { dg-final { scan-tree-dump-times "common.code" 1 "dom2" { xfail *-*-* } } } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  extern void abort (void);
  struct rtx_def;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  extern void abort (void);
  struct rtx_def;
*************** mark_constant_function (void)
*** 38,42 ****
     and the temporary used as the argument to cgraph_rtl_info.
     This if we find current_function_decl used as an argument, then
     we have failed.  */
! /* { dg-final { scan-tree-dump-times "\\(current_function_decl\\)" 0 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 38,42 ----
     and the temporary used as the argument to cgraph_rtl_info.
     This if we find current_function_decl used as an argument, then
     we have failed.  */
! /* { dg-final { scan-tree-dump-times "\\(current_function_decl\\)" 0 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
    
  extern void abort (void);
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
    
  extern void abort (void);
  
*************** voidify_wrapper_expr (tree wrapper)
*** 30,34 ****
  
  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom3"} } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 30,34 ----
  
  
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dom2"} } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20040729-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20040729-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20040729-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dce3" } */
  
  foo ()
  {
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dce2" } */
  
  foo ()
  {
*************** foo ()
*** 15,19 ****
     compiler was mistakenly thinking that the statement had volatile
     operands.  But 'p' itself is not volatile and taking the address of
     a volatile does not constitute a volatile operand.  */
! /* { dg-final { scan-tree-dump-times "&x" 0 "dce3"} } */
! /* { dg-final { cleanup-tree-dump "dce3" } } */
--- 15,19 ----
     compiler was mistakenly thinking that the statement had volatile
     operands.  But 'p' itself is not volatile and taking the address of
     a volatile does not constitute a volatile operand.  */
! /* { dg-final { scan-tree-dump-times "&x" 0 "dce2"} } */
! /* { dg-final { cleanup-tree-dump "dce2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom3" } */
  
  
  typedef unsigned int size_t;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dom2" } */
  
  
  typedef unsigned int size_t;
*************** find_unreachable_blocks (int frobit)
*** 34,38 ****
     able to determine that modifying e->dest->flags does not
     modify e or e->dest.  The net result is that we only need one
     load of e->dest.  */
! /* { dg-final { scan-tree-dump-times "->dest" 1 "dom3" { xfail *-*-* } } } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
--- 34,38 ----
     able to determine that modifying e->dest->flags does not
     modify e or e->dest.  The net result is that we only need one
     load of e->dest.  */
! /* { dg-final { scan-tree-dump-times "->dest" 1 "dom2" { xfail *-*-* } } } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp2 -fno-early-inlining" } */
  
  typedef struct {
    int code;
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1 -fno-early-inlining" } */
  
  typedef struct {
    int code;
*************** can_combine_p (rtx insn, rtx elt)
*** 36,41 ****
  }
  
  /* Target with fno-delete-null-pointer-checks should not fold checks */
! /* { dg-final { scan-tree-dump-times "Folding predicate.*to 0" 1 "vrp2" { target { ! keeps_null_pointer_checks } } } } */
! /* { dg-final { scan-tree-dump-times "Folding predicate.*to 0" 0 "vrp2" { target {   keeps_null_pointer_checks } } } } */
! /* { dg-final { cleanup-tree-dump "vrp2" } } */
--- 36,41 ----
  }
  
  /* Target with fno-delete-null-pointer-checks should not fold checks */
! /* { dg-final { scan-tree-dump-times "Folding predicate.*to 0" 1 "vrp1" { target { ! keeps_null_pointer_checks } } } } */
! /* { dg-final { scan-tree-dump-times "Folding predicate.*to 0" 0 "vrp1" { target {   keeps_null_pointer_checks } } } } */
! /* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom3-details" } */
  
  struct tree_common 
  { 
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dom2-details" } */
  
  struct tree_common 
  { 
*************** L23:
*** 49,54 ****
  /* We should thread the backedge to the top of the loop; ie we only
     execute the if (expr->common.code != 142) test once per loop
     iteration.  */
! /* { dg-final { scan-tree-dump-times "Threaded jump" 1 "dom3" } } */
! /* { dg-final { cleanup-tree-dump "dom3" } } */
  
--- 49,54 ----
  /* We should thread the backedge to the top of the loop; ie we only
     execute the if (expr->common.code != 142) test once per loop
     iteration.  */
! /* { dg-final { scan-tree-dump-times "Threaded jump" 1 "dom2" } } */
! /* { dg-final { cleanup-tree-dump "dom2" } } */
  
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21829.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr21829.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21829.c	2008-08-19 15:19:13.000000000 +0200
*************** int test(int v)
*** 16,21 ****
    return x;
  }
  
! /* { dg-final { scan-tree-dump-times "Original statement:.*% 2\[ \t\n]*Updated statement.*=1" 0 "phicprop3" } } */
! /* { dg-final { cleanup-tree-dump "phicprop\[1-3\]" } } */
  
--- 16,21 ----
    return x;
  }
  
! /* { dg-final { scan-tree-dump-times "Original statement:.*% 2\[ \t\n]*Updated statement.*=1" 0 "phicprop2" } } */
! /* { dg-final { cleanup-tree-dump "phicprop\[1-2\]" } } */
  
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dce3" } */
  
  int t() __attribute__ ((const));
  q()
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O1 -fdump-tree-dce2" } */
  
  int t() __attribute__ ((const));
  q()
*************** q()
*** 9,13 ****
      i = t();
  }
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dce3"} } */
! /* { dg-final { cleanup-tree-dump "dce3" } } */
--- 9,13 ----
      i = t();
  }
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dce2"} } */
! /* { dg-final { cleanup-tree-dump "dce2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dce3" } */
  
  /* We should notice constantness of this function. */
  static int __attribute__((noinline)) t(int a) 
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-dce2" } */
  
  /* We should notice constantness of this function. */
  static int __attribute__((noinline)) t(int a) 
*************** void q(void)
*** 13,17 ****
      i = t(1);
  }
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dce3"} } */
! /* { dg-final { cleanup-tree-dump "dce3" } } */
--- 13,17 ----
      i = t(1);
  }
  /* There should be no IF conditionals.  */
! /* { dg-final { scan-tree-dump-times "if " 0 "dce2"} } */
! /* { dg-final { cleanup-tree-dump "dce2" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c	2008-08-19 15:19:13.000000000 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */ 
! /* { dg-options "-O2 -fdump-tree-dom1-details" } */
  void t(void);
  void q(void);
  void q1(void);
--- 1,5 ----
  /* { dg-do compile } */ 
! /* { dg-options "-O2 -fno-tree-vrp -fdump-tree-dom1-details" } */
  void t(void);
  void q(void);
  void q1(void);
Index: trunk/gcc/tree-vrp.c
===================================================================
*** trunk.orig/gcc/tree-vrp.c	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/tree-vrp.c	2008-08-19 15:19:13.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 39,47 ****
  #include "tree-chrec.h"
  
  
! /* Set of SSA names found during the dominator traversal of a
!    sub-graph in find_assert_locations.  */
! static sbitmap found_in_subgraph;
  
  /* Local functions.  */
  static int compare_values (tree val1, tree val2);
--- 39,56 ----
  #include "tree-chrec.h"
  
  
! /* Set of SSA names found live during the RPO traversal of the function
!    for still active basic-blocks.  */
! static sbitmap *live;
! 
! /* Return true if the SSA name NAME is live on the edge E.  */
! 
! static bool
! live_on_edge (edge e, tree name)
! {
!   return (live[e->dest->index]
! 	  && TEST_BIT (live[e->dest->index], SSA_NAME_VERSION (name)));
! }
  
  /* Local functions.  */
  static int compare_values (tree val1, tree val2);
*************** static bitmap need_assert_for;
*** 91,100 ****
     ASSERT_EXPRs for SSA name N_I should be inserted.  */
  static assert_locus_t *asserts_for;
  
- /* Set of blocks visited in find_assert_locations.  Used to avoid
-    visiting the same block more than once.  */
- static sbitmap blocks_visited;
- 
  /* Value range array.  After propagation, VR_VALUE[I] holds the range
     of values that SSA name N_I may take.  */
  static value_range_t **vr_value;
--- 100,105 ----
*************** register_edge_assert_for_2 (tree name, e
*** 3910,3916 ****
  
    /* Only register an ASSERT_EXPR if NAME was found in the sub-graph
       reachable from E.  */
!   if (TEST_BIT (found_in_subgraph, SSA_NAME_VERSION (name))
        && !has_single_use (name))
      {
        register_new_assert_for (name, name, comp_code, val, NULL, e, bsi);
--- 3915,3921 ----
  
    /* Only register an ASSERT_EXPR if NAME was found in the sub-graph
       reachable from E.  */
!   if (live_on_edge (e, name)
        && !has_single_use (name))
      {
        register_new_assert_for (name, name, comp_code, val, NULL, e, bsi);
*************** register_edge_assert_for_2 (tree name, e
*** 3956,3962 ****
  	  && (cst2 == NULL_TREE
  	      || TREE_CODE (cst2) == INTEGER_CST)
  	  && INTEGRAL_TYPE_P (TREE_TYPE (name3))
! 	  && TEST_BIT (found_in_subgraph, SSA_NAME_VERSION (name3))
  	  && !has_single_use (name3))
  	{
  	  tree tmp;
--- 3961,3967 ----
  	  && (cst2 == NULL_TREE
  	      || TREE_CODE (cst2) == INTEGER_CST)
  	  && INTEGRAL_TYPE_P (TREE_TYPE (name3))
! 	  && live_on_edge (e, name3)
  	  && !has_single_use (name3))
  	{
  	  tree tmp;
*************** register_edge_assert_for_2 (tree name, e
*** 3985,3991 ****
        	  && TREE_CODE (name2) == SSA_NAME
  	  && TREE_CODE (cst2) == INTEGER_CST
  	  && INTEGRAL_TYPE_P (TREE_TYPE (name2))
! 	  && TEST_BIT (found_in_subgraph, SSA_NAME_VERSION (name2))
  	  && !has_single_use (name2))
  	{
  	  tree tmp;
--- 3990,3996 ----
        	  && TREE_CODE (name2) == SSA_NAME
  	  && TREE_CODE (cst2) == INTEGER_CST
  	  && INTEGRAL_TYPE_P (TREE_TYPE (name2))
! 	  && live_on_edge (e, name2)
  	  && !has_single_use (name2))
  	{
  	  tree tmp;
*************** register_edge_assert_for (tree name, edg
*** 4185,4192 ****
  }
  
  
- static bool find_assert_locations (basic_block bb);
- 
  /* Determine whether the outgoing edges of BB should receive an
     ASSERT_EXPR for each of the operands of BB's LAST statement.
     The last statement of BB must be a COND_EXPR.
--- 4190,4195 ----
*************** find_conditional_asserts (basic_block bb
*** 4217,4251 ****
        if (e->dest == bb)
  	continue;
  
-       /* Remove the COND_EXPR operands from the FOUND_IN_SUBGRAPH bitmap.
- 	 Otherwise, when we finish traversing each of the sub-graphs, we
- 	 won't know whether the variables were found in the sub-graphs or
- 	 if they had been found in a block upstream from BB. 
- 
- 	 This is actually a bad idea is some cases, particularly jump
- 	 threading.  Consider a CFG like the following:
- 
-                     0
-                    /|
-                   1 |
-                    \|
-                     2
-                    / \
-                   3   4
- 
- 	 Assume that one or more operands in the conditional at the
- 	 end of block 0 are used in a conditional in block 2, but not
- 	 anywhere in block 1.  In this case we will not insert any
- 	 assert statements in block 1, which may cause us to miss
- 	 opportunities to optimize, particularly for jump threading.  */
-       FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
- 	RESET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
- 
-       /* Traverse the strictly dominated sub-graph rooted at E->DEST
- 	 to determine if any of the operands in the conditional
- 	 predicate are used.  */
-       need_assert |= find_assert_locations (e->dest);
- 
        /* Register the necessary assertions for each operand in the
  	 conditional predicate.  */
        FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
--- 4220,4225 ----
*************** find_conditional_asserts (basic_block bb
*** 4257,4267 ****
  	}
      }
  
-   /* Finally, indicate that we have found the operands in the
-      conditional.  */
-   FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
-     SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
- 
    return need_assert;
  }
  
--- 4231,4236 ----
*************** find_switch_asserts (basic_block bb, gim
*** 4358,4375 ****
        /* Find the edge to register the assert expr on.  */
        e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
  
-       /* Remove the SWITCH_EXPR operand from the FOUND_IN_SUBGRAPH bitmap.
- 	 Otherwise, when we finish traversing each of the sub-graphs, we
- 	 won't know whether the variables were found in the sub-graphs or
- 	 if they had been found in a block upstream from BB.  */
-       RESET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
- 
-       /* Traverse the strictly dominated sub-graph rooted at E->DEST
- 	 to determine if any of the operands in the conditional
- 	 predicate are used.  */
-       if (e->dest != bb)
- 	need_assert |= find_assert_locations (e->dest);
- 
        /* Register the necessary assertions for the operand in the
  	 SWITCH_EXPR.  */
        need_assert |= register_edge_assert_for (op, e, bsi,
--- 4327,4332 ----
*************** find_switch_asserts (basic_block bb, gim
*** 4386,4395 ****
  	}
      }
  
-   /* Finally, indicate that we have found the operand in the
-      SWITCH_EXPR.  */
-   SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
- 
    return need_assert;
  }
  
--- 4343,4348 ----
*************** find_switch_asserts (basic_block bb, gim
*** 4458,4499 ****
     inserted by process_assert_insertions.  */
  
  static bool
! find_assert_locations (basic_block bb)
  {
    gimple_stmt_iterator si;
    gimple last;
    gimple phi;
    bool need_assert;
-   basic_block son;
- 
-   if (TEST_BIT (blocks_visited, bb->index))
-     return false;
- 
-   SET_BIT (blocks_visited, bb->index);
  
    need_assert = false;
  
!   /* Traverse all PHI nodes in BB marking used operands.  */
!   for (si = gsi_start_phis (bb); !gsi_end_p(si); gsi_next (&si))
!     {
!       use_operand_p arg_p;
!       ssa_op_iter i;
!       phi = gsi_stmt (si);
  
!       FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
! 	{
! 	  tree arg = USE_FROM_PTR (arg_p);
! 	  if (TREE_CODE (arg) == SSA_NAME)
! 	    {
! 	      gcc_assert (is_gimple_reg (PHI_RESULT (phi)));
! 	      SET_BIT (found_in_subgraph, SSA_NAME_VERSION (arg));
! 	    }
! 	}
!     }
  
    /* Traverse all the statements in BB marking used names and looking
       for statements that may infer assertions for their used operands.  */
-   last = NULL;
    for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
      {
        gimple stmt;
--- 4411,4443 ----
     inserted by process_assert_insertions.  */
  
  static bool
! find_assert_locations_1 (basic_block bb, sbitmap live)
  {
    gimple_stmt_iterator si;
    gimple last;
    gimple phi;
    bool need_assert;
  
    need_assert = false;
+   last = last_stmt (bb);
  
!   /* If BB's last statement is a conditional statement involving integer
!      operands, determine if we need to add ASSERT_EXPRs.  */
!   if (last
!       && gimple_code (last) == GIMPLE_COND
!       && !fp_predicate (last)
!       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
!     need_assert |= find_conditional_asserts (bb, last);
  
!   /* If BB's last statement is a switch statement involving integer
!      operands, determine if we need to add ASSERT_EXPRs.  */
!   if (last
!       && gimple_code (last) == GIMPLE_SWITCH
!       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
!     need_assert |= find_switch_asserts (bb, last);
  
    /* Traverse all the statements in BB marking used names and looking
       for statements that may infer assertions for their used operands.  */
    for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
      {
        gimple stmt;
*************** find_assert_locations (basic_block bb)
*** 4508,4519 ****
  	  tree value;
  	  enum tree_code comp_code;
  
! 	  /* Mark OP in bitmap FOUND_IN_SUBGRAPH.  If STMT is inside
! 	     the sub-graph of a conditional block, when we return from
! 	     this recursive walk, our parent will use the
! 	     FOUND_IN_SUBGRAPH bitset to determine if one of the
! 	     operands it was looking for was present in the sub-graph.  */
! 	  SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
  
  	  /* If OP is used in such a way that we can infer a value
  	     range for it, and we don't find a previous assertion for
--- 4452,4459 ----
  	  tree value;
  	  enum tree_code comp_code;
  
! 	  /* Mark OP in our live bitmap.  */
! 	  SET_BIT (live, SSA_NAME_VERSION (op));
  
  	  /* If OP is used in such a way that we can infer a value
  	     range for it, and we don't find a previous assertion for
*************** find_assert_locations (basic_block bb)
*** 4564,4597 ****
  		}
  	    }
  	}
- 
-       /* Remember the last statement of the block.  */
-       last = stmt;
      }
  
!   /* If BB's last statement is a conditional expression
!      involving integer operands, recurse into each of the sub-graphs
!      rooted at BB to determine if we need to add ASSERT_EXPRs.  */
!   if (last
!       && gimple_code (last) == GIMPLE_COND
!       && !fp_predicate (last)
!       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
!     need_assert |= find_conditional_asserts (bb, last);
! 
!   if (last
!       && gimple_code (last) == GIMPLE_SWITCH
!       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
!     need_assert |= find_switch_asserts (bb, last);
  
!   /* Recurse into the dominator children of BB.  */
!   for (son = first_dom_son (CDI_DOMINATORS, bb);
!        son;
!        son = next_dom_son (CDI_DOMINATORS, son))
!     need_assert |= find_assert_locations (son);
  
    return need_assert;
  }
  
  
  /* Create an ASSERT_EXPR for NAME and insert it in the location
     indicated by LOC.  Return true if we made any edge insertions.  */
--- 4504,4616 ----
  		}
  	    }
  	}
      }
  
!   /* Traverse all PHI nodes in BB marking used operands.  */
!   for (si = gsi_start_phis (bb); !gsi_end_p(si); gsi_next (&si))
!     {
!       use_operand_p arg_p;
!       ssa_op_iter i;
!       phi = gsi_stmt (si);
  
!       FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
! 	{
! 	  tree arg = USE_FROM_PTR (arg_p);
! 	  if (TREE_CODE (arg) == SSA_NAME)
! 	    SET_BIT (live, SSA_NAME_VERSION (arg));
! 	}
!     }
  
    return need_assert;
  }
  
+ /* Do an RPO walk over the function computing SSA name liveness
+    on-the-fly and deciding on assert expressions to insert.
+    Returns true if there are assert expressions to be inserted.  */
+ 
+ static bool
+ find_assert_locations (void)
+ {
+   int *rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
+   int *bb_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
+   int *last_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
+   int rpo_cnt, i;
+   bool need_asserts;
+ 
+   live = XCNEWVEC (sbitmap, last_basic_block + NUM_FIXED_BLOCKS);
+   rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false);
+   for (i = 0; i < rpo_cnt; ++i)
+     bb_rpo[rpo[i]] = i;
+ 
+   need_asserts = false;
+   for (i = rpo_cnt-1; i >= 0; --i)
+     {
+       basic_block bb = BASIC_BLOCK (rpo[i]);
+       edge e;
+       edge_iterator ei;
+ 
+       if (!live[rpo[i]])
+ 	{
+ 	  live[rpo[i]] = sbitmap_alloc (num_ssa_names);
+ 	  sbitmap_zero (live[rpo[i]]);
+ 	}
+ 
+       /* Process BB and update the live information with uses in
+          this block.  */
+       need_asserts |= find_assert_locations_1 (bb, live[rpo[i]]);
+ 
+       /* Merge liveness into the predecessor blocks and free it.  */
+       if (!sbitmap_empty_p (live[rpo[i]]))
+ 	{
+ 	  int pred_rpo = i;
+ 	  FOR_EACH_EDGE (e, ei, bb->preds)
+ 	    {
+ 	      int pred = e->src->index;
+ 	      if (e->flags & EDGE_DFS_BACK)
+ 		continue;
+ 
+ 	      if (!live[pred])
+ 		{
+ 		  live[pred] = sbitmap_alloc (num_ssa_names);
+ 		  sbitmap_zero (live[pred]);
+ 		}
+ 	      sbitmap_a_or_b (live[pred], live[pred], live[rpo[i]]);
+ 
+ 	      if (bb_rpo[pred] < pred_rpo)
+ 		pred_rpo = bb_rpo[pred];
+ 	    }
+ 
+ 	  /* Record the RPO number of the last visited block that needs
+ 	     live information from this block.  */
+ 	  last_rpo[rpo[i]] = pred_rpo;
+ 	}
+       else
+ 	{
+ 	  sbitmap_free (live[rpo[i]]);
+ 	  live[rpo[i]] = NULL;
+ 	}
+ 
+       /* We can free all successors live bitmaps if all their
+          predecessors have been visited already.  */
+       FOR_EACH_EDGE (e, ei, bb->succs)
+ 	if (last_rpo[e->dest->index] == i
+ 	    && live[e->dest->index])
+ 	  {
+ 	    sbitmap_free (live[e->dest->index]);
+ 	    live[e->dest->index] = NULL;
+ 	  }
+     }
+ 
+   XDELETEVEC (rpo);
+   XDELETEVEC (bb_rpo);
+   XDELETEVEC (last_rpo);
+   for (i = 0; i < last_basic_block + NUM_FIXED_BLOCKS; ++i)
+     if (live[i])
+       sbitmap_free (live[i]);
+   XDELETEVEC (live);
+ 
+   return need_asserts;
+ }
  
  /* Create an ASSERT_EXPR for NAME and insert it in the location
     indicated by LOC.  Return true if we made any edge insertions.  */
*************** process_assert_insertions (void)
*** 4718,4744 ****
  static void
  insert_range_assertions (void)
  {
-   edge e;
-   edge_iterator ei;
-   bool update_ssa_p;
-   
-   found_in_subgraph = sbitmap_alloc (num_ssa_names);
-   sbitmap_zero (found_in_subgraph);
- 
-   blocks_visited = sbitmap_alloc (last_basic_block);
-   sbitmap_zero (blocks_visited);
- 
    need_assert_for = BITMAP_ALLOC (NULL);
    asserts_for = XCNEWVEC (assert_locus_t, num_ssa_names);
  
    calculate_dominance_info (CDI_DOMINATORS);
  
!   update_ssa_p = false;
!   FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
!     if (find_assert_locations (e->dest))
!       update_ssa_p = true;
! 
!   if (update_ssa_p)
      {
        process_assert_insertions ();
        update_ssa (TODO_update_ssa_no_phi);
--- 4737,4748 ----
  static void
  insert_range_assertions (void)
  {
    need_assert_for = BITMAP_ALLOC (NULL);
    asserts_for = XCNEWVEC (assert_locus_t, num_ssa_names);
  
    calculate_dominance_info (CDI_DOMINATORS);
  
!   if (find_assert_locations ())
      {
        process_assert_insertions ();
        update_ssa (TODO_update_ssa_no_phi);
*************** insert_range_assertions (void)
*** 4750,4756 ****
        dump_function_to_file (current_function_decl, dump_file, dump_flags);
      }
  
-   sbitmap_free (found_in_subgraph);
    free (asserts_for);
    BITMAP_FREE (need_assert_for);
  }
--- 4754,4759 ----
*************** remove_range_assertions (void)
*** 5019,5026 ****
  	else
  	  gsi_next (&si);
        }
- 
-   sbitmap_free (blocks_visited);
  }
  
  
--- 5022,5027 ----
Index: trunk/gcc/testsuite/g++.dg/tree-ssa/pr31146.C
===================================================================
*** trunk.orig/gcc/testsuite/g++.dg/tree-ssa/pr31146.C	2008-08-19 15:19:07.000000000 +0200
--- trunk/gcc/testsuite/g++.dg/tree-ssa/pr31146.C	2008-08-19 15:19:13.000000000 +0200
*************** void foo (int j)
*** 12,17 ****
    *q = 1;
  }
  
! /* { dg-final { scan-tree-dump "i\\\[j.*\\\] = 1;" "forwprop1" { xfail *-*-* } } } */
! /* { dg-final { scan-tree-dump "i\\\[j.*\\\] = 1;" "forwprop2" } } */
  /* { dg-final { cleanup-tree-dump "forwprop?" } } */
--- 12,16 ----
    *q = 1;
  }
  
! /* { dg-final { scan-tree-dump "i\\\[j.*\\\] =.* 1;" "forwprop1" } } */
  /* { dg-final { cleanup-tree-dump "forwprop?" } } */
Index: trunk/gcc/tree-ssa-pre.c
===================================================================
*** trunk.orig/gcc/tree-ssa-pre.c	2008-08-19 15:19:11.000000000 +0200
--- trunk/gcc/tree-ssa-pre.c	2008-08-19 15:37:30.000000000 +0200
*************** do_regular_insertion (basic_block block,
*** 3160,3173 ****
  	    {
  	      unsigned int vprime;
  
! 	      /* This can happen in the very weird case
! 		 that our fake infinite loop edges have caused a
! 		 critical edge to appear.  */
! 	      if (EDGE_CRITICAL_P (pred))
! 		{
! 		  cant_insert = true;
! 		  break;
! 		}
  	      bprime = pred->src;
  	      eprime = phi_translate (expr, ANTIC_IN (block), NULL,
  				      bprime, block);
--- 3160,3168 ----
  	    {
  	      unsigned int vprime;
  
! 	      /* We should never run insertion for the exit block
! 	         and so not come across fake pred edges.  */
! 	      gcc_assert (!(pred->flags & EDGE_FAKE));
  	      bprime = pred->src;
  	      eprime = phi_translate (expr, ANTIC_IN (block), NULL,
  				      bprime, block);
*************** fini_pre (bool do_fre)
*** 4117,4123 ****
    free_alloc_pool (pre_expr_pool);
    htab_delete (phi_translate_table);
    htab_delete (expression_to_id);
-   remove_fake_exit_edges ();
  
    FOR_ALL_BB (bb)
      {
--- 4112,4117 ----
*************** execute_pre (bool do_fre ATTRIBUTE_UNUSE
*** 4203,4208 ****
--- 4197,4207 ----
    statistics_counter_event (cfun, "New PHIs", pre_stats.phis);
    statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations);
    statistics_counter_event (cfun, "Constified", pre_stats.constified);
+ 
+   /* Make sure to remove fake edges before committing our inserts.
+      This makes sure we don't end up with extra critical edges that
+      we would need to split.  */
+   remove_fake_exit_edges ();
    gsi_commit_edge_inserts ();
  
    clear_expression_ids ();
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c	2008-08-19 15:40:11.000000000 +0200
***************
*** 0 ****
--- 1,35 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-pre-stats" } */
+ 
+ double pcheck;
+ 
+ void foo(int n, int m, int b)
+ {
+   int i, j;
+ 
+   goto bb18;
+ 
+ start:
+   i = 1;
+   do {
+     j = 1;
+     do {
+       double x = pcheck;
+       x = x + 1;
+       pcheck = x;
+       j = j + 1;
+     } while (j != m);
+     i = i + 1;
+   } while (i != n);
+ 
+ bb18:
+   pcheck = 0.0;
+   goto start;
+ }
+ 
+ /* We should have inserted two PHI nodes and the one in the i-loop
+    should have 0.0 in the argument coming from the bb18 block.  */
+ 
+ /* { dg-final { scan-tree-dump "New PHIs: 2" "pre" } } */
+ /* { dg-final { scan-tree-dump "PHI <.*0\\\.0" "pre" } } */
+ /* { dg-final { cleanup-tree-dump "pre" } } */


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