/* Induction variable optimizations.
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
#include "ggc.h"
#include "insn-config.h"
#include "recog.h"
+#include "pointer-set.h"
#include "hashtab.h"
#include "tree-chrec.h"
#include "tree-scalar-evolution.h"
unsigned regs_used;
/* Numbers of iterations for all exits of the current loop. */
- htab_t niters;
+ struct pointer_map_t *niters;
/* The size of version_info array allocated. */
unsigned version_info_size;
return false;
}
-/* Element of the table in that we cache the numbers of iterations obtained
- from exits of the loop. */
-
-struct nfe_cache_elt
-{
- /* The edge for that the number of iterations is cached. */
- edge exit;
-
- /* Number of iterations corresponding to this exit, or NULL if it cannot be
- determined. */
- tree niter;
-};
-
-/* Hash function for nfe_cache_elt E. */
-
-static hashval_t
-nfe_hash (const void *e)
-{
- const struct nfe_cache_elt *elt = e;
-
- return htab_hash_pointer (elt->exit);
-}
-
-/* Equality function for nfe_cache_elt E1 and edge E2. */
-
-static int
-nfe_eq (const void *e1, const void *e2)
-{
- const struct nfe_cache_elt *elt1 = e1;
-
- return elt1->exit == e2;
-}
-
/* Returns tree describing number of iterations determined from
EXIT of DATA->current_loop, or NULL if something goes wrong. */
static tree
niter_for_exit (struct ivopts_data *data, edge exit)
{
- struct nfe_cache_elt *nfe_desc;
struct tree_niter_desc desc;
- PTR *slot;
-
- slot = htab_find_slot_with_hash (data->niters, exit,
- htab_hash_pointer (exit),
- INSERT);
+ tree niter;
+ void **slot;
- if (!*slot)
+ if (!data->niters)
{
- nfe_desc = xmalloc (sizeof (struct nfe_cache_elt));
- nfe_desc->exit = exit;
+ data->niters = pointer_map_create ();
+ slot = NULL;
+ }
+ else
+ slot = pointer_map_contains (data->niters, exit);
+ if (!slot)
+ {
/* Try to determine number of iterations. We must know it
unconditionally (i.e., without possibility of # of iterations
being zero). Also, we cannot safely work with ssa names that
exit, &desc, true)
&& integer_zerop (desc.may_be_zero)
&& !contains_abnormal_ssa_name_p (desc.niter))
- nfe_desc->niter = desc.niter;
+ niter = desc.niter;
else
- nfe_desc->niter = NULL_TREE;
+ niter = NULL_TREE;
+
+ *pointer_map_insert (data->niters, exit) = niter;
}
else
- nfe_desc = *slot;
+ niter = *slot;
- return nfe_desc->niter;
+ return niter;
}
/* Returns tree describing number of iterations determined from
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);
+ data->niters = NULL;
data->iv_uses = VEC_alloc (iv_use_p, heap, 20);
data->iv_candidates = VEC_alloc (iv_cand_p, heap, 20);
decl_rtl_to_reset = VEC_alloc (tree, heap, 20);
if (!EXPR_P (expr) && !GIMPLE_STMT_P (expr))
return false;
- len = TREE_CODE_LENGTH (TREE_CODE (expr));
+ len = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < len; i++)
if (!expr_invariant_in_loop_p (loop, TREE_OPERAND (expr, i)))
return false;
{
if (stmts)
bsi_insert_after (&bsi, stmts, BSI_CONTINUE_LINKING);
- ass = build2_gimple (GIMPLE_MODIFY_STMT, tgt, op);
+ ass = build_gimple_modify_stmt (tgt, op);
bsi_insert_after (&bsi, ass, BSI_NEW_STMT);
remove_statement (use->stmt, false);
SSA_NAME_DEF_STMT (tgt) = ass;
bitmap_iterator bi;
tree obj;
- htab_empty (data->niters);
+ if (data->niters)
+ {
+ pointer_map_destroy (data->niters);
+ data->niters = NULL;
+ }
EXECUTE_IF_SET_IN_BITMAP (data->relevant, 0, i, bi)
{
free (data->version_info);
BITMAP_FREE (data->relevant);
BITMAP_FREE (data->important_candidates);
- htab_delete (data->niters);
VEC_free (tree, heap, decl_rtl_to_reset);
VEC_free (iv_use_p, heap, data->iv_uses);
struct iv_ca *iv_ca;
edge exit;
+ gcc_assert (!data->niters);
data->current_loop = loop;
if (dump_file && (dump_flags & TDF_DETAILS))