From 7002f3bd9ce16ae52d452718fc44b18572d31169 Mon Sep 17 00:00:00 2001 From: Igor Zamyatin Date: Tue, 20 Jan 2015 08:29:09 +0000 Subject: [PATCH] re PR bootstrap/64676 (SEGV in tree-ssa-structalias.c solve_constraint) gcc/ PR bootstrap/64676 Revert: 2015-01-19 Igor Zamyatin PR rtl-optimization/64081 * loop-iv.c (def_pred_latch_p): New function. (latch_dominating_def): Allow specific cases with non-single definitions. (iv_get_reaching_def): Likewise. (check_complex_exit_p): New function. (check_simple_exit): Use check_complex_exit_p to allow certain cases with exits not executing on any iteration. gcc/testsuite/ PR bootstrap/64676 Revert: 2014-01-19 Igor Zamyatin PR rtl-optimization/64081 * gcc.dg/pr64081.c: New test. From-SVN: r219880 --- gcc/ChangeLog | 15 ++++ gcc/loop-iv.c | 127 ++++----------------------------- gcc/testsuite/ChangeLog | 9 +++ gcc/testsuite/gcc.dg/pr64081.c | 41 ----------- 4 files changed, 39 insertions(+), 153 deletions(-) delete mode 100644 gcc/testsuite/gcc.dg/pr64081.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7adefef3e02..1879743fd0c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2015-01-20 Igor Zamyatin + + PR bootstrap/64676 + Revert: + 2015-01-19 Igor Zamyatin + + PR rtl-optimization/64081 + * loop-iv.c (def_pred_latch_p): New function. + (latch_dominating_def): Allow specific cases with non-single + definitions. + (iv_get_reaching_def): Likewise. + (check_complex_exit_p): New function. + (check_simple_exit): Use check_complex_exit_p to allow certain cases + with exits not executing on any iteration. + 2015-01-19 Jan Hubicka PR lto/45375 diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 7b2116c61a2..de2b15a8fef 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -332,72 +332,34 @@ iv_analysis_loop_init (struct loop *loop) check_iv_ref_table_size (); } -/* Return true if D_REF is defined in an immediate predecessor of the - current loop's latch block. Otherwise return false. */ - -static bool -def_pred_latch_p (df_ref d_ref) -{ - basic_block bb = DF_REF_BB (d_ref); - edge_iterator ei; - edge e; - - FOR_EACH_EDGE (e, ei, current_loop->latch->preds) - { - if (e->src == bb) - return true; - } - return false; -} - /* Finds the definition of REG that dominates loop latch and stores it to DEF. Returns false if there is not a single definition - dominating the latch or all defs are same and they are on different - predecessors of loop latch. If REG has no definition in loop, DEF + dominating the latch. If REG has no definition in loop, DEF is set to NULL and true is returned. */ static bool latch_dominating_def (rtx reg, df_ref *def) { df_ref single_rd = NULL, adef; - unsigned regno = REGNO (reg), def_num = 0; + unsigned regno = REGNO (reg); struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch); for (adef = DF_REG_DEF_CHAIN (regno); adef; adef = DF_REF_NEXT_REG (adef)) { - /* Initialize this to true for the very first iteration when - SINGLE_RD is NULL. */ - bool def_pred_latch = true; - if (!bitmap_bit_p (df->blocks_to_analyze, DF_REF_BBNO (adef)) || !bitmap_bit_p (&bb_info->out, DF_REF_ID (adef))) continue; - /* More than one reaching definition is ok in case definitions are - in predecessors of latch block and those definitions are the same. - Probably this could be relaxed and check for sub-dominance instead - predecessor. */ - def_num++; + /* More than one reaching definition. */ if (single_rd) - { - if (!(def_pred_latch = def_pred_latch_p (adef)) - || !rtx_equal_p (PATTERN (DF_REF_INSN (single_rd)), - PATTERN (DF_REF_INSN (adef)))) - return false; - } + return false; + + if (!just_once_each_iteration_p (current_loop, DF_REF_BB (adef))) + return false; single_rd = adef; } - /* If we have single definition it has to be executed on each iteration. */ - if ((def_num == 1) && single_rd - && !just_once_each_iteration_p (current_loop, DF_REF_BB (single_rd))) - return false; - - /* Make sure all preds contain definitions. */ - if (def_num != EDGE_COUNT (current_loop->latch->preds)) - return false; - *def = single_rd; return true; } @@ -407,10 +369,10 @@ latch_dominating_def (rtx reg, df_ref *def) static enum iv_grd_result iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def) { - df_ref use, adef = NULL; + df_ref use, adef; basic_block def_bb, use_bb; rtx_insn *def_insn; - bool dom_p, dom_latch_p = false; + bool dom_p; *def = NULL; if (!simple_reg_p (reg)) @@ -425,26 +387,11 @@ iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def) if (!DF_REF_CHAIN (use)) return GRD_INVARIANT; - adef = DF_REF_CHAIN (use)->ref; - /* Having more than one reaching def is ok once all defs are in blocks which - are latch's predecessors. */ + /* More than one reaching def. */ if (DF_REF_CHAIN (use)->next) - { - df_link* defs; - unsigned int def_num = 0; - - for (defs = DF_REF_CHAIN (use); defs; defs = defs->next) - { - if (!def_pred_latch_p (defs->ref)) - return GRD_INVALID; - def_num++; - } - /* Make sure all preds contain definitions. */ - if (def_num != EDGE_COUNT (current_loop->latch->preds)) - return GRD_INVALID; + return GRD_INVALID; - dom_latch_p = true; - } + adef = DF_REF_CHAIN (use)->ref; /* We do not handle setting only part of the register. */ if (DF_REF_FLAGS (adef) & DF_REF_READ_WRITE) @@ -467,8 +414,8 @@ iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def) /* The definition does not dominate the use. This is still OK if this may be a use of a biv, i.e. if the def_bb dominates loop - latch or all defs are in latch's predecessors. */ - if (dom_latch_p || just_once_each_iteration_p (current_loop, def_bb)) + latch. */ + if (just_once_each_iteration_p (current_loop, def_bb)) return GRD_MAYBE_BIV; return GRD_INVALID; @@ -2981,49 +2928,6 @@ fail: return; } -/* Return true if LOOP has a complex exit, but is still good for further - analysis. Return false otherwise. BB is LOOP's exit block. */ - -static bool -check_complex_exit_p (struct loop* loop, basic_block bb) -{ - edge e; - basic_block pred, exit; - - if (EDGE_COUNT (bb->preds) > 1) - return false; - - e = EDGE_PRED (bb, 0); - - pred = e->src; - if (EDGE_COUNT (pred->succs) != 2) - return false; - - /* Predecessor must be tested (at least) once during any iteration. */ - if (!dominated_by_p (CDI_DOMINATORS, loop->latch, pred)) - return false; - - if (EDGE_SUCC (pred, 0)->dest == bb) - exit = EDGE_SUCC (pred, 1)->dest; - else - exit = EDGE_SUCC (pred, 0)->dest; - - /* Check that EXIT is really loop exit. */ - if (flow_bb_inside_loop_p (loop, exit)) - { - edge_iterator eei; - edge ee; - - FOR_EACH_EDGE (ee, eei, exit->succs) - { - if (!flow_bb_inside_loop_p (loop, ee->dest)) - return true; - } - } - return false; - -} - /* Checks whether E is a simple exit from LOOP and stores its description into DESC. */ @@ -3043,8 +2947,7 @@ check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc) return; /* It must be tested (at least) once during any iteration. */ - if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit_bb) - && !check_complex_exit_p (loop, exit_bb)) + if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit_bb)) return; /* It must end in a simple conditional jump. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6dc5125ebb8..83f2e29fa0f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-01-20 Igor Zamyatin + + PR bootstrap/64676 + Revert: + 2014-01-19 Igor Zamyatin + + PR rtl-optimization/64081 + * gcc.dg/pr64081.c: New test. + 2015-01-19 David Malcolm * jit.dg/harness.h: Include . diff --git a/gcc/testsuite/gcc.dg/pr64081.c b/gcc/testsuite/gcc.dg/pr64081.c deleted file mode 100644 index 6151d0054a4..00000000000 --- a/gcc/testsuite/gcc.dg/pr64081.c +++ /dev/null @@ -1,41 +0,0 @@ -/* PR rtl-optimization/64081 */ -/* { dg-do compile } */ -/* { dg-options "-O2 -funroll-loops -fdump-rtl-loop2_unroll" } */ - -long token; -long *data; -long *arr1; -long *arr2; - -int main (int argc, const char* argv[]) -{ - unsigned long i; - static long pos, start, count; - static int dir; - - pos = 0; - dir = 1; - - for (i = 0; i < argc; i++) - { - start = pos; - for (count = 0; count <= 400; count++) - { - if (token == data[pos]) - break; - if (dir == 1) - pos = arr1[pos]; - else - pos = arr2[pos]; - if (pos == -1) - { - pos = start; - dir = !dir; - } - } - } - return pos + dir; -} - -/* { dg-final { scan-rtl-dump "loop unrolled 7 times" "loop2_unroll" } } */ -/* { dg-final { cleanup-rtl-dump "loop*" } } */ -- 2.30.2