From f56e675de51d00f2ddaede1933175374628f6952 Mon Sep 17 00:00:00 2001 From: Tomas Bily Date: Mon, 12 Jan 2009 16:37:09 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 ++ gcc/testsuite/gcc.dg/tree-ssa/pr38385.c | 124 ++++++++++++++++++++++++++++++++ gcc/tree-loop-distribution.c | 33 +++++++++ 3 files changed, 164 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr38385.c 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 + + 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 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..745957f 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); -- 2.7.4