Simply register an != 0 expression for them.  This should solve Honzas
request to optimize away != 0 checks for this pointers during early opts.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2015-08-13  Richard Biener  <rguent...@suse.de>

        * tree.c (nonnull_arg_p): Move from ...
        * tree-vrp.c (nonnull_arg_p): ... here.
        * tree.h (nonnull_arg_p): Declare.
        * tree-ssa-sccvn.c (init_scc_vn): Perform all lattice init
        here, register ptr != 0 for nonnull_arg_p pointer arguments.
        Properly initialize static chain and by-reference result pointer.
        (run_scc_vn): Adjust.

Index: gcc/tree.c
===================================================================
--- gcc/tree.c  (revision 226852)
+++ gcc/tree.c  (working copy)
@@ -13571,4 +13571,67 @@ verify_type (const_tree t)
     }
 }
 
+
+/* Return true if ARG is marked with the nonnull attribute in the
+   current function signature.  */
+
+bool
+nonnull_arg_p (const_tree arg)
+{
+  tree t, attrs, fntype;
+  unsigned HOST_WIDE_INT arg_num;
+
+  gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE 
(arg)));
+
+  /* The static chain decl is always non null.  */
+  if (arg == cfun->static_chain_decl)
+    return true;
+
+  /* THIS argument of method is always non-NULL.  */
+  if (TREE_CODE (TREE_TYPE (cfun->decl)) == METHOD_TYPE
+      && arg == DECL_ARGUMENTS (cfun->decl)
+      && flag_delete_null_pointer_checks)
+    return true;
+
+  /* Values passed by reference are always non-NULL.  */
+  if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE
+      && flag_delete_null_pointer_checks)
+    return true;
+
+  fntype = TREE_TYPE (cfun->decl);
+  for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs))
+    {
+      attrs = lookup_attribute ("nonnull", attrs);
+
+      /* If "nonnull" wasn't specified, we know nothing about the argument.  */
+      if (attrs == NULL_TREE)
+       return false;
+
+      /* If "nonnull" applies to all the arguments, then ARG is non-null.  */
+      if (TREE_VALUE (attrs) == NULL_TREE)
+       return true;
+
+      /* Get the position number for ARG in the function signature.  */
+      for (arg_num = 1, t = DECL_ARGUMENTS (cfun->decl);
+          t;
+          t = DECL_CHAIN (t), arg_num++)
+       {
+         if (t == arg)
+           break;
+       }
+
+      gcc_assert (t == arg);
+
+      /* Now see if ARG_NUM is mentioned in the nonnull list.  */
+      for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
+       {
+         if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
+           return true;
+       }
+    }
+
+  return false;
+}
+
+
 #include "gt-tree.h"
Index: gcc/tree.h
===================================================================
--- gcc/tree.h  (revision 226852)
+++ gcc/tree.h  (working copy)
@@ -5133,4 +5133,6 @@ extern void gt_ggc_mx (tree &);
 extern void gt_pch_nx (tree &);
 extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
 
+extern bool nonnull_arg_p (const_tree);
+
 #endif  /* GCC_TREE_H  */
Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c      (revision 226852)
+++ gcc/tree-vrp.c      (working copy)
@@ -355,68 +355,6 @@ avoid_overflow_infinity (tree val)
 }
 
 
-/* Return true if ARG is marked with the nonnull attribute in the
-   current function signature.  */
-
-static bool
-nonnull_arg_p (const_tree arg)
-{
-  tree t, attrs, fntype;
-  unsigned HOST_WIDE_INT arg_num;
-
-  gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE 
(arg)));
-
-  /* The static chain decl is always non null.  */
-  if (arg == cfun->static_chain_decl)
-    return true;
-
-  /* THIS argument of method is always non-NULL.  */
-  if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
-      && arg == DECL_ARGUMENTS (current_function_decl)
-      && flag_delete_null_pointer_checks)
-    return true;
-
-  /* Values passed by reference are always non-NULL.  */
-  if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE
-      && flag_delete_null_pointer_checks)
-    return true;
-
-  fntype = TREE_TYPE (current_function_decl);
-  for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs))
-    {
-      attrs = lookup_attribute ("nonnull", attrs);
-
-      /* If "nonnull" wasn't specified, we know nothing about the argument.  */
-      if (attrs == NULL_TREE)
-       return false;
-
-      /* If "nonnull" applies to all the arguments, then ARG is non-null.  */
-      if (TREE_VALUE (attrs) == NULL_TREE)
-       return true;
-
-      /* Get the position number for ARG in the function signature.  */
-      for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
-          t;
-          t = DECL_CHAIN (t), arg_num++)
-       {
-         if (t == arg)
-           break;
-       }
-
-      gcc_assert (t == arg);
-
-      /* Now see if ARG_NUM is mentioned in the nonnull list.  */
-      for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
-       {
-         if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
-           return true;
-       }
-    }
-
-  return false;
-}
-
-
 /* Set value range VR to VR_UNDEFINED.  */
 
 static inline void
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c        (revision 226852)
+++ gcc/tree-ssa-sccvn.c        (working copy)
@@ -4203,19 +4211,6 @@ init_scc_vn (void)
 
   VN_TOP = create_tmp_var_raw (void_type_node, "vn_top");
 
