From dd7473111a63cdeb442d1b74535405739bf7e866 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 17 May 2004 20:53:55 -0600 Subject: [PATCH] toplev.h (flag_delete_null_pointer_checks): Move from here to... * toplev.h (flag_delete_null_pointer_checks): Move from here to... * flags.h (flag_delete_null_pointer_checks): Here. * tree-flow.h (cprop_into_successor_phis): Add argument to prototype. * tree-phinodes.c (resize_phi_node): Initialize PHI_ARG_NONZERO. (add_phi_arg, remove_phi_arg_num): Similarly. * tree-ssa-copy.c (cprop_into_successor_phis): Propagate nonzero property into PHI nodes. * tree-ssa-dom.c: Remove redundant inclusion of flags.h. (record_equivalences_from_phis): If all PHI arguments are known to be nonzero, then the result must be nonzero as well. (cprop_into_phis): Pass nonzero_vars bitmap to cprop_into_successor_phis (record_equivalences_from_stmt): Check flag_delete_null_pointer_checks appropriately. Walk the USE-DEF chains and propagate nonzero property as appropriate. * tree.h (PHI_ARG_NONZERO): Define. (phi_arg_d): Add nonzero flag. From-SVN: r81968 --- gcc/ChangeLog | 18 +++++++++++ gcc/flags.h | 4 +++ gcc/toplev.h | 1 - gcc/tree-flow.h | 2 +- gcc/tree-phinodes.c | 4 +++ gcc/tree-ssa-dom.c | 73 +++++++++++++++++++++++++++++++-------------- gcc/tree.h | 2 ++ 7 files changed, 80 insertions(+), 24 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6b265b055b5..ee2ae6f5747 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2004-05-17 Jeff Law + + * toplev.h (flag_delete_null_pointer_checks): Move from here to... + * flags.h (flag_delete_null_pointer_checks): Here. + * tree-flow.h (cprop_into_successor_phis): Add argument to prototype. + * tree-phinodes.c (resize_phi_node): Initialize PHI_ARG_NONZERO. + (add_phi_arg, remove_phi_arg_num): Similarly. + * tree-ssa-copy.c (cprop_into_successor_phis): Propagate nonzero + property into PHI nodes. + * tree-ssa-dom.c: Remove redundant inclusion of flags.h. + (record_equivalences_from_phis): If all PHI arguments are known to be + nonzero, then the result must be nonzero as well. + (cprop_into_phis): Pass nonzero_vars bitmap to cprop_into_successor_phis (record_equivalences_from_stmt): Check flag_delete_null_pointer_checks + appropriately. Walk the USE-DEF chains and propagate nonzero property + as appropriate. + * tree.h (PHI_ARG_NONZERO): Define. + (phi_arg_d): Add nonzero flag. + 2004-05-17 Zack Weinberg * f: Entire directory removed diff --git a/gcc/flags.h b/gcc/flags.h index 8778b635392..6f8f5f67ea3 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -323,6 +323,10 @@ extern int flag_cse_skip_blocks; perform miscellaneous relatively-expensive optimizations. */ extern int flag_expensive_optimizations; +/* Nonzero means to use global dataflow analysis to eliminate + useless null pointer tests. */ +extern int flag_delete_null_pointer_checks; + /* Nonzero means don't put addresses of constant functions in registers. Used for compiling the Unix kernel, where strange substitutions are done on the assembly output. */ diff --git a/gcc/toplev.h b/gcc/toplev.h index daad92fa10e..7a2dc6b19b2 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -113,7 +113,6 @@ extern int flag_loop_optimize; extern int flag_crossjumping; extern int flag_if_conversion; extern int flag_if_conversion2; -extern int flag_delete_null_pointer_checks; extern int flag_keep_static_consts; extern int flag_peel_loops; extern int flag_rerun_cse_after_loop; diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 66995338a40..997ed6247d6 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -575,7 +575,7 @@ extern void debug_dominator_optimization_stats (void); extern void propagate_value (tree *, tree); extern void replace_exp (tree *, tree); extern bool cprop_into_stmt (tree, varray_type); -extern void cprop_into_successor_phis (basic_block, varray_type); +extern void cprop_into_successor_phis (basic_block, varray_type, bitmap); /* In tree-flow-inline.h */ static inline int phi_arg_from_edge (tree, edge); diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index e4fc904fd4a..8a8454c1c1c 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -280,6 +280,7 @@ resize_phi_node (tree *phi, int len) { PHI_ARG_DEF (new_phi, i) = NULL_TREE; PHI_ARG_EDGE (new_phi, i) = NULL; + PHI_ARG_NONZERO (new_phi, i) = false; } *phi = new_phi; @@ -366,6 +367,7 @@ add_phi_arg (tree *phi, tree def, edge e) PHI_ARG_DEF (*phi, i) = def; PHI_ARG_EDGE (*phi, i) = e; + PHI_ARG_NONZERO (*phi, i) = false; PHI_NUM_ARGS (*phi)++; } @@ -408,11 +410,13 @@ remove_phi_arg_num (tree phi, int i) { PHI_ARG_DEF (phi, i) = PHI_ARG_DEF (phi, num_elem - 1); PHI_ARG_EDGE (phi, i) = PHI_ARG_EDGE (phi, num_elem - 1); + PHI_ARG_NONZERO (phi, i) = PHI_ARG_NONZERO (phi, num_elem - 1); } /* Shrink the vector and return. */ PHI_ARG_DEF (phi, num_elem - 1) = NULL_TREE; PHI_ARG_EDGE (phi, num_elem - 1) = NULL; + PHI_ARG_NONZERO (phi, num_elem - 1) = false; PHI_NUM_ARGS (phi)--; /* If we removed the last PHI argument, then go ahead and diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 5f8896f7019..3ecb8e0a3f9 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -40,7 +40,6 @@ Boston, MA 02111-1307, USA. */ #include "domwalk.h" #include "real.h" #include "tree-pass.h" -#include "flags.h" #include "langhooks.h" /* This file implements optimizations on the dominator tree. */ @@ -1314,7 +1313,12 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb) Ignoring any alternatives which are the same as the result, if all the alternatives are equal, then the PHI node creates an - equivalence. */ + equivalence. + + Additionally, if all the PHI alternatives are known to have a nonzero + value, then the result of this PHI is known to have a nonzero value, + even if we do not know its exact value. */ + static void record_equivalences_from_phis (struct dom_walk_data *walk_data, basic_block bb) { @@ -1367,6 +1371,17 @@ record_equivalences_from_phis (struct dom_walk_data *walk_data, basic_block bb) && may_propagate_copy (lhs, rhs)) set_value_for (lhs, rhs, const_and_copies); + /* Now see if we know anything about the nonzero property for the + result of this PHI. */ + for (i = 0; i < PHI_NUM_ARGS (phi); i++) + { + if (!PHI_ARG_NONZERO (phi, i)) + break; + } + + if (i == PHI_NUM_ARGS (phi)) + bitmap_set_bit (nonzero_vars, SSA_NAME_VERSION (PHI_RESULT (phi))); + register_new_def (lhs, &bd->block_defs); } } @@ -2257,7 +2272,7 @@ static void cprop_into_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, basic_block bb) { - cprop_into_successor_phis (bb, const_and_copies); + cprop_into_successor_phis (bb, const_and_copies, nonzero_vars); } /* Search for redundant computations in STMT. If any are found, then @@ -2422,25 +2437,39 @@ record_equivalences_from_stmt (tree stmt, /* Look at both sides for pointer dereferences. If we find one, then the pointer must be nonnull and we can enter that equivalence into the hash tables. */ - for (i = 0; i < 2; i++) - { - tree t = TREE_OPERAND (stmt, i); - - /* Strip away any COMPONENT_REFs. */ - while (TREE_CODE (t) == COMPONENT_REF) - t = TREE_OPERAND (t, 0); - - /* Now see if this is a pointer dereference. */ - if (TREE_CODE (t) == INDIRECT_REF) - { - tree op = TREE_OPERAND (t, 0); - - /* If the pointer is a SSA variable, then enter new - equivalences into the hash table. */ - if (TREE_CODE (op) == SSA_NAME) - record_var_is_nonzero (op, block_nonzero_vars_p); - } - } + if (flag_delete_null_pointer_checks) + for (i = 0; i < 2; i++) + { + tree t = TREE_OPERAND (stmt, i); + + /* Strip away any COMPONENT_REFs. */ + while (TREE_CODE (t) == COMPONENT_REF) + t = TREE_OPERAND (t, 0); + + /* Now see if this is a pointer dereference. */ + if (TREE_CODE (t) == INDIRECT_REF) + { + tree op = TREE_OPERAND (t, 0); + + /* If the pointer is a SSA variable, then enter new + equivalences into the hash table. */ + while (TREE_CODE (op) == SSA_NAME) + { + tree def = SSA_NAME_DEF_STMT (op); + + record_var_is_nonzero (op, block_nonzero_vars_p); + + /* And walk up the USE-DEF chains noting other SSA_NAMEs + which are known to have a nonzero value. */ + if (def + && TREE_CODE (def) == MODIFY_EXPR + && TREE_CODE (TREE_OPERAND (def, 1)) == NOP_EXPR) + op = TREE_OPERAND (TREE_OPERAND (def, 1), 0); + else + break; + } + } + } /* A memory store, even an aliased store, creates a useful equivalence. By exchanging the LHS and RHS, creating suitable diff --git a/gcc/tree.h b/gcc/tree.h index efc8691a0d0..d753f0209d3 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1203,6 +1203,7 @@ struct tree_ssa_name GTY(()) #define PHI_ARG_ELT(NODE, I) PHI_NODE_ELT_CHECK (NODE, I) #define PHI_ARG_EDGE(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).e #define PHI_ARG_DEF(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).def +#define PHI_ARG_NONZERO(NODE, I) PHI_NODE_ELT_CHECK (NODE, I).nonzero struct edge_def; @@ -1210,6 +1211,7 @@ struct phi_arg_d GTY(()) { tree def; struct edge_def * GTY((skip (""))) e; + bool nonzero; }; struct tree_phi_node GTY(()) -- 2.30.2