aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog71
-rw-r--r--gcc/Makefile.in8
-rw-r--r--gcc/tree-cfg.c120
-rw-r--r--gcc/tree-nested.c157
-rw-r--r--gcc/tree-ssa-loop-ivopts.c75
-rw-r--r--gcc/tree-ssa-reassoc.c77
-rw-r--r--gcc/tree-ssa-structalias.c82
7 files changed, 217 insertions, 373 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a3b07b0b172..f915a021713 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,74 @@
+2006-02-06 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.in (tree-ssa-loop-ivopts.o): Add pointer-set.h dependency.
+ (tree-ssa-reassoc.o): Add pointer-set.h dependency.
+ (tree-cfg.o): Remove hashtab.h dependency.
+
+ * tree-ssa-loop-ivopts.c: Include pointer-set.h.
+ (struct ivopts_data): Change niters to pointer_map_t.
+ (struct nfe_cache_elt, nfe_hash, nfe_eq): Delete.
+ (niter_for_exit): Create pointer_map on demand. Change for
+ pointer_map API.
+ (tree_ssa_iv_optimize_init): Initialize data->niters to NULL.
+ (free_loop_data): Destroy data->niters if created and reset field.
+ (tree_ssa_iv_optimize_finalize): Don't delete data->niters here.
+ (tree_ssa_iv_optimize_loop): Check for presence of stale data.
+
+ * tree-ssa-reassoc.c: Include pointer-set.h.
+ (bb_rank): Change to long *.
+ (operand_rank): Change to pointer_map_t.
+ (find_operand_rank): Return long, -1 if not found. Declare as inline.
+ (insert_operand_rank): Accept long.
+ (operand_entry_hash, operand_entry_eq): Remove.
+ (get_rank): Return long. Adjust for changes above.
+ (init_reassoc): Change rank type to long. Adjust creation of bb_rank
+ and operand_rank.
+ (fini_reassoc): Delete operand_rank with pointer_map_destroy.
+
+ * tree-ssa-structalias.c (vi_for_tree): Change to pointer_map.
+ (struct tree_vi, tree_vi_t, tree_vi_hash, tree_vi_eq): Delete.
+ (insert_vi_for_tree): Rewrite for pointer_map API. Assert argument
+ is not NULL.
+ (lookup_vi_for_tree): Rewrite for pointer_map API. Return varinfo_t
+ directly since it cannot be NULL.
+ (get_vi_for_tree): Rewrite for pointer_map API.
+ (find_what_p_points_to): Adjust for change to lookup_vi_for_tree.
+ (init_alias_vars): Create vi_for_tree as pointer_map.
+ (delete_points_to_sets): Delete vi_for_tree using pointer_map_destroy.
+
+ * tree-cfg.c: Don't include hashtab.h.
+ (edge_to_cases): Declare as pointer_map.
+ (struct edge_to_cases_elt, edge_to_cases_hash, edge_to_cases_eq):
+ Delete.
+ (edge_to_cases_cleanup): Rewrite as pointer_map_traverse callback.
+ (start_recording_case_labels): Create edge_to_cases as pointer_map.
+ (end_recoding_case_labels): Cleanup edge_to_cases manually before
+ destroying it.
+ (record_switch_edge): Delete.
+ (get_cases_for_edge): Adjust for pointer_map API, inline
+ record_switch_edge (rewritten for new API), remove goto.
+
+2006-02-06 Paolo Bonzini <bonzini@gnu.org>
+
+ * Makefile.in (tree-nested.o): Add pointer-set.h dependency.
+ * tree-nested.c: Include pointer-set.h.
+ (var_map_elt, var_map_eq, var_map_hash): Delete.
+ (struct nesting_info): Remove GTY marker. Change the two htab_t's
+ to pointer_map_t's.
+ (nesting_info_bitmap_obstack): New.
+ (lookup_field_for_decl): Adjust for pointer_map API.
+ (lookup_tramp_for_decl): Adjust for pointer_map API.
+ (get_nonlocal_debug_decl): Adjust for pointer_map API.
+ (get_local_debug_decl): Adjust for pointer_map API.
+ (convert_nl_goto_reference): Adjust for pointer_map API.
+ (convert_nl_goto_receiver): Adjust for pointer_map API.
+ (create_nesting_tree): Create outside GGC space. Create bitmap on
+ the new obstack. Create field_map and var_map as pointer_maps.
+ (free_nesting_tree): Adjust for changes to create_nesting_tree.
+ (root): Delete.
+ (lower_nested_functions): Move root here, no need to NULL it.
+ Initialize and release the obstack.
+
2007-02-06 Paolo Bonzini <bonzini@gnu.org>
* tree.c (tree_int_map_hash, tree_int_map_eq, tree_int_map_marked_p):
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index f22407f8f79..689122d1490 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2055,7 +2055,7 @@ tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \
- $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) toplev.h \
+ $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h toplev.h \
tree-ssa-propagate.h
tree-cfgcleanup.o : tree-cfgcleanup.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
@@ -2078,7 +2078,7 @@ tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
$(RTL_H) $(TM_P_H) $(FUNCTION_H) $(TREE_DUMP_H) $(TREE_INLINE_H) \
tree-iterator.h $(TREE_GIMPLE_H) $(CGRAPH_H) $(EXPR_H) langhooks.h \
- $(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H)
+ $(GGC_H) gt-tree-nested.h coretypes.h $(TREE_FLOW_H) pointer-set.h
tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
$(CFGLOOP_H) $(RTL_H) $(C_COMMON_H) tree-chrec.h $(TREE_DATA_REF_H) \
@@ -2140,7 +2140,7 @@ tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
$(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
- tree-chrec.h $(VARRAY_H) tree-affine.h
+ tree-chrec.h $(VARRAY_H) tree-affine.h pointer-set.h
tree-affine.o : tree-affine.c tree-affine.h $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \
output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H)
@@ -2167,7 +2167,7 @@ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\
$(BASIC_BLOCK_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) vec.h \
- alloc-pool.h
+ alloc-pool.h pointer-set.h
tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
$(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 6f492052501..d9794592cf6 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -44,7 +44,6 @@ Boston, MA 02110-1301, USA. */
#include "except.h"
#include "cfgloop.h"
#include "cfglayout.h"
-#include "hashtab.h"
#include "tree-ssa-propagate.h"
#include "value-prof.h"
#include "pointer-set.h"
@@ -70,19 +69,7 @@ static const int initial_cfg_capacity = 20;
more persistent. The key is getting notification of changes to
the CFG (particularly edge removal, creation and redirection). */
-struct edge_to_cases_elt
-{
- /* The edge itself. Necessary for hashing and equality tests. */
- edge e;
-
- /* The case labels associated with this edge. We link these up via
- their TREE_CHAIN field, then we wipe out the TREE_CHAIN fields
- when we destroy the hash table. This prevents problems when copying
- SWITCH_EXPRs. */
- tree case_labels;
-};
-
-static htab_t edge_to_cases;
+static struct pointer_map_t *edge_to_cases;
/* CFG statistics. */
struct cfg_stats_d
@@ -619,28 +606,6 @@ make_cond_expr_edges (basic_block bb)
}
}
-/* Hashing routine for EDGE_TO_CASES. */
-
-static hashval_t
-edge_to_cases_hash (const void *p)
-{
- edge e = ((struct edge_to_cases_elt *)p)->e;
-
- /* Hash on the edge itself (which is a pointer). */
- return htab_hash_pointer (e);
-}
-
-/* Equality routine for EDGE_TO_CASES, edges are unique, so testing
- for equality is just a pointer comparison. */
-
-static int
-edge_to_cases_eq (const void *p1, const void *p2)
-{
- edge e1 = ((struct edge_to_cases_elt *)p1)->e;
- edge e2 = ((struct edge_to_cases_elt *)p2)->e;
-
- return e1 == e2;
-}
/* Called for each element in the hash table (P) as we delete the
edge to cases hash table.
@@ -649,18 +614,20 @@ edge_to_cases_eq (const void *p1, const void *p2)
SWITCH_EXPRs and structure sharing rules, then free the hash table
element. */
-static void
-edge_to_cases_cleanup (void *p)
+static bool
+edge_to_cases_cleanup (void *key ATTRIBUTE_UNUSED, void **value,
+ void *data ATTRIBUTE_UNUSED)
{
- struct edge_to_cases_elt *elt = (struct edge_to_cases_elt *) p;
tree t, next;
- for (t = elt->case_labels; t; t = next)
+ for (t = (tree) *value; t; t = next)
{
next = TREE_CHAIN (t);
TREE_CHAIN (t) = NULL;
}
- free (p);
+
+ *value = NULL;
+ return false;
}
/* Start recording information mapping edges to case labels. */
@@ -669,11 +636,7 @@ void
start_recording_case_labels (void)
{
gcc_assert (edge_to_cases == NULL);
-
- edge_to_cases = htab_create (37,
- edge_to_cases_hash,
- edge_to_cases_eq,
- edge_to_cases_cleanup);
+ edge_to_cases = pointer_map_create ();
}
/* Return nonzero if we are recording information for case labels. */
@@ -689,46 +652,11 @@ recording_case_labels_p (void)
void
end_recording_case_labels (void)
{
- htab_delete (edge_to_cases);
+ pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL);
+ pointer_map_destroy (edge_to_cases);
edge_to_cases = NULL;
}
-/* Record that CASE_LABEL (a CASE_LABEL_EXPR) references edge E. */
-
-static void
-record_switch_edge (edge e, tree case_label)
-{
- struct edge_to_cases_elt *elt;
- void **slot;
-
- /* Build a hash table element so we can see if E is already
- in the table. */
- elt = XNEW (struct edge_to_cases_elt);
- elt->e = e;
- elt->case_labels = case_label;
-
- slot = htab_find_slot (edge_to_cases, elt, INSERT);
-
- if (*slot == NULL)
- {
- /* E was not in the hash table. Install E into the hash table. */
- *slot = (void *)elt;
- }
- else
- {
- /* E was already in the hash table. Free ELT as we do not need it
- anymore. */
- free (elt);
-
- /* Get the entry stored in the hash table. */
- elt = (struct edge_to_cases_elt *) *slot;
-
- /* Add it to the chain of CASE_LABEL_EXPRs referencing E. */
- TREE_CHAIN (case_label) = elt->case_labels;
- elt->case_labels = case_label;
- }
-}
-
/* If we are inside a {start,end}_recording_cases block, then return
a chain of CASE_LABEL_EXPRs from T which reference E.
@@ -737,7 +665,6 @@ record_switch_edge (edge e, tree case_label)
static tree
get_cases_for_edge (edge e, tree t)
{
- struct edge_to_cases_elt elt, *elt_p;
void **slot;
size_t i, n;
tree vec;
@@ -747,16 +674,9 @@ get_cases_for_edge (edge e, tree t)
if (!recording_case_labels_p ())
return NULL;
-restart:
- elt.e = e;
- elt.case_labels = NULL;
- slot = htab_find_slot (edge_to_cases, &elt, NO_INSERT);
-
+ slot = pointer_map_contains (edge_to_cases, e);
if (slot)
- {
- elt_p = (struct edge_to_cases_elt *)*slot;
- return elt_p->case_labels;
- }
+ return (tree) *slot;
/* If we did not find E in the hash table, then this must be the first
time we have been queried for information about E & T. Add all the
@@ -766,11 +686,19 @@ restart:
n = TREE_VEC_LENGTH (vec);
for (i = 0; i < n; i++)
{
- tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
+ tree elt = TREE_VEC_ELT (vec, i);
+ tree lab = CASE_LABEL (elt);
basic_block label_bb = label_to_block (lab);
- record_switch_edge (find_edge (e->src, label_bb), TREE_VEC_ELT (vec, i));
+ edge this_edge = find_edge (e->src, label_bb);
+
+ /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
+ a new chain. */
+ slot = pointer_map_insert (edge_to_cases, this_edge);
+ TREE_CHAIN (elt) = (tree) *slot;
+ *slot = elt;
}
- goto restart;
+
+ return (tree) *pointer_map_contains (edge_to_cases, e);
}
/* Create the edges for a SWITCH_EXPR starting at block BB.
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index fdf39cc4623..a3ea11432d0 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -34,6 +34,7 @@
#include "cgraph.h"
#include "expr.h"
#include "langhooks.h"
+#include "pointer-set.h"
#include "ggc.h"
@@ -77,20 +78,14 @@
been written as independent functions without change. */
-struct var_map_elt GTY(())
-{
- tree old;
- tree new;
-};
-
-struct nesting_info GTY ((chain_next ("%h.next")))
+struct nesting_info
{
struct nesting_info *outer;
struct nesting_info *inner;
struct nesting_info *next;
- htab_t GTY ((param_is (struct var_map_elt))) field_map;
- htab_t GTY ((param_is (struct var_map_elt))) var_map;
+ struct pointer_map_t *field_map;
+ struct pointer_map_t *var_map;
bitmap suppress_expansion;
tree context;
@@ -108,22 +103,9 @@ struct nesting_info GTY ((chain_next ("%h.next")))
};
-/* Hashing and equality functions for nesting_info->var_map. */
+/* Obstack used for the bitmaps in the struct above. */
+static struct bitmap_obstack nesting_info_bitmap_obstack;
-static hashval_t
-var_map_hash (const void *x)
-{
- const struct var_map_elt *a = (const struct var_map_elt *) x;
- return htab_hash_pointer (a->old);
-}
-
-static int
-var_map_eq (const void *x, const void *y)
-{
- const struct var_map_elt *a = (const struct var_map_elt *) x;
- const struct var_map_elt *b = (const struct var_map_elt *) y;
- return a->old == b->old;
-}
/* We're working in so many different function contexts simultaneously,
that create_tmp_var is dangerous. Prevent mishap. */
@@ -268,22 +250,18 @@ static tree
lookup_field_for_decl (struct nesting_info *info, tree decl,
enum insert_option insert)
{
- struct var_map_elt *elt, dummy;
void **slot;
- tree field;
- dummy.old = decl;
- slot = htab_find_slot (info->field_map, &dummy, insert);
- if (!slot)
+ if (insert == NO_INSERT)
{
- gcc_assert (insert != INSERT);
- return NULL;
+ slot = pointer_map_contains (info->field_map, decl);
+ return slot ? *slot : NULL;
}
- elt = (struct var_map_elt *) *slot;
- if (!elt && insert == INSERT)
+ slot = pointer_map_insert (info->field_map, decl);
+ if (!*slot)
{
- field = make_node (FIELD_DECL);
+ tree field = make_node (FIELD_DECL);
DECL_NAME (field) = DECL_NAME (decl);
if (use_pointer_in_frame (decl))
@@ -304,19 +282,13 @@ lookup_field_for_decl (struct nesting_info *info, tree decl,
}
insert_field_into_struct (get_frame_type (info), field);
-
- elt = GGC_NEW (struct var_map_elt);
- elt->old = decl;
- elt->new = field;
- *slot = elt;
+ *slot = field;
if (TREE_CODE (decl) == PARM_DECL)
info->any_parm_remapped = true;
}
- else
- field = elt ? elt->new : NULL;
- return field;
+ return *slot;
}
/* Build or return the variable that holds the static chain within
@@ -469,39 +441,29 @@ static tree
lookup_tramp_for_decl (struct nesting_info *info, tree decl,
enum insert_option insert)
{
- struct var_map_elt *elt, dummy;
void **slot;
- tree field;
- dummy.old = decl;
- slot = htab_find_slot (info->var_map, &dummy, insert);
- if (!slot)
+ if (insert == NO_INSERT)
{
- gcc_assert (insert != INSERT);
- return NULL;
+ slot = pointer_map_contains (info->var_map, decl);
+ return slot ? *slot : NULL;
}
- elt = (struct var_map_elt *) *slot;
- if (!elt && insert == INSERT)
+ slot = pointer_map_insert (info->var_map, decl);
+ if (!*slot)
{
- field = make_node (FIELD_DECL);
+ tree field = make_node (FIELD_DECL);
DECL_NAME (field) = DECL_NAME (decl);
TREE_TYPE (field) = get_trampoline_type ();
TREE_ADDRESSABLE (field) = 1;
insert_field_into_struct (get_frame_type (info), field);
-
- elt = GGC_NEW (struct var_map_elt);
- elt->old = decl;
- elt->new = field;
- *slot = elt;
+ *slot = field;
info->any_tramp_created = true;
}
- else
- field = elt ? elt->new : NULL;
- return field;
+ return *slot;
}
/* Build or return the field within the non-local frame state that holds
@@ -767,10 +729,10 @@ check_for_nested_with_variably_modified (tree fndecl, tree orig_fndecl)
static struct nesting_info *
create_nesting_tree (struct cgraph_node *cgn)
{
- struct nesting_info *info = GGC_CNEW (struct nesting_info);
- info->field_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
- info->var_map = htab_create_ggc (7, var_map_hash, var_map_eq, ggc_free);
- info->suppress_expansion = BITMAP_GGC_ALLOC ();
+ struct nesting_info *info = XCNEW (struct nesting_info);
+ info->field_map = pointer_map_create ();
+ info->var_map = pointer_map_create ();
+ info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
info->context = cgn->decl;
for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
@@ -865,18 +827,15 @@ get_frame_field (struct nesting_info *info, tree target_context,
static tree
get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
{
- struct var_map_elt *elt, dummy;
tree target_context;
struct nesting_info *i;
tree x, field, new_decl;
void **slot;
- dummy.old = decl;
- slot = htab_find_slot (info->var_map, &dummy, INSERT);
- elt = *slot;
+ slot = pointer_map_insert (info->var_map, decl);
- if (elt)
- return elt->new;
+ if (*slot)
+ return *slot;
target_context = decl_function_context (decl);
@@ -920,11 +879,7 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
SET_DECL_VALUE_EXPR (new_decl, x);
DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
- elt = ggc_alloc (sizeof (*elt));
- elt->old = decl;
- elt->new = new_decl;
- *slot = elt;
-
+ *slot = new_decl;
TREE_CHAIN (new_decl) = info->debug_var_chain;
info->debug_var_chain = new_decl;
@@ -1198,16 +1153,12 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
static tree
get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
{
- struct var_map_elt *elt, dummy;
tree x, new_decl;
void **slot;
- dummy.old = decl;
- slot = htab_find_slot (info->var_map, &dummy, INSERT);
- elt = *slot;
-
- if (elt)
- return elt->new;
+ slot = pointer_map_insert (info->var_map, decl);
+ if (*slot)
+ return *slot;
/* Make sure frame_decl gets created. */
(void) get_frame_type (info);
@@ -1227,11 +1178,7 @@ get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
SET_DECL_VALUE_EXPR (new_decl, x);
DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
-
- elt = ggc_alloc (sizeof (*elt));
- elt->old = decl;
- elt->new = new_decl;
- *slot = elt;
+ *slot = new_decl;
TREE_CHAIN (new_decl) = info->debug_var_chain;
info->debug_var_chain = new_decl;
@@ -1491,7 +1438,6 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *info = wi->info, *i;
tree t = *tp, label, new_label, target_context, x, arg, field;
- struct var_map_elt *elt, dummy;
void **slot;
*walk_subtrees = 0;
@@ -1514,21 +1460,15 @@ convert_nl_goto_reference (tree *tp, int *walk_subtrees, void *data)
(hairy target-specific) non-local goto receiver code to be generated
when we expand rtl. Enter this association into var_map so that we
can insert the new label into the IL during a second pass. */
- dummy.old = label;
- slot = htab_find_slot (i->var_map, &dummy, INSERT);
- elt = (struct var_map_elt *) *slot;
- if (elt == NULL)
+ slot = pointer_map_insert (i->var_map, label);
+ if (*slot == NULL)
{
new_label = create_artificial_label ();
DECL_NONLOCAL (new_label) = 1;
-
- elt = GGC_NEW (struct var_map_elt);
- elt->old = label;
- elt->new = new_label;
- *slot = elt;
+ *slot = new_label;
}
else
- new_label = elt->new;
+ new_label = *slot;
/* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */
field = get_nl_goto_field (i);
@@ -1559,19 +1499,17 @@ convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data)
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct nesting_info *info = wi->info;
tree t = *tp, label, new_label, x;
- struct var_map_elt *elt, dummy;
tree_stmt_iterator tmp_tsi;
+ void **slot;
*walk_subtrees = 0;
if (TREE_CODE (t) != LABEL_EXPR)
return NULL_TREE;
label = LABEL_EXPR_LABEL (t);
- dummy.old = label;
- elt = (struct var_map_elt *) htab_find (info->var_map, &dummy);
- if (!elt)
+ slot = pointer_map_contains (info->var_map, label);
+ if (!slot)
return NULL_TREE;
- new_label = elt->new;
/* If there's any possibility that the previous statement falls through,
then we must branch around the new non-local label. */
@@ -1582,6 +1520,8 @@ convert_nl_goto_receiver (tree *tp, int *walk_subtrees, void *data)
x = build1 (GOTO_EXPR, void_type_node, label);
tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
}
+
+ new_label = (tree) *slot;
x = build1 (LABEL_EXPR, void_type_node, new_label);
tsi_link_before (&wi->tsi, x, TSI_SAME_STMT);
@@ -1953,16 +1893,15 @@ free_nesting_tree (struct nesting_info *root)
{
if (root->inner)
free_nesting_tree (root->inner);
- htab_delete (root->var_map);
+ pointer_map_destroy (root->var_map);
+ pointer_map_destroy (root->field_map);
next = root->next;
- ggc_free (root);
+ free (root);
root = next;
}
while (root);
}
-static GTY(()) struct nesting_info *root;
-
/* Main entry point for this pass. Process FNDECL and all of its nested
subroutines and turn them into something less tightly bound. */
@@ -1970,12 +1909,14 @@ void
lower_nested_functions (tree fndecl)
{
struct cgraph_node *cgn;
+ struct nesting_info *root;
/* If there are no nested functions, there's nothing to do. */
cgn = cgraph_node (fndecl);
if (!cgn->nested)
return;
+ bitmap_obstack_initialize (&nesting_info_bitmap_obstack);
root = create_nesting_tree (cgn);
walk_all_functions (convert_nonlocal_reference, root);
walk_all_functions (convert_local_reference, root);
@@ -1985,7 +1926,7 @@ lower_nested_functions (tree fndecl)
finalize_nesting_tree (root);
unnest_nesting_tree (root);
free_nesting_tree (root);
- root = NULL;
+ bitmap_obstack_release (&nesting_info_bitmap_obstack);
}
#include "gt-tree-nested.h"
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 65f1b84df14..5982b3d3f62 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -83,6 +83,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#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"
@@ -208,7 +209,7 @@ struct ivopts_data
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;
@@ -673,58 +674,26 @@ contains_abnormal_ssa_name_p (tree expr)
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
@@ -734,14 +703,16 @@ niter_for_exit (struct ivopts_data *data, edge exit)
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
@@ -770,7 +741,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
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);
@@ -5236,7 +5207,11 @@ free_loop_data (struct ivopts_data *data)
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)
{
@@ -5304,7 +5279,6 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data)
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);
@@ -5320,6 +5294,7 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop)
struct iv_ca *iv_ca;
edge exit;
+ gcc_assert (!data->niters);
data->current_loop = loop;
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 5e782615072..e216f996637 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA. */
#include "alloc-pool.h"
#include "vec.h"
#include "langhooks.h"
+#include "pointer-set.h"
/* This is a simple global reassociation pass. It is, in part, based
on the LLVM pass of the same name (They do some things more/less
@@ -179,68 +180,38 @@ static alloc_pool operand_entry_pool;
/* Starting rank number for a given basic block, so that we can rank
operations using unmovable instructions in that BB based on the bb
depth. */
-static unsigned int *bb_rank;
+static long *bb_rank;
/* Operand->rank hashtable. */
-static htab_t operand_rank;
+static struct pointer_map_t *operand_rank;
/* Look up the operand rank structure for expression E. */
-static operand_entry_t
+static inline long
find_operand_rank (tree e)
{
- void **slot;
- struct operand_entry vrd;
-
- vrd.op = e;
- slot = htab_find_slot (operand_rank, &vrd, NO_INSERT);
- if (!slot)
- return NULL;
- return ((operand_entry_t) *slot);
+ void **slot = pointer_map_contains (operand_rank, e);
+ return slot ? (long) *slot : -1;
}
/* Insert {E,RANK} into the operand rank hashtable. */
-static void
-insert_operand_rank (tree e, unsigned int rank)
+static inline void
+insert_operand_rank (tree e, long rank)
{
void **slot;
- operand_entry_t new_pair = pool_alloc (operand_entry_pool);
-
- new_pair->op = e;
- new_pair->rank = rank;
- slot = htab_find_slot (operand_rank, new_pair, INSERT);
- gcc_assert (*slot == NULL);
- *slot = new_pair;
-}
-
-/* Return the hash value for a operand rank structure */
-
-static hashval_t
-operand_entry_hash (const void *p)
-{
- const operand_entry_t vr = (operand_entry_t) p;
- return iterative_hash_expr (vr->op, 0);
-}
-
-/* Return true if two operand rank structures are equal. */
-
-static int
-operand_entry_eq (const void *p1, const void *p2)
-{
- const operand_entry_t vr1 = (operand_entry_t) p1;
- const operand_entry_t vr2 = (operand_entry_t) p2;
- return vr1->op == vr2->op;
+ gcc_assert (rank > 0);
+ slot = pointer_map_insert (operand_rank, e);
+ gcc_assert (!*slot);
+ *slot = (void *) rank;
}
/* Given an expression E, return the rank of the expression. */
-static unsigned int
+static long
get_rank (tree e)
{
- operand_entry_t vr;
-
/* Constants have rank 0. */
if (is_gimple_min_invariant (e))
return 0;
@@ -260,12 +231,12 @@ get_rank (tree e)
{
tree stmt;
tree rhs;
- unsigned int rank, maxrank;
+ long rank, maxrank;
int i;
if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL
&& SSA_NAME_IS_DEFAULT_DEF (e))
- return find_operand_rank (e)->rank;
+ return find_operand_rank (e);
stmt = SSA_NAME_DEF_STMT (e);
if (bb_for_stmt (stmt) == NULL)
@@ -276,9 +247,9 @@ get_rank (tree e)
return bb_rank[bb_for_stmt (stmt)->index];
/* If we already have a rank for this expression, use that. */
- vr = find_operand_rank (e);
- if (vr)
- return vr->rank;
+ rank = find_operand_rank (e);
+ if (rank != -1)
+ return rank;
/* Otherwise, find the maximum rank for the operands, or the bb
rank, whichever is less. */
@@ -301,7 +272,7 @@ get_rank (tree e)
{
fprintf (dump_file, "Rank for ");
print_generic_expr (dump_file, e, 0);
- fprintf (dump_file, " is %d\n", (rank + 1));
+ fprintf (dump_file, " is %ld\n", (rank + 1));
}
/* Note the rank in the hashtable so we don't recompute it. */
@@ -1417,7 +1388,7 @@ static void
init_reassoc (void)
{
int i;
- unsigned int rank = 2;
+ long rank = 2;
tree param;
int *bbs = XNEWVEC (int, last_basic_block + 1);
@@ -1429,10 +1400,8 @@ init_reassoc (void)
/* Reverse RPO (Reverse Post Order) will give us something where
deeper loops come later. */
pre_and_rev_post_order_compute (NULL, bbs, false);
- bb_rank = XCNEWVEC (unsigned int, last_basic_block + 1);
-
- operand_rank = htab_create (511, operand_entry_hash,
- operand_entry_eq, 0);
+ bb_rank = XCNEWVEC (long, last_basic_block + 1);
+ operand_rank = pointer_map_create ();
/* Give each argument a distinct rank. */
for (param = DECL_ARGUMENTS (current_function_decl);
@@ -1483,8 +1452,8 @@ fini_reassoc (void)
fprintf (dump_file, "Statements rewritten: %d\n",
reassociate_stats.rewritten);
}
- htab_delete (operand_rank);
+ pointer_map_destroy (operand_rank);
free_alloc_pool (operand_entry_pool);
free (bb_rank);
VEC_free (tree, heap, broken_up_subtracts);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 576ae1b78bb..238e7f487c1 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -2138,67 +2138,31 @@ solve_graph (constraint_graph_t graph)
}
/* Map from trees to variable infos. */
-static htab_t vi_for_tree;
+static struct pointer_map_t *vi_for_tree;
-typedef struct tree_vi
-{
- tree t;
- varinfo_t vi;
-} *tree_vi_t;
-
-/* Hash a tree id structure. */
-
-static hashval_t
-tree_vi_hash (const void *p)
-{
- const tree_vi_t ta = (tree_vi_t) p;
- return htab_hash_pointer (ta->t);
-}
-
-/* Return true if the tree in P1 and the tree in P2 are the same. */
-
-static int
-tree_vi_eq (const void *p1, const void *p2)
-{
- const tree_vi_t ta1 = (tree_vi_t) p1;
- const tree_vi_t ta2 = (tree_vi_t) p2;
- return ta1->t == ta2->t;
-}
-/* Insert ID as the variable id for tree T in the hashtable. */
+/* Insert ID as the variable id for tree T in the vi_for_tree map. */
static void
insert_vi_for_tree (tree t, varinfo_t vi)
{
- void **slot;
- struct tree_vi finder;
- tree_vi_t new_pair;
-
- finder.t = t;
- slot = htab_find_slot (vi_for_tree, &finder, INSERT);
+ void **slot = pointer_map_insert (vi_for_tree, t);
+ gcc_assert (vi);
gcc_assert (*slot == NULL);
- new_pair = XNEW (struct tree_vi);
- new_pair->t = t;
- new_pair->vi = vi;
- *slot = (void *)new_pair;
+ *slot = vi;
}
/* Find the variable info for tree T in VI_FOR_TREE. If T does not
- exist in the hash table, return false, otherwise, return true and
- set *VI to the varinfo we found. */
+ exist in the map, return NULL, otherwise, return the varinfo we found. */
-static bool
-lookup_vi_for_tree (tree t, varinfo_t *vi)
+static varinfo_t
+lookup_vi_for_tree (tree t)
{
- tree_vi_t pair;
- struct tree_vi finder;
+ void **slot = pointer_map_contains (vi_for_tree, t);
+ if (slot == NULL)
+ return NULL;
- finder.t = t;
- pair = htab_find (vi_for_tree, &finder);
- if (pair == NULL)
- return false;
- *vi = pair->vi;
- return true;
+ return (varinfo_t) *slot;
}
/* Return a printable name for DECL */
@@ -2235,21 +2199,17 @@ alias_get_name (tree decl)
return res;
}
-/* Find the variable id for tree T in the hashtable.
- If T doesn't exist in the hash table, create an entry for it. */
+/* Find the variable id for tree T in the map.
+ If T doesn't exist in the map, create an entry for it and return it. */
static varinfo_t
get_vi_for_tree (tree t)
{
- tree_vi_t pair;
- struct tree_vi finder;
-
- finder.t = t;
- pair = htab_find (vi_for_tree, &finder);
- if (pair == NULL)
+ void **slot = pointer_map_contains (vi_for_tree, t);
+ if (slot == NULL)
return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
- return pair->vi;
+ return (varinfo_t) *slot;
}
/* Get a constraint expression from an SSA_VAR_P node. */
@@ -4383,9 +4343,9 @@ find_what_p_points_to (tree p)
&& SSA_NAME_IS_DEFAULT_DEF (p))
lookup_p = SSA_NAME_VAR (p);
- if (lookup_vi_for_tree (lookup_p, &vi))
+ vi = lookup_vi_for_tree (lookup_p);
+ if (vi)
{
-
if (vi->is_artificial_var)
return false;
@@ -4633,7 +4593,7 @@ init_alias_vars (void)
sizeof (struct variable_info), 30);
constraints = VEC_alloc (constraint_t, heap, 8);
varmap = VEC_alloc (varinfo_t, heap, 8);
- vi_for_tree = htab_create (10, tree_vi_hash, tree_vi_eq, free);
+ vi_for_tree = pointer_map_create ();
memset (&stats, 0, sizeof (stats));
@@ -4774,7 +4734,7 @@ delete_points_to_sets (void)
fprintf (dump_file, "Points to sets created:%d\n",
stats.points_to_sets_created);
- htab_delete (vi_for_tree);
+ pointer_map_destroy (vi_for_tree);
bitmap_obstack_release (&pta_obstack);
VEC_free (constraint_t, heap, constraints);