abstract gimple_call_nonnull*() from vr-values

Message ID 3a4b09cc-e333-ea6a-2e76-1e6a3ae35388@redhat.com
State New
Headers show
Series
  • abstract gimple_call_nonnull*() from vr-values
Related show

Commit Message

Aldy Hernandez July 10, 2018, 10:14 a.m.
Ho hum, more abstractions.

No change in functionality.

OK for trunk?

Comments

Richard Biener July 11, 2018, 12:44 p.m. | #1
On Tue, Jul 10, 2018 at 12:14 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> Ho hum, more abstractions.
>
> No change in functionality.
>
> OK for trunk?

OK.  Bonus points for finding the copy I vaguely remember exists somewhere...

Richard.

Patch

gcc/

        * vr-values.c (gimple_stmt_nonzero_p): Abstract common code to...
        * gimple.c (gimple_call_nonnull_result_p): ...here...
        (gimple_call_nonnull_arg): ...and here.
        * gimple.h (gimple_call_nonnull_result_p): New.
        (gimple_call_nonnull_arg): New.

diff --git a/gcc/gimple.c b/gcc/gimple.c
index afdf583256c..8d56a966cc1 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1548,6 +1548,57 @@  gimple_call_return_flags (const gcall *stmt)
 }
 
 
+/* Return true if call STMT is known to return a non-zero result.  */
+
+bool
+gimple_call_nonnull_result_p (gcall *call)
+{
+  tree fndecl = gimple_call_fndecl (call);
+  if (!fndecl)
+    return false;
+  if (flag_delete_null_pointer_checks && !flag_check_new
+      && DECL_IS_OPERATOR_NEW (fndecl)
+      && !TREE_NOTHROW (fndecl))
+    return true;
+
+  /* References are always non-NULL.  */
+  if (flag_delete_null_pointer_checks
+      && TREE_CODE (TREE_TYPE (fndecl)) == REFERENCE_TYPE)
+    return true;
+
+  if (flag_delete_null_pointer_checks
+      && lookup_attribute ("returns_nonnull",
+			   TYPE_ATTRIBUTES (gimple_call_fntype (call))))
+    return true;
+  return gimple_alloca_call_p (call);
+}
+
+
+/* If CALL returns a non-null result in an argument, return that arg.  */
+
+tree
+gimple_call_nonnull_arg (gcall *call)
+{
+  tree fndecl = gimple_call_fndecl (call);
+  if (!fndecl)
+    return NULL_TREE;
+
+  unsigned rf = gimple_call_return_flags (call);
+  if (rf & ERF_RETURNS_ARG)
+    {
+      unsigned argnum = rf & ERF_RETURN_ARG_MASK;
+      if (argnum < gimple_call_num_args (call))
+	{
+	  tree arg = gimple_call_arg (call, argnum);
+	  if (SSA_VAR_P (arg)
+	      && infer_nonnull_range_by_attribute (call, arg))
+	    return arg;
+	}
+    }
+  return NULL_TREE;
+}
+
+
 /* Return true if GS is a copy assignment.  */
 
 bool
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 32e1908c534..a5dda9369bc 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1488,6 +1488,8 @@  bool gimple_call_same_target_p (const gimple *, const gimple *);
 int gimple_call_flags (const gimple *);
 int gimple_call_arg_flags (const gcall *, unsigned);
 int gimple_call_return_flags (const gcall *);
+bool gimple_call_nonnull_result_p (gcall *);
+tree gimple_call_nonnull_arg (gcall *);
 bool gimple_assign_copy_p (gimple *);
 bool gimple_assign_ssa_name_copy_p (gimple *);
 bool gimple_assign_unary_nop_p (gimple *);
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 32f64e047af..bba170f341b 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -313,35 +313,9 @@  gimple_stmt_nonzero_p (gimple *stmt)
       return gimple_assign_nonzero_p (stmt);
     case GIMPLE_CALL:
       {
-	tree fndecl = gimple_call_fndecl (stmt);
-	if (!fndecl) return false;
-	if (flag_delete_null_pointer_checks && !flag_check_new
-	    && DECL_IS_OPERATOR_NEW (fndecl)
-	    && !TREE_NOTHROW (fndecl))
-	  return true;
-	/* References are always non-NULL.  */
-	if (flag_delete_null_pointer_checks
-	    && TREE_CODE (TREE_TYPE (fndecl)) == REFERENCE_TYPE)
-	  return true;
-	if (flag_delete_null_pointer_checks && 
-	    lookup_attribute ("returns_nonnull",
-			      TYPE_ATTRIBUTES (gimple_call_fntype (stmt))))
-	  return true;
-
-	gcall *call_stmt = as_a<gcall *> (stmt);
-	unsigned rf = gimple_call_return_flags (call_stmt);
-	if (rf & ERF_RETURNS_ARG)
-	  {
-	    unsigned argnum = rf & ERF_RETURN_ARG_MASK;
-	    if (argnum < gimple_call_num_args (call_stmt))
-	      {
-		tree arg = gimple_call_arg (call_stmt, argnum);
-		if (SSA_VAR_P (arg)
-		    && infer_nonnull_range_by_attribute (stmt, arg))
-		  return true;
-	      }
-	  }
-	return gimple_alloca_call_p (stmt);
+        gcall *call_stmt = as_a<gcall *> (stmt);
+	return (gimple_call_nonnull_result_p (call_stmt)
+		|| gimple_call_nonnull_arg (call_stmt));
       }
     default:
       gcc_unreachable ();