Makefile.in (tree-ssa-loop-ivopts.o): Add pointer-set.h dependency.

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.

From-SVN: r121648
This commit is contained in:
Paolo Bonzini 2007-02-06 14:34:51 +00:00 committed by Paolo Bonzini
parent 0802f6a2f7
commit 15814ba0a2
7 changed files with 217 additions and 373 deletions

View file

@ -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):

View file

@ -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 \

View file

@ -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.

View file

@ -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"

View file

@ -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;
tree niter;
void **slot;
slot = htab_find_slot_with_hash (data->niters, exit,
htab_hash_pointer (exit),
INSERT);
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))

View file

@ -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);

View file

@ -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);