-  /* Create the VN_INFO structures, and initialize value numbers to
-     TOP.  */
-  for (i = 0; i < num_ssa_names; i++)
-    {
-      tree name = ssa_name (i);
-      if (name)
-       {
-         VN_INFO_GET (name)->valnum = VN_TOP;
-         VN_INFO (name)->expr = NULL_TREE;
-         VN_INFO (name)->value_id = 0;
-       }
-    }
-
   renumber_gimple_stmt_uids ();
 
   /* Create the valid and optimistic value numbering tables.  */
@@ -4223,6 +4218,65 @@ init_scc_vn (void)
   allocate_vn_table (valid_info);
   optimistic_info = XCNEW (struct vn_tables_s);
   allocate_vn_table (optimistic_info);
+  current_info = valid_info;
+
+  /* Create the VN_INFO structures, and initialize value numbers to
+     TOP or VARYING for parameters.  */
+  for (i = 1; i < num_ssa_names; i++)
+    {
+      tree name = ssa_name (i);
+      if (!name)
+       continue;
+
+      VN_INFO_GET (name)->valnum = VN_TOP;
+      VN_INFO (name)->expr = NULL_TREE;
+      VN_INFO (name)->value_id = 0;
+
+      if (!SSA_NAME_IS_DEFAULT_DEF (name))
+       continue;
+
+      switch (TREE_CODE (SSA_NAME_VAR (name)))
+       {
+       case VAR_DECL:
+         /* Undefined vars keep TOP.  */
+         break;
+
+       case PARM_DECL:
+         /* Parameters are VARYING but we can record a condition
+            if we know it is a non-NULL pointer.  */
+         VN_INFO (name)->visited = true;
+         VN_INFO (name)->valnum = name; 
+         if (POINTER_TYPE_P (TREE_TYPE (name))
+             && nonnull_arg_p (SSA_NAME_VAR (name)))
+           {
+             tree ops[2];
+             ops[0] = name;
+             ops[1] = build_int_cst (TREE_TYPE (name), 0);
+             vn_nary_op_insert_pieces (2, NE_EXPR, boolean_type_node, ops,
+                                       boolean_true_node, 0);
+             if (dump_file && (dump_flags & TDF_DETAILS))
+               {
+                 fprintf (dump_file, "Recording ");
+                 print_generic_expr (dump_file, name, TDF_SLIM);
+                 fprintf (dump_file, " != 0\n");
+               }
+           }
+         break;
+
+       case RESULT_DECL:
+         /* If the result is passed by invisible reference the default
+            def is initialized, otherwise it's uninitialized.  */
+         if (DECL_BY_REFERENCE (SSA_NAME_VAR (name)))
+           {
+             VN_INFO (name)->visited = true;
+             VN_INFO (name)->valnum = name; 
+           }
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+    }
 }
 
 void
@@ -4444,7 +4547,6 @@ sccvn_dom_walker::before_dom_children (b
          break;
       if (e2 && (e2->flags & EDGE_EXECUTABLE))
        {
-
          gimple stmt = last_stmt (e->src);
          if (stmt
              && gimple_code (stmt) == GIMPLE_COND)
@@ -4577,24 +4679,10 @@ run_scc_vn (vn_lookup_kind default_vn_wa
 {
   basic_block bb;
   size_t i;
-  tree param;
 
   default_vn_walk_kind = default_vn_walk_kind_;
 
   init_scc_vn ();
-  current_info = valid_info;
-
-  for (param = DECL_ARGUMENTS (current_function_decl);
-       param;
-       param = DECL_CHAIN (param))
-    {
-      tree def = ssa_default_def (cfun, param);
-      if (def)
-       {
-         VN_INFO (def)->visited = true;
-         VN_INFO (def)->valnum = def;
-       }
-    }
 
   /* Mark all edges as possibly executable.  */
   FOR_ALL_BB_FN (bb, cfun)

Reply via email to