From b80280f2c568097c1da9aacd9b540f74ad91cf22 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 18 Mar 2008 16:10:24 +0000 Subject: [PATCH] tree-ssa-sccvn.c (visit_reference_op_load): If the lookup found an expression with constants, note that in the VN for the lhs. 2008-03-18 Richard Guenther * tree-ssa-sccvn.c (visit_reference_op_load): If the lookup found an expression with constants, note that in the VN for the lhs. * tree-ssa-pre.c (eliminate): Visit COND_EXPR statements and fold them to constants if possible. Run cleanup_cfg if done so. (execute_pre): Return todo. (do_pre): Likewise. (execute_fre): Likewise. * tree-ssa-forwprop.c (can_propagate_from): Allow propagation of constants. (get_prop_source_stmt): Look through pointer conversions. * gcc.dg/tree-ssa/forwprop-4.c: New testcase. * gcc.dg/tree-ssa/ssa-fre-16.c: Likewise. From-SVN: r133315 --- gcc/ChangeLog | 13 +++++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c | 18 +++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c | 18 +++++++ gcc/tree-ssa-forwprop.c | 26 ++++++++-- gcc/tree-ssa-pre.c | 56 ++++++++++++++++++---- gcc/tree-ssa-sccvn.c | 6 +++ 7 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 82374258411..add3e25ad86 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2008-03-18 Richard Guenther + + * tree-ssa-sccvn.c (visit_reference_op_load): If the lookup + found an expression with constants, note that in the VN for the lhs. + * tree-ssa-pre.c (eliminate): Visit COND_EXPR statements and + fold them to constants if possible. Run cleanup_cfg if done so. + (execute_pre): Return todo. + (do_pre): Likewise. + (execute_fre): Likewise. + * tree-ssa-forwprop.c (can_propagate_from): Allow propagation + of constants. + (get_prop_source_stmt): Look through pointer conversions. + 2008-03-18 Jan Hubicka * tree-pretty-print.c: Include predict.h. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5543830532..d9bca3944e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-18 Richard Guenther + + * gcc.dg/tree-ssa/forwprop-4.c: New testcase. + * gcc.dg/tree-ssa/ssa-fre-16.c: Likewise. + 2008-03-18 Richard Guenther * gcc.dg/tree-ssa/loop-19.c: Revert previous change. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c new file mode 100644 index 00000000000..7eabd1a7bd8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-4.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop1" } */ + +/* We should be able to fold the comparison at least with the + first forwprop pass, if not a ccp pass before. */ + +extern void link_error (void); +void foo() +{ + int i; + char *p = (char *)&i; + long *q = (long *)p; + if (q == 0) + link_error (); +} + +/* { dg-final { scan-tree-dump-not "link_error" "forwprop1" } } */ +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c new file mode 100644 index 00000000000..56d85e58e7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-16.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre" } */ + +/* FRE should be able to combine i and j and perform simplification + on the condition. */ + +extern void link_error (void); +int i; +int foo(int b, int c) +{ + i = b + 1; + int j = i - 1; + if (b != j) + link_error (); +} + +/* { dg-final { scan-tree-dump-not "link_error" "fre" } } */ +/* { dg-final { cleanup-tree-dump "fre" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 5108cfcd6f2..1766869d0c4 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -218,14 +218,28 @@ get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p) /* If name is not a simple copy destination, we found it. */ if (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) != SSA_NAME) { + tree rhs; + if (!single_use_only && single_use_p) *single_use_p = single_use; - return def_stmt; + /* We can look through pointer conversions in the search + for a useful stmt for the comparison folding. */ + rhs = GIMPLE_STMT_OPERAND (def_stmt, 1); + if ((TREE_CODE (rhs) == NOP_EXPR + || TREE_CODE (rhs) == CONVERT_EXPR) + && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME + && POINTER_TYPE_P (TREE_TYPE (rhs)) + && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))) + name = TREE_OPERAND (rhs, 0); + else + return def_stmt; + } + else + { + /* Continue searching the def of the copy source name. */ + name = GIMPLE_STMT_OPERAND (def_stmt, 1); } - - /* Continue searching the def of the copy source name. */ - name = GIMPLE_STMT_OPERAND (def_stmt, 1); } while (1); } @@ -245,6 +259,10 @@ can_propagate_from (tree def_stmt) if (REFERENCE_CLASS_P (rhs)) return false; + /* Constants can be always propagated. */ + if (is_gimple_min_invariant (rhs)) + return true; + /* We cannot propagate ssa names that occur in abnormal phi nodes. */ switch (TREE_CODE_LENGTH (TREE_CODE (rhs))) { diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 616627ccb1b..ad628a31916 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3605,10 +3605,11 @@ do_SCCVN_insertion (tree stmt, tree ssa_vn) /* Eliminate fully redundant computations. */ -static void +static unsigned int eliminate (void) { basic_block b; + unsigned int todo = 0; FOR_EACH_BB (b) { @@ -3689,8 +3690,46 @@ eliminate (void) } } } + /* Visit COND_EXPRs and fold the comparison with the + available value-numbers. */ + else if (TREE_CODE (stmt) == COND_EXPR + && COMPARISON_CLASS_P (COND_EXPR_COND (stmt))) + { + tree cond = COND_EXPR_COND (stmt); + tree op0 = TREE_OPERAND (cond, 0); + tree op1 = TREE_OPERAND (cond, 1); + tree result; + + if (TREE_CODE (op0) == SSA_NAME) + op0 = VN_INFO (op0)->valnum; + if (TREE_CODE (op1) == SSA_NAME) + op1 = VN_INFO (op1)->valnum; + result = fold_binary (TREE_CODE (cond), TREE_TYPE (cond), + op0, op1); + if (result && TREE_CODE (result) == INTEGER_CST) + { + COND_EXPR_COND (stmt) = result; + update_stmt (stmt); + todo = TODO_cleanup_cfg; + } + } + else if (TREE_CODE (stmt) == COND_EXPR + && TREE_CODE (COND_EXPR_COND (stmt)) == SSA_NAME) + { + tree op = COND_EXPR_COND (stmt); + op = VN_INFO (op)->valnum; + if (TREE_CODE (op) == INTEGER_CST) + { + COND_EXPR_COND (stmt) = integer_zerop (op) + ? boolean_false_node : boolean_true_node; + update_stmt (stmt); + todo = TODO_cleanup_cfg; + } + } } } + + return todo; } /* Borrow a bit of tree-ssa-dce.c for the moment. @@ -3931,9 +3970,10 @@ fini_pre (void) /* Main entry point to the SSA-PRE pass. DO_FRE is true if the caller only wants to do full redundancy elimination. */ -static void +static unsigned int execute_pre (bool do_fre) { + unsigned int todo = 0; do_partial_partial = optimize > 2; init_pre (do_fre); @@ -3947,7 +3987,7 @@ execute_pre (bool do_fre) if (!do_fre) remove_dead_inserted_code (); fini_pre (); - return; + return 0; } switch_to_PRE_table (); compute_avail (); @@ -3978,7 +4018,7 @@ execute_pre (bool do_fre) } /* Remove all the redundant expressions. */ - eliminate (); + todo |= eliminate (); if (dump_file && (dump_flags & TDF_STATS)) { @@ -3999,6 +4039,8 @@ execute_pre (bool do_fre) } fini_pre (); + + return todo; } /* Gate and execute functions for PRE. */ @@ -4006,8 +4048,7 @@ execute_pre (bool do_fre) static unsigned int do_pre (void) { - execute_pre (false); - return TODO_rebuild_alias; + return TODO_rebuild_alias | execute_pre (false); } static bool @@ -4041,8 +4082,7 @@ struct tree_opt_pass pass_pre = static unsigned int execute_fre (void) { - execute_pre (true); - return 0; + return execute_pre (true); } static bool diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index b10d3e31a85..b613b2ba21f 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1251,6 +1251,12 @@ visit_reference_op_load (tree lhs, tree op, tree stmt) if (result) { changed = set_ssa_val_to (lhs, result); + if (TREE_CODE (result) == SSA_NAME + && VN_INFO (result)->has_constants) + { + VN_INFO (lhs)->expr = VN_INFO (result)->expr; + VN_INFO (lhs)->has_constants = true; + } } else { -- 2.30.2