Hi,
We generally need to compute cand step in loop preheader and use it in loop
body.
Unless it's an SSA_NAME of constant integer, an invariant expression is needed.
Thanks,
bin
2017-04-11 Bin Cheng <bin.ch...@arm.com>
* tree-ssa-loop-ivopts.c (struct iv_cand): New field inv_exprs.
(dump_cand): Support iv_cand.inv_exprs.
(add_candidate_1): Record invariant exprs in iv_cand.inv_exprs
for candidates.
(iv_ca_set_no_cp, iv_ca_set_cp, free_loop_data): Support
iv_cand.inv_exprs.
From 06806d09f557854a5987b83a044a5eb5433cda60 Mon Sep 17 00:00:00 2001
From: Bin Cheng <binch...@e108451-lin.cambridge.arm.com>
Date: Wed, 1 Mar 2017 14:50:11 +0000
Subject: [PATCH 17/33] treat-cand_step-as-inv_expr-20170225.txt
---
gcc/tree-ssa-loop-ivopts.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index c3e9bce..2c6fa76 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -421,6 +421,7 @@ struct iv_cand
where it is incremented. */
bitmap inv_vars; /* The list of invariants that are used in step of the
biv. */
+ bitmap inv_exprs; /* Hanlde step as inv expr if it's not simple. */
struct iv *orig_iv; /* The original iv if this cand is added from biv with
smaller type. */
};
@@ -790,6 +791,11 @@ dump_cand (FILE *file, struct iv_cand *cand)
fprintf (file, " Depend on inv.vars: ");
dump_bitmap (file, cand->inv_vars);
}
+ if (cand->inv_exprs)
+ {
+ fprintf (file, " Depend on inv.exprs: ");
+ dump_bitmap (file, cand->inv_exprs);
+ }
if (cand->var_before)
{
@@ -3032,7 +3038,23 @@ add_candidate_1 (struct ivopts_data *data,
data->vcands.safe_push (cand);
if (TREE_CODE (step) != INTEGER_CST)
- find_inv_vars (data, &step, &cand->inv_vars);
+ {
+ find_inv_vars (data, &step, &cand->inv_vars);
+
+ iv_inv_expr_ent *inv_expr = get_loop_invariant_expr (data, step);
+ /* Share bitmap between inv_vars and inv_exprs for cand. */
+ if (inv_expr != NULL)
+ {
+ cand->inv_exprs = cand->inv_vars;
+ cand->inv_vars = NULL;
+ if (cand->inv_exprs)
+ bitmap_clear (cand->inv_exprs);
+ else
+ cand->inv_exprs = BITMAP_ALLOC (NULL);
+
+ bitmap_set_bit (cand->inv_exprs, inv_expr->id);
+ }
+ }
if (pos == IP_AFTER_USE || pos == IP_BEFORE_USE)
cand->ainc_use = use;
@@ -5606,6 +5628,7 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca
*ivs,
ivs->n_cands--;
ivs->cand_cost -= cp->cand->cost;
iv_ca_set_remove_invs (ivs, cp->cand->inv_vars, ivs->n_inv_var_uses);
+ iv_ca_set_remove_invs (ivs, cp->cand->inv_exprs, ivs->n_inv_expr_uses);
}
ivs->cand_use_cost -= cp->cost;
@@ -5662,6 +5685,7 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
ivs->n_cands++;
ivs->cand_cost += cp->cand->cost;
iv_ca_set_add_invs (ivs, cp->cand->inv_vars, ivs->n_inv_var_uses);
+ iv_ca_set_add_invs (ivs, cp->cand->inv_exprs, ivs->n_inv_expr_uses);
}
ivs->cand_use_cost += cp->cost;
@@ -7143,6 +7167,8 @@ free_loop_data (struct ivopts_data *data)
if (cand->inv_vars)
BITMAP_FREE (cand->inv_vars);
+ if (cand->inv_exprs)
+ BITMAP_FREE (cand->inv_exprs);
free (cand);
}
data->vcands.truncate (0);
--
1.9.1