* 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.
From-SVN: r262557
+2018-07-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * 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.
+
2018-07-11 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm-cpus.in: Move information from fpu field of each
}
+/* 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
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 *);
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 ();