aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTomas Bily <tbily@suse.cz>2009-01-12 16:37:09 +0100
committerTomas Bily <tomby@gcc.gnu.org>2009-01-12 16:37:09 +0100
commitf56e675de51d00f2ddaede1933175374628f6952 (patch)
treee1e3f644a0682e8328a8ea1037b43d04118503c4 /gcc
parentc2152239ace246c45e1ec2b50af196762d18782a (diff)
downloadgcc-f56e675de51d00f2ddaede1933175374628f6952.zip
gcc-f56e675de51d00f2ddaede1933175374628f6952.tar.gz
gcc-f56e675de51d00f2ddaede1933175374628f6952.tar.bz2
re PR tree-optimization/38385 (ICE with -O2 -ftree-loop-distribution)
PR middlend/38385 * tree-loop-distribution.c (prop_phis): New function. (generate_builtin): Call prop_phis. * testsuite/gcc.dg/tree-ssa/pr38385.c: New file. From-SVN: r143291
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr38385.c124
-rw-r--r--gcc/tree-loop-distribution.c33
3 files changed, 164 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 715cbfb..ebe85fa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2009-01-12 Tomas Bily <tbily@suse.cz>
+
+ PR middlend/38385
+ * tree-loop-distribution.c (prop_phis): New function.
+ (generate_builtin): Call prop_phis.
+ * testsuite/gcc.dg/tree-ssa/pr38385.c: New file.
+
2009-01-12 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/38807
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr38385.c b/gcc/testsuite/gcc.dg/tree-ssa/pr38385.c
new file mode 100644
index 0000000..a49c93e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr38385.c
@@ -0,0 +1,124 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution" } */
+
+struct rtx_def
+{
+ int a;
+};
+
+typedef struct rtx_def *rtx;
+
+struct rd {
+ int alternative_enabled_p[100];
+ rtx operand[100];
+ int n_operands;
+};
+
+rtx this_insn;
+int n_reloads;
+int n_replacements;
+int n_earlyclobbers;
+int replace_reloads;
+int hard_regs_live_known;
+short* static_reload_reg_p;
+struct rd recog_data;
+
+int
+find_reloads (rtx insn, int replace, int ind_levels, int live_known,
+ short *reload_reg_p)
+{
+ int i, j;
+ int noperands = replace;
+
+ int no_input_reloads = 0;
+ int n_alternatives = replace;
+ char this_alternative_match_win[30];
+ char this_alternative_win[30];
+ char this_alternative_earlyclobber[30];
+ int this_alternative_matches[30];
+ int goal_alternative[30];
+ int this_alternative_number;
+
+ char goal_alternative_match_win[30];
+ char goal_alternative_win[30];
+ int best;
+
+ int operand_mode[30];
+ int retval = 0;
+
+ for (this_alternative_number = 0;
+ this_alternative_number < n_alternatives;
+ this_alternative_number++)
+ {
+
+ int losers = 0;
+ int bad = 0;
+
+ if (!recog_data.alternative_enabled_p[this_alternative_number])
+ {
+ int i;
+
+ for (i = 0; i < recog_data.n_operands; i++)
+ ;
+
+ continue;
+ }
+
+ for (i = 0; i < noperands; i++)
+ if (this_alternative_earlyclobber[i]
+ && (this_alternative_win[i] || this_alternative_match_win[i]))
+ {
+ if (j != noperands)
+ {
+ losers++;
+
+ for (j = 0; j < noperands; j++)
+ if (this_alternative_matches[j] == i
+ && this_alternative_match_win[j])
+ {
+ this_alternative_win[j] = 0;
+ this_alternative_match_win[j] = 0;
+ losers++;
+ }
+ }
+ }
+
+ if (losers == 0)
+ {
+ for (i = 0; i < noperands; i++)
+ {
+ goal_alternative_win[i] = 0;
+ goal_alternative_match_win[i] = 0;
+ }
+
+ goto finish;
+ }
+
+ if (! bad && best > losers)
+ {
+ for (i = 0; i < noperands; i++)
+ {
+ goal_alternative[i] = 0;
+ goal_alternative_win[i] = 0;
+ }
+ }
+ }
+
+
+ finish:
+
+ for (i = 0; i < noperands; i++)
+ if (! goal_alternative_win[i])
+ {
+ rtx op = recog_data.operand[i];
+ int mode = operand_mode[i];
+
+ if (((ix86_preferred_reload_class ((op), (goal_alternative[i])) == 2)
+ || no_input_reloads)
+ && mode != 0)
+ {}
+ }
+
+ return retval;
+}
+
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 062ab48..745957fc 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -331,6 +331,38 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
return res;
}
+/* Propagate phis in BB b to their uses and remove them. */
+
+static void
+prop_phis (basic_block b)
+{
+ gimple_stmt_iterator psi;
+ gimple_seq phis = phi_nodes (b);
+
+ for (psi = gsi_start (phis); !gsi_end_p (psi); )
+ {
+ gimple phi = gsi_stmt (psi);
+ tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
+
+ gcc_assert (gimple_phi_num_args (phi) == 1);
+
+ if (!is_gimple_reg (def))
+ {
+ imm_use_iterator iter;
+ use_operand_p use_p;
+ gimple stmt;
+
+ FOR_EACH_IMM_USE_STMT (stmt, iter, def)
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, use);
+ }
+ else
+ replace_uses_by (def, use);
+
+ remove_phi_node (&psi, true);
+ }
+}
+
/* Tries to generate a builtin function for the instructions of LOOP
pointed to by the bits set in PARTITION. Returns true when the
operation succeeded. */
@@ -400,6 +432,7 @@ generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
unsigned nbbs = loop->num_nodes;
basic_block src = loop_preheader_edge (loop)->src;
basic_block dest = single_exit (loop)->dest;
+ prop_phis (dest);
make_edge (src, dest, EDGE_FALLTHRU);
set_immediate_dominator (CDI_DOMINATORS, dest, src);
cancel_loop_tree (loop);