diff options
author | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-20 08:29:09 +0000 |
---|---|---|
committer | ienkovich <ienkovich@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-01-20 08:29:09 +0000 |
commit | c102b5b94d30e50a26793ddc14899edf6b60f354 (patch) | |
tree | 795636fd50f97efcf92b36580bc45b8c20d812a7 /gcc/loop-iv.c | |
parent | fa125df21965ad7a87f60f70a13cfcb4c74dd255 (diff) | |
download | gcc-c102b5b94d30e50a26793ddc14899edf6b60f354.tar.gz |
gcc/
PR bootstrap/64676
Revert:
2015-01-19 Igor Zamyatin <igor.zamyatin@intel.com>
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 <igor.zamyatin@intel.com>
PR rtl-optimization/64081
* gcc.dg/pr64081.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219880 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop-iv.c')
-rw-r--r-- | gcc/loop-iv.c | 127 |
1 files changed, 15 insertions, 112 deletions
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. */ |