+2015-10-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/67891
+ * gimple-match.h (gimple_simplified_result_is_gimple_val):
+ New helper.
+ (gimple_resimplify1): Declare.
+ (gimple_resimplify2): Likewise.
+ (gimple_resimplify3): Likewise.
+ * gimple-match-head.c (gimple_resimplify1): Export.
+ (gimple_resimplify2): Likewise.
+ (gimple_resimplify3): Likewise.
+ (maybe_push_res_to_seq): Use gimple_simplified_result_is_gimple_val.
+ * gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
+ * tree-ssa-sccvn.c (visit_reference_op_load): Use gimple_resimplify1
+ to avoid creating stmts without VN info.
+
2015-10-08 Jan Hubicka <hubicka@ucw.cz>
* ipa-icf.c (sem_item::compare_symbol_references): Fix use
if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize))
{
tree res = NULL_TREE;
- if (rcode.is_tree_code ()
- && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
- || ((tree_code) rcode) == ADDR_EXPR)
- && is_gimple_val (ops[0]))
+ if (gimple_simplified_result_is_gimple_val (rcode, ops))
res = ops[0];
else if (mprts_hook)
res = mprts_hook (rcode, gimple_expr_type (stmt), ops);
*RES_CODE and *RES_OPS with a simplified and/or canonicalized
result and returns whether any change was made. */
-static bool
+bool
gimple_resimplify1 (gimple_seq *seq,
code_helper *res_code, tree type, tree *res_ops,
tree (*valueize)(tree))
*RES_CODE and *RES_OPS with a simplified and/or canonicalized
result and returns whether any change was made. */
-static bool
+bool
gimple_resimplify2 (gimple_seq *seq,
code_helper *res_code, tree type, tree *res_ops,
tree (*valueize)(tree))
*RES_CODE and *RES_OPS with a simplified and/or canonicalized
result and returns whether any change was made. */
-static bool
+bool
gimple_resimplify3 (gimple_seq *seq,
code_helper *res_code, tree type, tree *res_ops,
tree (*valueize)(tree))
if (rcode.is_tree_code ())
{
if (!res
- && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
- || ((tree_code) rcode) == ADDR_EXPR)
- && is_gimple_val (ops[0]))
+ && gimple_simplified_result_is_gimple_val (rcode, ops))
return ops[0];
if (mprts_hook)
{
int rep;
};
+/* Return whether OPS[0] with CODE is a non-expression result and
+ a gimple value. */
+
+inline bool
+gimple_simplified_result_is_gimple_val (code_helper code, tree *ops)
+{
+ return (code.is_tree_code ()
+ && (TREE_CODE_LENGTH ((tree_code) code) == 0
+ || ((tree_code) code) == ADDR_EXPR)
+ && is_gimple_val (ops[0]));
+}
+
extern tree (*mprts_hook) (code_helper, tree, tree *);
bool gimple_simplify (gimple *, code_helper *, tree *, gimple_seq *,
tree (*)(tree), tree (*)(tree));
+bool gimple_resimplify1 (gimple_seq *, code_helper *, tree, tree *,
+ tree (*)(tree));
+bool gimple_resimplify2 (gimple_seq *, code_helper *, tree, tree *,
+ tree (*)(tree));
+bool gimple_resimplify3 (gimple_seq *, code_helper *, tree, tree *,
+ tree (*)(tree));
tree maybe_push_res_to_seq (code_helper, tree, tree *,
gimple_seq *, tree res = NULL_TREE);
void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
+2015-10-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/67891
+ * gcc.dg/tree-ssa/pr67891.c: New testcase.
+
2015-10-08 Richard Sandiford <richard.sandiford@arm.com>
* gcc.dg/builtins-47.c: Test the optimized dump instead.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+unsigned int a, *b;
+unsigned short c;
+int d;
+
+void
+fn1 ()
+{
+ b = &d;
+ *b = c = a;
+ *b = d;
+}
+
+/* We should remove all loads but that from a. */
+/* { dg-final { scan-tree-dump-not "= \[dbc\];" "fre1" } } */
of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
So first simplify and lookup this expression to see if it
is already available. */
- gimple_seq stmts = NULL;
mprts_hook = vn_lookup_simplify_result;
- tree val = gimple_simplify (VIEW_CONVERT_EXPR, TREE_TYPE (op),
- result, &stmts, vn_valueize);
+ code_helper rcode = VIEW_CONVERT_EXPR;
+ tree ops[3] = { result };
+ bool res = gimple_resimplify1 (NULL, &rcode, TREE_TYPE (op), ops,
+ vn_valueize);
mprts_hook = NULL;
- if (!val)
+ gimple *new_stmt = NULL;
+ if (res
+ && gimple_simplified_result_is_gimple_val (rcode, ops))
+ /* The expression is already available. */
+ result = ops[0];
+ else
{
- val = vn_nary_op_lookup_pieces (1, VIEW_CONVERT_EXPR,
- TREE_TYPE (op), &result, NULL);
+ tree val = vn_lookup_simplify_result (rcode, TREE_TYPE (op), ops);
if (!val)
{
- val = make_ssa_name (TREE_TYPE (op));
- gimple *new_stmt = gimple_build_assign (val, VIEW_CONVERT_EXPR,
- build1 (VIEW_CONVERT_EXPR,
- TREE_TYPE (op),
- result));
- gimple_seq_add_stmt_without_update (&stmts, new_stmt);
+ gimple_seq stmts = NULL;
+ result = maybe_push_res_to_seq (rcode, TREE_TYPE (op), ops,
+ &stmts);
+ gcc_assert (result && gimple_seq_singleton_p (stmts));
+ new_stmt = gimple_seq_first_stmt (stmts);
}
+ else
+ /* The expression is already available. */
+ result = val;
}
- if (gimple_seq_empty_p (stmts))
- /* The expression is already available. */
- result = val;
- else
+ if (new_stmt)
{
- gcc_assert (gimple_seq_singleton_p (stmts));
/* The expression is not yet available, value-number lhs to
the new SSA_NAME we created. */
- result = val;
/* Initialize value-number information properly. */
VN_INFO_GET (result)->valnum = result;
VN_INFO (result)->value_id = get_next_value_id ();
- VN_INFO (result)->expr = stmts;
+ gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
+ new_stmt);
VN_INFO (result)->needs_insertion = true;
/* As all "inserted" statements are singleton SCCs, insert
to the valid table. This is strictly needed to
if (current_info == optimistic_info)
{
current_info = valid_info;
- vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
+ vn_nary_op_insert_stmt (new_stmt, result);
current_info = optimistic_info;
}
else
- vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
+ vn_nary_op_insert_stmt (new_stmt, result);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Inserting name ");
print_generic_expr (dump_file, result, 0);
fprintf (dump_file, " for expression ");
- print_gimple_expr (dump_file, gimple_seq_first_stmt (stmts),
- 0, TDF_SLIM);
+ print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
fprintf (dump_file, "\n");
}
}