From: Richard Biener Date: Thu, 13 Aug 2015 12:34:36 +0000 (+0000) Subject: tree.c (nonnull_arg_p): Move from ... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34c896978b84baf64f51a11fe8382038e46c058d;p=gcc.git tree.c (nonnull_arg_p): Move from ... 2015-08-13 Richard Biener * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d97d32bb9b2..477335dfb60 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-08-13 Richard Biener + + * 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 * config/mips/mips.h (ENABLE_LD_ST_PAIRS): Enable load/store pairs for diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index d4c2b46316c..a72a9208f07 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -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) diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 0439272b97d..685eb726a0d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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 diff --git a/gcc/tree.c b/gcc/tree.c index 3c2c20a82b4..af3a6a340e4 100644 --- a/gcc/tree.c +++ b/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" diff --git a/gcc/tree.h b/gcc/tree.h index d280ea7fae5..2cd6ec475a8 100644 --- a/gcc/tree.h +++ b/gcc/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 */