aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2022-01-24 10:03:47 +0100
committerThomas Schwinge <thomas_schwinge@mentor.com>2022-01-24 10:06:43 +0100
commit21af490baa734a901fb798bc2ac4df62109bc895 (patch)
treea292dc4ac7de999d47f20ab9a2dff597afadea2a /gcc/tree-ssa-loop-ivopts.c
parent2cce6b8919ce16acd37a7a203049a52925a7e295 (diff)
parent490e23032baaece71f2ec09fa1805064b150fbc2 (diff)
downloadgcc-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.c64
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;