diff mbox

Use non-nullness of parameters in SCCVN

Message ID alpine.LSU.2.11.1508131432370.19998@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Aug. 13, 2015, 12:33 p.m. UTC
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  <rguenther@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.
diff mbox

Patch

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)