-2005-04-23 Steven Bosscher <stevenb@suse.de>
-
- PR tree-optimization/21173
- PR tree-optimization/21167
- * tree-ssa-pre.c (create_expression_by_pieces): Fix tcc_unary case if
- GENOP1 is invariant. Avoid code duplication.
-
- * gcc.c-torture/compile/20050423-2.c: New test.
- * gcc.c-torture/execute/20050423-1.c: New test.
-
---- gcc/tree-ssa-pre.c.jj 2005-04-23 21:55:45.000000000 +0200
-+++ gcc/tree-ssa-pre.c 2005-04-23 21:57:00.000000000 +0200
-@@ -1308,125 +1308,98 @@ find_or_generate_expression (basic_block
- static tree
- create_expression_by_pieces (basic_block block, tree expr, tree stmts)
- {
-- tree name = NULL_TREE;
-- tree newexpr = NULL_TREE;
-+ tree temp, name;
-+ tree folded, forced_stmts, newexpr;
- tree v;
--
-+ tree_stmt_iterator tsi;
-+
- switch (TREE_CODE_CLASS (TREE_CODE (expr)))
- {
- case tcc_binary:
- {
-- tree_stmt_iterator tsi;
-- tree forced_stmts;
-- tree genop1, genop2;
-- tree temp;
-- tree folded;
- tree op1 = TREE_OPERAND (expr, 0);
- tree op2 = TREE_OPERAND (expr, 1);
-- genop1 = find_or_generate_expression (block, op1, stmts);
-- genop2 = find_or_generate_expression (block, op2, stmts);
-- temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
-- add_referenced_tmp_var (temp);
--
-+ tree genop1 = find_or_generate_expression (block, op1, stmts);
-+ tree genop2 = find_or_generate_expression (block, op2, stmts);
+===================================================================
+RCS file: /cvs/gcc/gcc/gcc/tree-ssa-pre.c,v
+retrieving revision 2.65.4.2
+retrieving revision 2.65.4.3
+diff -u -r2.65.4.2 -r2.65.4.3
+--- gcc/gcc/tree-ssa-pre.c 2005/04/17 23:40:31 2.65.4.2
++++ gcc/gcc/tree-ssa-pre.c 2005/04/25 14:02:31 2.65.4.3
+@@ -1330,7 +1330,8 @@
+
folded = fold (build (TREE_CODE (expr), TREE_TYPE (expr),
genop1, genop2));
- newexpr = force_gimple_operand (folded, &forced_stmts, false, NULL);
-- if (forced_stmts)
-- {
-- tsi = tsi_start (forced_stmts);
-- for (; !tsi_end_p (tsi); tsi_next (&tsi))
-- {
-- tree stmt = tsi_stmt (tsi);
-- tree forcedname = TREE_OPERAND (stmt, 0);
-- tree forcedexpr = TREE_OPERAND (stmt, 1);
-- tree val = vn_lookup_or_add (forcedexpr, NULL);
-- vn_add (forcedname, val, NULL);
-- bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
-- bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
-- }
--
-- tsi = tsi_last (stmts);
-- tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
-- }
-- newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
-- temp, newexpr);
-- NECESSARY (newexpr) = 0;
-- name = make_ssa_name (temp, newexpr);
-- TREE_OPERAND (newexpr, 0) = name;
-- tsi = tsi_last (stmts);
-- tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
-- VEC_safe_push (tree_on_heap, inserted_exprs, newexpr);
-- pre_stats.insertions++;
- break;
- }
-+
- case tcc_unary:
- {
-- tree_stmt_iterator tsi;
-- tree forced_stmts = NULL;
-- tree genop1;
-- tree temp;
-- tree folded;
- tree op1 = TREE_OPERAND (expr, 0);
-- genop1 = find_or_generate_expression (block, op1, stmts);
-- temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
-- add_referenced_tmp_var (temp);
-+ tree genop1 = find_or_generate_expression (block, op1, stmts);
++ newexpr = force_gimple_operand (unshare_expr (folded),
++ &forced_stmts, false, NULL);
+ if (forced_stmts)
+ {
+ tsi = tsi_start (forced_stmts);
+@@ -1372,14 +1373,8 @@
+ add_referenced_tmp_var (temp);
folded = fold (build (TREE_CODE (expr), TREE_TYPE (expr),
genop1));
- /* If the generated operand is already GIMPLE min_invariant
- newexpr = force_gimple_operand (folded, &forced_stmts, false, NULL);
- else
- newexpr = genop1;
-- if (forced_stmts)
-- {
-- tsi = tsi_start (forced_stmts);
-- for (; !tsi_end_p (tsi); tsi_next (&tsi))
-- {
-- tree stmt = tsi_stmt (tsi);
-- tree forcedname = TREE_OPERAND (stmt, 0);
-- tree forcedexpr = TREE_OPERAND (stmt, 1);
-- tree val = vn_lookup_or_add (forcedexpr, NULL);
-- vn_add (forcedname, val, NULL);
-- bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
-- bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
-- }
-- tsi = tsi_last (stmts);
-- tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
-- }
-- newexpr = build (MODIFY_EXPR, TREE_TYPE (expr),
-- temp, newexpr);
-- name = make_ssa_name (temp, newexpr);
-- TREE_OPERAND (newexpr, 0) = name;
-- NECESSARY (newexpr) = 0;
-- tsi = tsi_last (stmts);
-- tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
-- VEC_safe_push (tree_on_heap, inserted_exprs, newexpr);
-- pre_stats.insertions++;
--
- break;
- }
-+
- default:
- gcc_unreachable ();
--
- }
-- v = get_value_handle (expr);
-- vn_add (name, v, NULL);
-
-- /* The value may already exist in either NEW_SETS, or AVAIL_OUT, because
-+ /* If the generated expression is already a valid GIMPLE rhs that can
-+ be assigned to TEMP. just use it as-is. Otherwise, we will have to
-+ call force_gimple_operand on it, and add intermediate expressions
-+ to the value sets as well. */
-+ if (is_gimple_reg_rhs (folded))
-+ newexpr = folded;
-+ else
-+ {
-+ newexpr = force_gimple_operand (folded, &forced_stmts, false, NULL);
-+
-+ /* If we have any intermediate expressions to the value sets,
-+ add them to the value sets and chain them on in the instruction
-+ stream. */
-+ if (forced_stmts)
-+ {
-+ tsi = tsi_start (forced_stmts);
-+ for (; !tsi_end_p (tsi); tsi_next (&tsi))
-+ {
-+ tree stmt = tsi_stmt (tsi);
-+ tree forcedname = TREE_OPERAND (stmt, 0);
-+ tree forcedexpr = TREE_OPERAND (stmt, 1);
-+ tree val = vn_lookup_or_add (forcedexpr, NULL);
-+ vn_add (forcedname, val, NULL);
-+ bitmap_value_replace_in_set (NEW_SETS (block), forcedname);
-+ bitmap_value_replace_in_set (AVAIL_OUT (block), forcedname);
-+ }
-+ tsi = tsi_last (stmts);
-+ tsi_link_after (&tsi, forced_stmts, TSI_CONTINUE_LINKING);
-+ }
-+ }
-+
-+ /* Build and insert the assignment of the end result to the temporary
-+ that we will return. */
-+ temp = create_tmp_var (TREE_TYPE (expr), "pretmp");
-+ add_referenced_tmp_var (temp);
-+ newexpr = build (MODIFY_EXPR, TREE_TYPE (expr), temp, newexpr);
-+ name = make_ssa_name (temp, newexpr);
-+ TREE_OPERAND (newexpr, 0) = name;
-+ NECESSARY (newexpr) = 0;
-+ tsi = tsi_last (stmts);
-+ tsi_link_after (&tsi, newexpr, TSI_CONTINUE_LINKING);
-+ VEC_safe_push (tree_on_heap, inserted_exprs, newexpr);
-+
-+ /* Add a value handle to the temprorary.
-+ The value may already exist in either NEW_SETS, or AVAIL_OUT, because
- we are creating the expression by pieces, and this particular piece of
- the expression may have been represented. There is no harm in replacing
- here. */
-+ v = get_value_handle (expr);
-+ vn_add (name, v, NULL);
- bitmap_value_replace_in_set (NEW_SETS (block), name);
- bitmap_value_replace_in_set (AVAIL_OUT (block), name);
-+
-+ pre_stats.insertions++;
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Inserted ");
- print_generic_expr (dump_file, newexpr, 0);
- fprintf (dump_file, " in predecessor %d\n", block->index);
- }
-+
- return name;
- }
-
---- gcc/testsuite/gcc.c-torture/compile/20050423-2.c 2005-04-07 15:51:53.775361896 +0200
-+++ gcc/testsuite/gcc.c-torture/compile/20050423-2.c 2005-04-23 19:47:22.000000000 +0200
-@@ -0,0 +1,21 @@
-+/* PR tree-optimization/21167 */
-+
-+extern const char *f_extensions[];
-+const char *f_extensions[] = { ".cnf", 0 };
-+void f (void);
-+
-+int
-+g (int ij)
-+{
-+ char **tmp_ext;
-+ unsigned i;
-+
-+ for (i = 0; i < (unsigned) ij; i++)
-+ {
-+ f ();
-+ tmp_ext = (char **) &f_extensions[0];
-+ if (*tmp_ext)
-+ return 0;
-+ }
-+ return 1;
-+}
---- gcc/testsuite/gcc.c-torture/execute/20050423-1.c 2005-04-07 15:51:53.775361896 +0200
-+++ gcc/testsuite/gcc.c-torture/execute/20050423-1.c 2005-04-23 19:48:05.000000000 +0200
-@@ -0,0 +1,24 @@
-+/* PR tree-optimization/21173 */
-+void abort (void);
-+
-+char q;
-+void *a[2];
-+
-+void
-+foo (char *p)
-+{
-+ int i;
-+ for (i = 0; i < 2; i++)
-+ a[i] += p - &q;
-+}
-+
-+int
-+main (void)
-+{
-+ int i;
-+ foo (&q);
-+ for (i = 0; i < 2; i++)
-+ if (a[i])
-+ abort ();
-+ return 0;
-+}
++ newexpr = force_gimple_operand (unshare_expr (folded),
++ &forced_stmts, false, NULL);
+ if (forced_stmts)
+ {
+ tsi = tsi_start (forced_stmts);