toplev.h (flag_delete_null_pointer_checks): Move from here to...
authorJeff Law <law@redhat.com>
Tue, 18 May 2004 02:53:55 +0000 (20:53 -0600)
committerJeff Law <law@gcc.gnu.org>
Tue, 18 May 2004 02:53:55 +0000 (20:53 -0600)
        * 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
gcc/flags.h
gcc/toplev.h
gcc/tree-flow.h
gcc/tree-phinodes.c
gcc/tree-ssa-dom.c
gcc/tree.h

index 6b265b055b518cfafb593e867b75ef9722fd4d98..ee2ae6f574751922dd3d1bfa9f4b6aab032ecfdb 100644 (file)
@@ -1,3 +1,21 @@
+2004-05-17  Jeff Law  <law@redhat.com>
+
+       * 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  <zack@codesourcery.com>
 
        * f: Entire directory removed
index 8778b63539274012db81323ee431b1916fc6045f..6f8f5f67ea3c13d0a9aa82deee87f1cbde61f63a 100644 (file)
@@ -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.  */
index daad92fa10eb179dcceff059bd798f44e3e320c0..7a2dc6b19b27556f689ec85bac9d5707f0740633 100644 (file)
@@ -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;
index 66995338a40d15b4b3b45c8cc144798a546ccbae..997ed6247d6399801c6c2b7dc7356989826c0ee9 100644 (file)
@@ -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);
index e4fc904fd4a5e802a7405d755cf3d9e8619ffb7b..8a8454c1c1ccee938bf84b8c67aca4fa8baf4b7a 100644 (file)
@@ -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
index 5f8896f70196875c3350e92de970cd3eea1b86c7..3ecb8e0a3f91369ef3fe5aacd3c7d60fd4df4b11 100644 (file)
@@ -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
index efc8691a0d0badd1236c9b950c9b29d87ecb577f..d753f0209d3a60b455222fe8a71c7ef705905a33 100644 (file)
@@ -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(())