The following fixes the remaining ICEs I see when testing all
languages (but ada and go).
The tree-cfg.c hunk highlights one change in the behavior
of fold_stmt, namely that it now follows SSA edges by default.
Maybe that's undesired? On a related note, fold_stmt_inplace
preserves the actual statement object gsi_stmt points to,
but in reality callers use it to avoid creating new SSA names
thus would it be ok if fold_stmt_inplace made sure to
preserve the number of statements (and only change what
gsi points to) only?
Bootstrapped / tested on x86_64-unknown-linux-gnu, applied.
Richard.
2014-08-16 Richard Biener rguent...@suse.de
* tree-cfg.c (no_follow_ssa_edges): New function.
(replace_uses_by): Do not follow SSA edges when folding the
stmt.
* gimple-match-head.c (maybe_push_res_to_seq): Disallow
stmts that mention SSA names occuring in abnormal PHIs.
(gimple_simplify): Likewise.
Index: gcc/tree-cfg.c
===
--- gcc/tree-cfg.c (revision 213651)
+++ gcc/tree-cfg.c (working copy)
@@ -1681,6 +1681,14 @@ gimple_can_merge_blocks_p (basic_block a
return true;
}
+/* ??? Maybe this should be a generic overload of fold_stmt. */
+
+static tree
+no_follow_ssa_edges (tree)
+{
+ return NULL_TREE;
+}
+
/* Replaces all uses of NAME by VAL. */
void
@@ -1737,7 +1745,16 @@ replace_uses_by (tree name, tree val)
recompute_tree_invariant_for_addr_expr (op);
}
- if (fold_stmt (gsi))
+ /* If we have sth like
+ neighbor_29 = name + -1;
+ _33 = name + neighbor_29;
+and end up visiting _33 first then folding will
+simplify the stmt to _33 = name; and the new
+immediate use will be inserted before the stmt
+iterator marker and thus we fail to visit it
+again, ICEing within the has_zero_uses assert.
+Avoid that by never following SSA edges. */
+ if (fold_stmt (gsi, no_follow_ssa_edges))
stmt = gsi_stmt (gsi);
if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
Index: gcc/gimple-match-head.c
===
--- gcc/gimple-match-head.c (revision 213651)
+++ gcc/gimple-match-head.c (working copy)
@@ -305,6 +305,17 @@ maybe_push_res_to_seq (code_helper rcode
return NULL_TREE;
if (!res)
res = make_ssa_name (type, NULL);
+ /* Play safe and do not allow abnormals to be mentioned in
+ newly created statements. */
+ if ((TREE_CODE (ops[0]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+ || (ops[1]
+ TREE_CODE (ops[1]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+ || (ops[2]
+ TREE_CODE (ops[2]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+ return NULL_TREE;
gimple new_stmt = gimple_build_assign_with_ops (rcode, res,
ops[0], ops[1], ops[2]);
gimple_seq_add_stmt_without_update (seq, new_stmt);
@@ -321,6 +332,17 @@ maybe_push_res_to_seq (code_helper rcode
res = make_ssa_name (type, NULL);
unsigned nargs = type_num_arguments (TREE_TYPE (decl));
gcc_assert (nargs = 3);
+ /* Play safe and do not allow abnormals to be mentioned in
+ newly created statements. */
+ if ((TREE_CODE (ops[0]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+ || (nargs = 2
+ TREE_CODE (ops[1]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+ || (nargs == 3
+ TREE_CODE (ops[2]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
+ return NULL_TREE;
gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1],
ops[2]);
gimple_call_set_lhs (new_stmt, res);
gimple_seq_add_stmt_without_update (seq, new_stmt);
@@ -414,8 +436,8 @@ gimple_simplify (enum tree_code code, tr
tree
gimple_simplify (enum built_in_function fn, tree type,
- tree arg0,
- gimple_seq *seq, tree (*valueize)(tree))
+tree arg0,
+gimple_seq *seq, tree (*valueize)(tree))
{
if (constant_for_folding (arg0))
{
@@ -683,6 +705,17 @@ gimple_simplify (gimple_stmt_iterator *g
if (is_gimple_assign (stmt)
rcode.is_tree_code ())
{
+ /* Play safe and do not allow abnormals to be mentioned in
+ newly created statements. */
+ if ((TREE_CODE (ops[0]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
+ || (ops[1]
+ TREE_CODE (ops[1]) == SSA_NAME
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
+ || (ops[2]
+ TREE_CODE (ops[2]) == SSA_NAME
+