diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2022-01-24 10:03:47 +0100 |
---|---|---|
committer | Thomas Schwinge <thomas_schwinge@mentor.com> | 2022-01-24 10:06:43 +0100 |
commit | 21af490baa734a901fb798bc2ac4df62109bc895 (patch) | |
tree | a292dc4ac7de999d47f20ab9a2dff597afadea2a /gcc/tree-ssa-loop-ivopts.c | |
parent | 2cce6b8919ce16acd37a7a203049a52925a7e295 (diff) | |
parent | 490e23032baaece71f2ec09fa1805064b150fbc2 (diff) | |
download | gcc-21af490baa734a901fb798bc2ac4df62109bc895.zip gcc-21af490baa734a901fb798bc2ac4df62109bc895.tar.gz gcc-21af490baa734a901fb798bc2ac4df62109bc895.tar.bz2 |
Merge commit '490e23032baaece71f2ec09fa1805064b150fbc2' [#247]
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 4a498ab..935d2d4 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -1,5 +1,5 @@ /* Induction variable optimizations. - Copyright (C) 2003-2021 Free Software Foundation, Inc. + Copyright (C) 2003-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -1462,22 +1462,20 @@ find_givs_in_bb (struct ivopts_data *data, basic_block bb) /* Finds general ivs. */ static void -find_givs (struct ivopts_data *data) +find_givs (struct ivopts_data *data, basic_block *body) { class loop *loop = data->current_loop; - basic_block *body = get_loop_body_in_dom_order (loop); unsigned i; for (i = 0; i < loop->num_nodes; i++) find_givs_in_bb (data, body[i]); - free (body); } /* For each ssa name defined in LOOP determines whether it is an induction variable and if so, its initial value and step. */ static bool -find_induction_variables (struct ivopts_data *data) +find_induction_variables (struct ivopts_data *data, basic_block *body) { unsigned i; bitmap_iterator bi; @@ -1485,7 +1483,7 @@ find_induction_variables (struct ivopts_data *data) if (!find_bivs (data)) return false; - find_givs (data); + find_givs (data, body); mark_bivs (data); if (dump_file && (dump_flags & TDF_DETAILS)) @@ -2736,11 +2734,10 @@ split_address_groups (struct ivopts_data *data) /* Finds uses of the induction variables that are interesting. */ static void -find_interesting_uses (struct ivopts_data *data) +find_interesting_uses (struct ivopts_data *data, basic_block *body) { basic_block bb; gimple_stmt_iterator bsi; - basic_block *body = get_loop_body (data->current_loop); unsigned i; edge e; @@ -2760,7 +2757,6 @@ find_interesting_uses (struct ivopts_data *data) if (!is_gimple_debug (gsi_stmt (bsi))) find_interesting_uses_stmt (data, gsi_stmt (bsi)); } - free (body); split_address_groups (data); @@ -5034,28 +5030,57 @@ determine_group_iv_cost_address (struct ivopts_data *data, return !sum_cost.infinite_cost_p (); } -/* Computes value of candidate CAND at position AT in iteration NITER, and - stores it to VAL. */ +/* Computes value of candidate CAND at position AT in iteration DESC->NITER, + and stores it to VAL. */ static void -cand_value_at (class loop *loop, struct iv_cand *cand, gimple *at, tree niter, - aff_tree *val) +cand_value_at (class loop *loop, struct iv_cand *cand, gimple *at, + class tree_niter_desc *desc, aff_tree *val) { aff_tree step, delta, nit; struct iv *iv = cand->iv; tree type = TREE_TYPE (iv->base); + tree niter = desc->niter; + bool after_adjust = stmt_after_increment (loop, cand, at); tree steptype; + if (POINTER_TYPE_P (type)) steptype = sizetype; else steptype = unsigned_type_for (type); + /* If AFTER_ADJUST is required, the code below generates the equivalent + of BASE + NITER * STEP + STEP, when ideally we'd prefer the expression + BASE + (NITER + 1) * STEP, especially when NITER is often of the form + SSA_NAME - 1. Unfortunately, guaranteeing that adding 1 to NITER + doesn't overflow is tricky, so we peek inside the TREE_NITER_DESC + class for common idioms that we know are safe. */ + if (after_adjust + && desc->control.no_overflow + && integer_onep (desc->control.step) + && (desc->cmp == LT_EXPR + || desc->cmp == NE_EXPR) + && TREE_CODE (desc->bound) == SSA_NAME) + { + if (integer_onep (desc->control.base)) + { + niter = desc->bound; + after_adjust = false; + } + else if (TREE_CODE (niter) == MINUS_EXPR + && integer_onep (TREE_OPERAND (niter, 1))) + { + niter = TREE_OPERAND (niter, 0); + after_adjust = false; + } + } + tree_to_aff_combination (iv->step, TREE_TYPE (iv->step), &step); aff_combination_convert (&step, steptype); tree_to_aff_combination (niter, TREE_TYPE (niter), &nit); aff_combination_convert (&nit, steptype); aff_combination_mult (&nit, &step, &delta); - if (stmt_after_increment (loop, cand, at)) + if (after_adjust) aff_combination_add (&delta, &step); tree_to_aff_combination (iv->base, type, val); @@ -5406,7 +5431,7 @@ may_eliminate_iv (struct ivopts_data *data, return true; } - cand_value_at (loop, cand, use->stmt, desc->niter, &bnd); + cand_value_at (loop, cand, use->stmt, desc, &bnd); *bound = fold_convert (TREE_TYPE (cand->iv->base), aff_combination_to_tree (&bnd)); @@ -7742,9 +7767,8 @@ remove_unused_ivs (struct ivopts_data *data, bitmap toremove) comp = unshare_expr (comp); if (count > 1) { - tree vexpr = make_node (DEBUG_EXPR_DECL); - DECL_ARTIFICIAL (vexpr) = 1; - TREE_TYPE (vexpr) = TREE_TYPE (comp); + tree vexpr = build_debug_expr_decl (TREE_TYPE (comp)); + /* FIXME: Is setting the mode really necessary? */ if (SSA_NAME_VAR (def)) SET_DECL_MODE (vexpr, DECL_MODE (SSA_NAME_VAR (def))); else @@ -8078,11 +8102,11 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, class loop *loop, /* For each ssa name determines whether it behaves as an induction variable in some loop. */ - if (!find_induction_variables (data)) + if (!find_induction_variables (data, body)) goto finish; /* Finds interesting uses (item 1). */ - find_interesting_uses (data); + find_interesting_uses (data, body); if (data->vgroups.length () > MAX_CONSIDERED_GROUPS) goto finish; |