* [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] @ 2008-08-15 14:43 Richard Guenther 2008-08-15 17:41 ` Paolo Bonzini ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Richard Guenther @ 2008-08-15 14:43 UTC (permalink / raw) To: gcc-patches; +Cc: gcc This is the third patch in the series of optimizing the pass-pipeline, it applies on top of [1/n]. Cross-posted again to hint people to test this on their favorite apps. Like moving CCP before the initial alias computation is beneficial this patch moves the first forwprop pass after alias computation before it. This again should increase the precision of the first alias pass somewhat. The second DCE pass right after FRE is somewhat misplaced (with the above change we now would run FRE, DCE, copy-prop, merge-phi, vrp, DCE). copy-prop doesn't benefit from DCE and while copy-prop exposes DCE opportunities the propagator engine already removes trivially dead statements. Removing this DCE pass completely doesn't show any negative effects on tramp3d statistics, in particular VRP is unaffected. The most interesting pass change is the removal of the first DOM/phi-cprop pair. DOM mostly deals with jump-threading at this place and for tramp3d catches 473 threads on top of the 2555 ones performed by the VRP pass that runs right before the first DOM. 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). The patch has not yet been benchmarked (scheduled for tonight) but it has been bootstrapped and tested on x86_64-unknown-linux-gnu. Thanks, Richard. 2008-08-15 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. * 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/pr20701.c: Scan vrp1 dump. * gcc.dg/tree-ssa/ssa-dce-1.c: Scan dce2 dump. * gcc.dg/tree-ssa/ssa-dce-2.c: Likewise. * gcc.dg/tree-ssa/ssa-dom-thread-1.c: Pass -fno-tree-vrp. Index: trunk/gcc/passes.c =================================================================== *** trunk.orig/gcc/passes.c 2008-08-15 15:03:43.000000000 +0200 --- trunk/gcc/passes.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030530-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030611-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030703-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030703-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030708-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030709-3.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030710-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030711-3.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030714-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030729-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030730-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030730-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030731-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-11.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-3.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-5.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-8.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030807-9.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-3.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-4.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-5.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-6.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030814-7.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20030922-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20040729-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/20041122-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21417.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21829.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-2.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c 2008-08-15 15:03:45.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-15 14:56:31.000000000 +0200 --- trunk/gcc/tree-vrp.c 2008-08-15 15:08:42.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 *** 3911,3917 **** /* 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); --- 3916,3922 ---- /* 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 *** 3958,3964 **** && (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; --- 3963,3969 ---- && (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 *** 3987,3993 **** && 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; --- 3992,3998 ---- && 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 *** 4188,4195 **** } - 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. --- 4193,4198 ---- *************** find_conditional_asserts (basic_block bb *** 4220,4254 **** 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) --- 4223,4228 ---- *************** find_conditional_asserts (basic_block bb *** 4260,4270 **** } } - /* 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; } --- 4234,4239 ---- *************** find_switch_asserts (basic_block bb, gim *** 4361,4378 **** /* 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, --- 4330,4335 ---- *************** find_switch_asserts (basic_block bb, gim *** 4389,4398 **** } } - /* Finally, indicate that we have found the operand in the - SWITCH_EXPR. */ - SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op)); - return need_assert; } --- 4346,4351 ---- *************** find_switch_asserts (basic_block bb, gim *** 4461,4502 **** 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; --- 4414,4446 ---- 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) *** 4511,4522 **** 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 --- 4455,4462 ---- 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) *** 4567,4600 **** } } } - - /* 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. */ --- 4507,4620 ---- } } } } ! /* 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 rpo_cnt, i; + bool need_asserts; + + live = XCNEWVEC (sbitmap, last_basic_block + NUM_FIXED_BLOCKS); + add_noreturn_fake_exit_edges (); + rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false); + remove_fake_exit_edges (); + 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]])) + { + 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]]); + } + } + + /* We can free all successors live bitmaps if all their + predecessors have been visited already. */ + FOR_EACH_EDGE (e, ei, bb->succs) + { + bool ok = true; + edge e2; + edge_iterator ei2; + if (e->flags & EDGE_DFS_BACK + || !live[e->dest->index]) + continue; + FOR_EACH_EDGE (e2, ei2, e->dest->preds) + { + if (e2->flags & EDGE_DFS_BACK) + continue; + if (bb_rpo[e2->src->index] < i) + ok = false; + } + if (ok) + { + sbitmap_free (live[e->dest->index]); + live[e->dest->index] = NULL; + } + } + } + + XDELETEVEC (rpo); + XDELETEVEC (bb_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) *** 4721,4747 **** 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); --- 4741,4752 ---- 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) *** 4753,4759 **** dump_function_to_file (current_function_decl, dump_file, dump_flags); } - sbitmap_free (found_in_subgraph); free (asserts_for); BITMAP_FREE (need_assert_for); } --- 4758,4763 ---- *************** remove_range_assertions (void) *** 5022,5029 **** else gsi_next (&si); } - - sbitmap_free (blocks_visited); } --- 5026,5031 ---- ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-15 14:43 [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] Richard Guenther @ 2008-08-15 17:41 ` Paolo Bonzini 2008-08-15 18:08 ` Richard Guenther 2008-08-16 21:25 ` Richard Guenther 2008-08-18 17:05 ` Jeff Law 2 siblings, 1 reply; 11+ messages in thread From: Paolo Bonzini @ 2008-08-15 17:41 UTC (permalink / raw) To: Richard Guenther; +Cc: gcc-patches > 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. Paolo ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-15 17:41 ` Paolo Bonzini @ 2008-08-15 18:08 ` Richard Guenther 2008-08-19 14:07 ` Richard Guenther 0 siblings, 1 reply; 11+ messages in thread From: Richard Guenther @ 2008-08-15 18:08 UTC (permalink / raw) To: Paolo Bonzini; +Cc: gcc-patches 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. Richard. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-15 18:08 ` Richard Guenther @ 2008-08-19 14:07 ` Richard Guenther 2008-08-20 10:19 ` Richard Guenther 0 siblings, 1 reply; 11+ messages in thread From: Richard Guenther @ 2008-08-19 14:07 UTC (permalink / raw) To: Paolo Bonzini; +Cc: gcc-patches, Daniel Berlin 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" } } */ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-19 14:07 ` Richard Guenther @ 2008-08-20 10:19 ` Richard Guenther 2008-08-20 13:43 ` Richard Guenther 0 siblings, 1 reply; 11+ messages in thread From: Richard Guenther @ 2008-08-20 10:19 UTC (permalink / raw) To: Paolo Bonzini; +Cc: gcc-patches, Daniel Berlin On Tue, 19 Aug 2008, Richard Guenther wrote: > 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. First half (VRP/PRE improvements) committed as rev. 139262 now. Bootstrapped and tested on x86_64-unknown-linux-gnu, patch appended for reference. 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. 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 17:04:20.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: 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 16:58:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-1.c 2008-08-19 17:04:20.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/testsuite/gcc.dg/tree-ssa/pr20701.c =================================================================== *** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c 2008-08-19 16:58:31.000000000 +0200 --- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20701.c 2008-08-19 17:04:20.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/tree-vrp.c =================================================================== *** trunk.orig/gcc/tree-vrp.c 2008-08-19 16:58:31.000000000 +0200 --- trunk/gcc/tree-vrp.c 2008-08-19 17:04:20.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/tree-ssa-pre.c =================================================================== *** trunk.orig/gcc/tree-ssa-pre.c 2008-08-19 16:58:31.000000000 +0200 --- trunk/gcc/tree-ssa-pre.c 2008-08-19 17:18:32.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); *************** do_partial_partial_insertion (basic_bloc *** 3299,3312 **** unsigned int vprime; pre_expr edoubleprime; ! /* 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), PA_IN (block), --- 3294,3302 ---- unsigned int vprime; pre_expr edoubleprime; ! /* 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), PA_IN (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) { --- 4107,4112 ---- *************** execute_pre (bool do_fre ATTRIBUTE_UNUSE *** 4203,4208 **** --- 4192,4202 ---- 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 (); ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-20 10:19 ` Richard Guenther @ 2008-08-20 13:43 ` Richard Guenther 2008-08-21 2:24 ` H.J. Lu 0 siblings, 1 reply; 11+ messages in thread From: Richard Guenther @ 2008-08-20 13:43 UTC (permalink / raw) To: Paolo Bonzini; +Cc: gcc-patches, Daniel Berlin On Wed, 20 Aug 2008, Richard Guenther wrote: > On Tue, 19 Aug 2008, Richard Guenther wrote: > > > 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. > > First half (VRP/PRE improvements) committed as rev. 139262 now. > > Bootstrapped and tested on x86_64-unknown-linux-gnu, patch appended > for reference. passes.c and releated testsuite changes committed as rev. 139286. Richard. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-20 13:43 ` Richard Guenther @ 2008-08-21 2:24 ` H.J. Lu 0 siblings, 0 replies; 11+ messages in thread From: H.J. Lu @ 2008-08-21 2:24 UTC (permalink / raw) To: Richard Guenther; +Cc: Paolo Bonzini, gcc-patches, Daniel Berlin On Wed, Aug 20, 2008 at 6:00 AM, Richard Guenther <rguenther@suse.de> wrote: >> >> Bootstrapped and tested on x86_64-unknown-linux-gnu, patch appended >> for reference. > > passes.c and releated testsuite changes committed as rev. 139286. > Revision 139286 caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37182 -- H.J. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-15 14:43 [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] Richard Guenther 2008-08-15 17:41 ` Paolo Bonzini @ 2008-08-16 21:25 ` Richard Guenther 2008-08-18 17:05 ` Jeff Law 2 siblings, 0 replies; 11+ messages in thread From: Richard Guenther @ 2008-08-16 21:25 UTC (permalink / raw) To: gcc-patches; +Cc: gcc On Fri, 15 Aug 2008, Richard Guenther wrote: > > This is the third patch in the series of optimizing the pass-pipeline, > it applies on top of [1/n]. Cross-posted again to hint people to test > this on their favorite apps. > > Like moving CCP before the initial alias computation is beneficial this > patch moves the first forwprop pass after alias computation before it. > This again should increase the precision of the first alias pass somewhat. > > The second DCE pass right after FRE is somewhat misplaced > (with the above change we now would run FRE, DCE, copy-prop, > merge-phi, vrp, DCE). copy-prop doesn't benefit from DCE and > while copy-prop exposes DCE opportunities the propagator engine > already removes trivially dead statements. Removing this DCE > pass completely doesn't show any negative effects on tramp3d statistics, > in particular VRP is unaffected. > > > The most interesting pass change is the removal of the first > DOM/phi-cprop pair. DOM mostly deals with jump-threading at this > place and for tramp3d catches 473 threads on top of the 2555 ones > performed by the VRP pass that runs right before the first DOM. > > 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). > > > The patch has not yet been benchmarked (scheduled for tonight) but > it has been bootstrapped and tested on x86_64-unknown-linux-gnu. SPEC/Polyhedron/C++ tests look good. There is overall improvement in runtime and compile-time. I'll plan to apply this two days after the first patch. Richard. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-15 14:43 [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] Richard Guenther 2008-08-15 17:41 ` Paolo Bonzini 2008-08-16 21:25 ` Richard Guenther @ 2008-08-18 17:05 ` Jeff Law 2008-08-18 21:57 ` Richard Guenther 2 siblings, 1 reply; 11+ messages in thread From: Jeff Law @ 2008-08-18 17:05 UTC (permalink / raw) To: Richard Guenther; +Cc: gcc-patches, gcc Richard Guenther wrote: > > The most interesting pass change is the removal of the first > DOM/phi-cprop pair. DOM mostly deals with jump-threading at this > place and for tramp3d catches 473 threads on top of the 2555 ones > performed by the VRP pass that runs right before the first DOM. > Ultimately, jump threading is all I really want DOM to do long term anyway -- the redundancy elimination performed by DOM can be better handled elsewhere. The interesting question is there redundancy elimination left in DOM that is unique and if not, can we get the same overall effect if we remove the redundancy elimination from DOM and instead using existing passes for redundancy elimination. Same overall effect doesn't mean identical code, but reasonably close and without incurring a significant compile-time hit. Regardless, I fully support eliminating the number of calls into DOM as well as trimming the set of transformations performed by DOM. jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-18 17:05 ` Jeff Law @ 2008-08-18 21:57 ` Richard Guenther 2008-08-23 7:22 ` Jeff Law 0 siblings, 1 reply; 11+ messages in thread From: Richard Guenther @ 2008-08-18 21:57 UTC (permalink / raw) To: Jeff Law; +Cc: gcc-patches, gcc On Mon, 18 Aug 2008, Jeff Law wrote: > Richard Guenther wrote: > > > > The most interesting pass change is the removal of the first > > DOM/phi-cprop pair. DOM mostly deals with jump-threading at this > > place and for tramp3d catches 473 threads on top of the 2555 ones > > performed by the VRP pass that runs right before the first DOM. > > > Ultimately, jump threading is all I really want DOM to do long term anyway -- Yes, I agree .. > the redundancy elimination performed by DOM can be better handled elsewhere. > The interesting question is there redundancy elimination left in DOM that is > unique and if not, can we get the same overall effect if we remove the > redundancy elimination from DOM and instead using existing passes for > redundancy elimination. Same overall effect doesn't mean identical code, but ... though I am not sure (I didn't investigate) how much of the redundancy elimination code feeds the jump threading parts. I was thinking of moving the jump threading parts over to SCCVN instead, given that VRP lacks capabilities regarding to symbolical conditions. > reasonably close and without incurring a significant compile-time hit. > > Regardless, I fully support eliminating the number of calls into DOM as well > as trimming the set of transformations performed by DOM. Thanks. It seems the last DOM pass doesn't do very much as well, so I'll be playing with removing that as a last step of cleaning up the pipeline. Even if that might need another run of FRE instead of DOM. Richard. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] 2008-08-18 21:57 ` Richard Guenther @ 2008-08-23 7:22 ` Jeff Law 0 siblings, 0 replies; 11+ messages in thread From: Jeff Law @ 2008-08-23 7:22 UTC (permalink / raw) To: Richard Guenther; +Cc: gcc-patches, gcc Richard Guenther wrote: >> the redundancy elimination performed by DOM can be better handled elsewhere. >> The interesting question is there redundancy elimination left in DOM that is >> unique and if not, can we get the same overall effect if we remove the >> redundancy elimination from DOM and instead using existing passes for >> redundancy elimination. Same overall effect doesn't mean identical code, but > > ... though I am not sure (I didn't investigate) how much of the > redundancy elimination code feeds the jump threading parts. I was > thinking of moving the jump threading parts over to SCCVN instead, given > that VRP lacks capabilities regarding to symbolical conditions. It's reasonably common. At one time I had mostly convinced myself that fixing PRE was the way to go as many of the complex threading cases would be much simpler if PRE was more effective at removing partial redundancies. But the more I pondered the problem the more I realized that the frameworks we have simply weren't sufficient to solve the class of problems I wanted to look at. In fact, there was a master's thesis (don't have it handy right now) which argued that what we're doing (poorly) in DOM is actually a whole new class of context/path specific optimizations and that solving them with traditional techniques was ultimately a horrid compile-time sink. They came up with a new framework to perform these context/path sensitive optimizations, but I wasn't ever able to wrap my head around it well enough to understand or explain it. In essence it was a context/path sensitive PRE-like algorithm. It looked expensive, but far less so than running multiple passes of our iterating DOM optimizer. > > Thanks. It seems the last DOM pass doesn't do very much as well, so > I'll be playing with removing that as a last step of cleaning up the > pipeline. Even if that might need another run of FRE instead of DOM. One of the indicators to watch is whether or not the RTL jump threading code starts to become more important -- if it does, then we're ripping too much out of DOM. When I last looked, the only common case left where the RTL version was still useful were cases where our tree aliasing code sucked horribly bad causing DOM/PRE to miss stuff which we later caught in the RTL jump threading code. jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-08-23 3:32 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-08-15 14:43 [PATCH][RFT] Optimization pass-pipeline re-organization [3/n] Richard Guenther 2008-08-15 17:41 ` Paolo Bonzini 2008-08-15 18:08 ` Richard Guenther 2008-08-19 14:07 ` Richard Guenther 2008-08-20 10:19 ` Richard Guenther 2008-08-20 13:43 ` Richard Guenther 2008-08-21 2:24 ` H.J. Lu 2008-08-16 21:25 ` Richard Guenther 2008-08-18 17:05 ` Jeff Law 2008-08-18 21:57 ` Richard Guenther 2008-08-23 7:22 ` Jeff Law
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).