tree.c (nonnull_arg_p): Move from ...
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. From-SVN: r226861
This commit is contained in:
parent
2ef38880ef
commit
34c896978b
5 changed files with 134 additions and 90 deletions
|
@ -1,3 +1,13 @@
|
|||
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.
|
||||
|
||||
2015-08-13 Robert Suchanek <robert.suchanek@imgtec.com>
|
||||
|
||||
* config/mips/mips.h (ENABLE_LD_ST_PAIRS): Enable load/store pairs for
|
||||
|
|
|
@ -4203,19 +4203,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 +4210,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
|
||||
|
@ -4447,7 +4493,6 @@ sccvn_dom_walker::before_dom_children (basic_block bb)
|
|||
break;
|
||||
if (e2 && (e2->flags & EDGE_EXECUTABLE))
|
||||
{
|
||||
|
||||
gimple stmt = last_stmt (e->src);
|
||||
if (stmt
|
||||
&& gimple_code (stmt) == GIMPLE_COND)
|
||||
|
@ -4573,24 +4618,10 @@ run_scc_vn (vn_lookup_kind default_vn_walk_kind_)
|
|||
{
|
||||
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)
|
||||
|
|
|
@ -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
|
||||
|
|
63
gcc/tree.c
63
gcc/tree.c
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue