aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c91
1 files changed, 58 insertions, 33 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 40661bea109..796946369d3 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -88,6 +88,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-scalar-evolution.h"
#include "cfgloop.h"
#include "params.h"
+#include "langhooks.h"
/* The infinite cost. */
#define INFTY 10000000
@@ -730,8 +731,8 @@ tree_ssa_iv_optimize_init (struct loops *loops, struct ivopts_data *data)
data->version_info_size = 2 * num_ssa_names;
data->version_info = xcalloc (data->version_info_size,
sizeof (struct version_info));
- data->relevant = BITMAP_XMALLOC ();
- data->important_candidates = BITMAP_XMALLOC ();
+ data->relevant = BITMAP_ALLOC (NULL);
+ data->important_candidates = BITMAP_ALLOC (NULL);
data->max_inv_id = 0;
data->niters = htab_create (10, nfe_hash, nfe_eq, free);
@@ -1152,7 +1153,7 @@ record_use (struct ivopts_data *data, tree *use_p, struct iv *iv,
use->iv = iv;
use->stmt = stmt;
use->op_p = use_p;
- use->related_cands = BITMAP_XMALLOC ();
+ use->related_cands = BITMAP_ALLOC (NULL);
/* To avoid showing ssa name in the dumps, if it was not reset by the
caller. */
@@ -1840,6 +1841,22 @@ strip_offset (tree expr, bool inside_addr, unsigned HOST_WIDE_INT *offset)
return fold_convert (orig_type, expr);
}
+/* Returns variant of TYPE that can be used as base for different uses.
+ For integer types, we return unsigned variant of the type, which
+ avoids problems with overflows. For pointer types, we return void *. */
+
+static tree
+generic_type_for (tree type)
+{
+ if (POINTER_TYPE_P (type))
+ return ptr_type_node;
+
+ if (TYPE_UNSIGNED (type))
+ return type;
+
+ return unsigned_type_for (type);
+}
+
/* Adds a candidate BASE + STEP * i. Important field is set to IMPORTANT and
position to POS. If USE is not NULL, the candidate is set as related to
it. If both BASE and STEP are NULL, we add a pseudocandidate for the
@@ -1852,14 +1869,14 @@ add_candidate_1 (struct ivopts_data *data,
{
unsigned i;
struct iv_cand *cand = NULL;
- tree type;
+ tree type, orig_type;
if (base)
{
- type = TREE_TYPE (base);
- if (!TYPE_UNSIGNED (type))
+ orig_type = TREE_TYPE (base);
+ type = generic_type_for (orig_type);
+ if (type != orig_type)
{
- type = unsigned_type_for (type);
base = fold_convert (type, base);
if (step)
step = fold_convert (type, step);
@@ -1980,23 +1997,28 @@ add_candidate (struct ivopts_data *data,
add_candidate_1 (data, base, step, important, IP_END, use, NULL_TREE);
}
+/* Add a standard "0 + 1 * iteration" iv candidate for a
+ type with SIZE bits. */
+
+static void
+add_standard_iv_candidates_for_size (struct ivopts_data *data,
+ unsigned int size)
+{
+ tree type = lang_hooks.types.type_for_size (size, true);
+ add_candidate (data, build_int_cst (type, 0), build_int_cst (type, 1),
+ true, NULL);
+}
+
/* Adds standard iv candidates. */
static void
add_standard_iv_candidates (struct ivopts_data *data)
{
- /* Add 0 + 1 * iteration candidate. */
- add_candidate (data,
- build_int_cst (unsigned_intSI_type_node, 0),
- build_int_cst (unsigned_intSI_type_node, 1),
- true, NULL);
+ add_standard_iv_candidates_for_size (data, INT_TYPE_SIZE);
- /* The same for a long type if it is still fast enough. */
- if (BITS_PER_WORD > 32)
- add_candidate (data,
- build_int_cst (unsigned_intDI_type_node, 0),
- build_int_cst (unsigned_intDI_type_node, 1),
- true, NULL);
+ /* The same for a double-integer type if it is still fast enough. */
+ if (BITS_PER_WORD >= INT_TYPE_SIZE * 2)
+ add_standard_iv_candidates_for_size (data, INT_TYPE_SIZE * 2);
}
@@ -2184,7 +2206,7 @@ record_important_candidates (struct ivopts_data *data)
for (i = 0; i < n_iv_uses (data); i++)
{
use = iv_use (data, i);
- BITMAP_XFREE (use->related_cands);
+ BITMAP_FREE (use->related_cands);
}
}
else
@@ -2260,7 +2282,7 @@ set_use_iv_cost (struct ivopts_data *data,
if (cost == INFTY)
{
- BITMAP_XFREE (depends_on);
+ BITMAP_FREE (depends_on);
return;
}
@@ -2427,7 +2449,8 @@ computation_cost (tree expr)
rtx seq, rslt;
tree type = TREE_TYPE (expr);
unsigned cost;
- int regno = 0;
+ /* Avoid using hard regs in ways which may be unsupported. */
+ int regno = LAST_VIRTUAL_REGISTER + 1;
walk_tree (&expr, prepare_decl_rtl, &regno, NULL);
start_sequence ();
@@ -2827,7 +2850,7 @@ find_depends (tree *expr_p, int *ws ATTRIBUTE_UNUSED, void *data)
return NULL_TREE;
if (!*depends_on)
- *depends_on = BITMAP_XMALLOC ();
+ *depends_on = BITMAP_ALLOC (NULL);
bitmap_set_bit (*depends_on, info->inv_id);
return NULL_TREE;
@@ -3589,7 +3612,7 @@ determine_use_iv_costs (struct ivopts_data *data)
unsigned i, j;
struct iv_use *use;
struct iv_cand *cand;
- bitmap to_clear = BITMAP_XMALLOC ();
+ bitmap to_clear = BITMAP_ALLOC (NULL);
alloc_use_cost_map (data);
@@ -3623,7 +3646,7 @@ determine_use_iv_costs (struct ivopts_data *data)
}
}
- BITMAP_XFREE (to_clear);
+ BITMAP_FREE (to_clear);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -4134,7 +4157,7 @@ iv_ca_new (struct ivopts_data *data)
nw->bad_uses = 0;
nw->cand_for_use = xcalloc (n_iv_uses (data), sizeof (struct cost_pair *));
nw->n_cand_uses = xcalloc (n_iv_cands (data), sizeof (unsigned));
- nw->cands = BITMAP_XMALLOC ();
+ nw->cands = BITMAP_ALLOC (NULL);
nw->n_cands = 0;
nw->n_regs = 0;
nw->cand_use_cost = 0;
@@ -4152,7 +4175,7 @@ iv_ca_free (struct iv_ca **ivs)
{
free ((*ivs)->cand_for_use);
free ((*ivs)->n_cand_uses);
- BITMAP_XFREE ((*ivs)->cands);
+ BITMAP_FREE ((*ivs)->cands);
free ((*ivs)->n_invariant_uses);
free (*ivs);
*ivs = NULL;
@@ -4877,15 +4900,17 @@ rewrite_use_compare (struct ivopts_data *data,
if (may_eliminate_iv (data, use, cand, &compare, &bound))
{
+ tree var = var_at_stmt (data->current_loop, cand, use->stmt);
+ tree var_type = TREE_TYPE (var);
+
+ bound = fold_convert (var_type, bound);
op = force_gimple_operand (unshare_expr (bound), &stmts,
true, NULL_TREE);
if (stmts)
bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
- *use->op_p = build2 (compare, boolean_type_node,
- var_at_stmt (data->current_loop,
- cand, use->stmt), op);
+ *use->op_p = build2 (compare, boolean_type_node, var, op);
modify_stmt (use->stmt);
return;
}
@@ -5192,10 +5217,10 @@ free_loop_data (struct ivopts_data *data)
struct iv_use *use = iv_use (data, i);
free (use->iv);
- BITMAP_XFREE (use->related_cands);
+ BITMAP_FREE (use->related_cands);
for (j = 0; j < use->n_map_members; j++)
if (use->cost_map[j].depends_on)
- BITMAP_XFREE (use->cost_map[j].depends_on);
+ BITMAP_FREE (use->cost_map[j].depends_on);
free (use->cost_map);
free (use);
}
@@ -5247,8 +5272,8 @@ tree_ssa_iv_optimize_finalize (struct loops *loops, struct ivopts_data *data)
free_loop_data (data);
free (data->version_info);
- BITMAP_XFREE (data->relevant);
- BITMAP_XFREE (data->important_candidates);
+ BITMAP_FREE (data->relevant);
+ BITMAP_FREE (data->important_candidates);
htab_delete (data->niters);
VARRAY_FREE (decl_rtl_to_reset);