+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
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. */
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
break;
if (e2 && (e2->flags & EDGE_EXECUTABLE))
{
-
gimple stmt = last_stmt (e->src);
if (stmt
&& gimple_code (stmt) == GIMPLE_COND)
{
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)
}
-/* 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
}
}
+
+/* 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"
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 */