tree-flow.h (struct var_ann_d): Remove need_phi_state and current_def members.

2012-07-31  Richard Guenther  <rguenther@suse.de>

	* tree-flow.h (struct var_ann_d): Remove need_phi_state
	and current_def members.
	* tree-into-ssa.c (struct def_blocks_d): Remove var member.
	(def_blocks): Remove.
	(struct var_info_d): New.
	(var_infos): New hashtable.
	(struct ssa_name_info): Add def_blocks member.
	(get_ssa_name_ann): Adjust.
	(get_var_info): New function.
	(get_phi_state, set_phi_state, get_current_def,
	set_current_def, get_def_blocks_for, find_def_blocks_for): Adjust.
	(insert_phi_nodes_compare_def_blocks): Rename to ...
	(insert_phi_nodes_compare_var_infos): ... this and adjust.
	(insert_phi_nodes): Adjust.
	(dump_tree_ssa, dump_tree_ssa_stats): Adjust.
	(def_blocks_hash, def_blocks_eq, def_blocks_free): Remove.
	(debug_def_blocks_r): Rename to ...
	(debug_var_infos_r): ... this and adjust.
	(var_info_hash): New function.
	(var_info_eq): Likewise.
	(rewrite_blocks): Adjust.
	(init_ssa_renamer): Likewise.
	(fini_ssa_renamer): Likewise.
	(delete_update_ssa): Likewise.
	(update_ssa): Likewise.
	* tree-ssanames.c (release_dead_ssa_names): Do not clear
	current defs.

From-SVN: r190012
This commit is contained in:
Richard Guenther 2012-07-31 13:42:16 +00:00 committed by Richard Biener
parent 8539d639a8
commit b4e209fd1a
4 changed files with 163 additions and 143 deletions

View File

@ -1,3 +1,33 @@
2012-07-31 Richard Guenther <rguenther@suse.de>
* tree-flow.h (struct var_ann_d): Remove need_phi_state
and current_def members.
* tree-into-ssa.c (struct def_blocks_d): Remove var member.
(def_blocks): Remove.
(struct var_info_d): New.
(var_infos): New hashtable.
(struct ssa_name_info): Add def_blocks member.
(get_ssa_name_ann): Adjust.
(get_var_info): New function.
(get_phi_state, set_phi_state, get_current_def,
set_current_def, get_def_blocks_for, find_def_blocks_for): Adjust.
(insert_phi_nodes_compare_def_blocks): Rename to ...
(insert_phi_nodes_compare_var_infos): ... this and adjust.
(insert_phi_nodes): Adjust.
(dump_tree_ssa, dump_tree_ssa_stats): Adjust.
(def_blocks_hash, def_blocks_eq, def_blocks_free): Remove.
(debug_def_blocks_r): Rename to ...
(debug_var_infos_r): ... this and adjust.
(var_info_hash): New function.
(var_info_eq): Likewise.
(rewrite_blocks): Adjust.
(init_ssa_renamer): Likewise.
(fini_ssa_renamer): Likewise.
(delete_update_ssa): Likewise.
(update_ssa): Likewise.
* tree-ssanames.c (release_dead_ssa_names): Do not clear
current defs.
2012-07-31 Bill Schmidt <wschmidt@linux.ibm.com>
PR tree-optimization/53773

View File

@ -184,17 +184,8 @@ struct GTY(()) var_ann_d {
applied. We set this when translating out of SSA form. */
unsigned used : 1;
/* This field indicates whether or not the variable may need PHI nodes.
See the enum's definition for more detailed information about the
states. */
ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
/* Used by var_map for the base index of ssa base variables. */
unsigned base_index;
/* During into-ssa and the dominator optimizer, this field holds the
current version of this variable (an SSA_NAME). */
tree current_def;
};

View File

@ -52,9 +52,6 @@ along with GCC; see the file COPYING3. If not see
definitions for VAR. */
struct def_blocks_d
{
/* The variable. */
tree var;
/* Blocks that contain definitions of VAR. Bit I will be set if the
Ith block contains a definition of VAR. */
bitmap def_blocks;
@ -69,18 +66,6 @@ struct def_blocks_d
typedef struct def_blocks_d *def_blocks_p;
DEF_VEC_P(def_blocks_p);
DEF_VEC_ALLOC_P(def_blocks_p,heap);
/* Each entry in DEF_BLOCKS contains an element of type STRUCT
DEF_BLOCKS_D, mapping a variable VAR to a bitmap describing all the
basic blocks where VAR is defined (assigned a new value). It also
contains a bitmap of all the blocks where VAR is live-on-entry
(i.e., there is a use of VAR in block B without a preceding
definition in B). The live-on-entry information is used when
computing PHI pruning heuristics. */
static htab_t def_blocks;
/* Stack of trees used to restore the global currdefs to its original
state after completing rewriting of a block and its dominator
@ -142,6 +127,35 @@ struct mark_def_sites_global_data
};
/* Information stored for decls. */
struct var_info_d
{
/* The variable. */
tree var;
/* This field indicates whether or not the variable may need PHI nodes.
See the enum's definition for more detailed information about the
states. */
ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
/* The current reaching definition replacing this SSA name. */
tree current_def;
/* Definitions for this VAR. */
struct def_blocks_d def_blocks;
};
/* The information associated with decls. */
typedef struct var_info_d *var_info_p;
DEF_VEC_P(var_info_p);
DEF_VEC_ALLOC_P(var_info_p,heap);
/* Each entry in VAR_INFOS contains an element of type STRUCT
VAR_INFO_D. */
static htab_t var_infos;
/* Information stored for SSA names. */
struct ssa_name_info
{
@ -160,6 +174,9 @@ struct ssa_name_info
/* Replacement mappings, allocated from update_ssa_obstack. */
bitmap repl_set;
/* Definitions for this SSA name. */
struct def_blocks_d def_blocks;
};
/* The information associated with names. */
@ -203,8 +220,8 @@ extern void dump_update_ssa (FILE *);
extern void debug_update_ssa (void);
extern void dump_names_replaced_by (FILE *, tree);
extern void debug_names_replaced_by (tree);
extern void dump_def_blocks (FILE *);
extern void debug_def_blocks (void);
extern void dump_var_infos (FILE *);
extern void debug_var_infos (void);
extern void dump_defs_stack (FILE *, int);
extern void debug_defs_stack (int);
extern void dump_currdefs (FILE *);
@ -282,12 +299,34 @@ get_ssa_name_ann (tree name)
info->need_phi_state = NEED_PHI_STATE_UNKNOWN;
info->current_def = NULL_TREE;
info->repl_set = NULL;
info->def_blocks.def_blocks = NULL;
info->def_blocks.phi_blocks = NULL;
info->def_blocks.livein_blocks = NULL;
info->age = current_info_for_ssa_name_age;
}
return info;
}
/* Return and allocate the auxiliar information for DECL. */
static inline var_info_p
get_var_info (tree decl)
{
struct var_info_d vi;
void **slot;
vi.var = decl;
slot = htab_find_slot_with_hash (var_infos, &vi, DECL_UID (decl), INSERT);
if (*slot == NULL)
{
var_info_p v = XCNEW (struct var_info_d);
v->var = decl;
*slot = (void *)v;
return v;
}
return (var_info_p) *slot;
}
/* Clears info for SSA names. */
@ -310,7 +349,7 @@ get_phi_state (tree var)
if (TREE_CODE (var) == SSA_NAME)
return get_ssa_name_ann (var)->need_phi_state;
else
return var_ann (var)->need_phi_state;
return get_var_info (var)->need_phi_state;
}
@ -322,7 +361,7 @@ set_phi_state (tree var, enum need_phi_state state)
if (TREE_CODE (var) == SSA_NAME)
get_ssa_name_ann (var)->need_phi_state = state;
else
var_ann (var)->need_phi_state = state;
get_var_info (var)->need_phi_state = state;
}
@ -334,7 +373,7 @@ get_current_def (tree var)
if (TREE_CODE (var) == SSA_NAME)
return get_ssa_name_ann (var)->current_def;
else
return var_ann (var)->current_def;
return get_var_info (var)->current_def;
}
@ -346,7 +385,7 @@ set_current_def (tree var, tree def)
if (TREE_CODE (var) == SSA_NAME)
get_ssa_name_ann (var)->current_def = def;
else
var_ann (var)->current_def = def;
get_var_info (var)->current_def = def;
}
@ -448,22 +487,19 @@ mark_block_for_update (basic_block bb)
static inline struct def_blocks_d *
get_def_blocks_for (tree var)
{
struct def_blocks_d db, *db_p;
void **slot;
struct def_blocks_d *db_p;
db.var = var;
slot = htab_find_slot (def_blocks, (void *) &db, INSERT);
if (*slot == NULL)
{
db_p = XNEW (struct def_blocks_d);
db_p->var = var;
db_p->def_blocks = BITMAP_ALLOC (NULL);
db_p->phi_blocks = BITMAP_ALLOC (NULL);
db_p->livein_blocks = BITMAP_ALLOC (NULL);
*slot = (void *) db_p;
}
if (TREE_CODE (var) == SSA_NAME)
db_p = &get_ssa_name_ann (var)->def_blocks;
else
db_p = (struct def_blocks_d *) *slot;
db_p = &get_var_info (var)->def_blocks;
if (!db_p->def_blocks)
{
db_p->def_blocks = BITMAP_ALLOC (&update_ssa_obstack);
db_p->phi_blocks = BITMAP_ALLOC (&update_ssa_obstack);
db_p->livein_blocks = BITMAP_ALLOC (&update_ssa_obstack);
}
return db_p;
}
@ -922,9 +958,14 @@ prune_unused_phi_nodes (bitmap phis, bitmap kills, bitmap uses)
static inline struct def_blocks_d *
find_def_blocks_for (tree var)
{
struct def_blocks_d dm;
dm.var = var;
return (struct def_blocks_d *) htab_find (def_blocks, &dm);
def_blocks_p p;
if (TREE_CODE (var) == SSA_NAME)
p = &get_ssa_name_ann (var)->def_blocks;
else
p = &get_var_info (var)->def_blocks;
if (!p->def_blocks)
return NULL;
return p;
}
@ -1062,13 +1103,13 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
}
}
/* Sort def_blocks after DECL_UID of their var. */
/* Sort var_infos after DECL_UID of their var. */
static int
insert_phi_nodes_compare_def_blocks (const void *a, const void *b)
insert_phi_nodes_compare_var_infos (const void *a, const void *b)
{
const struct def_blocks_d *defa = *(struct def_blocks_d * const *)a;
const struct def_blocks_d *defb = *(struct def_blocks_d * const *)b;
const struct var_info_d *defa = *(struct var_info_d * const *)a;
const struct var_info_d *defb = *(struct var_info_d * const *)b;
if (DECL_UID (defa->var) < DECL_UID (defb->var))
return -1;
else
@ -1084,28 +1125,28 @@ insert_phi_nodes (bitmap_head *dfs)
{
htab_iterator hi;
unsigned i;
struct def_blocks_d *def_map;
VEC(def_blocks_p,heap) *vars;
var_info_p info;
VEC(var_info_p,heap) *vars;
timevar_push (TV_TREE_INSERT_PHI_NODES);
vars = VEC_alloc (def_blocks_p, heap, htab_elements (def_blocks));
FOR_EACH_HTAB_ELEMENT (def_blocks, def_map, struct def_blocks_d *, hi)
if (get_phi_state (def_map->var) != NEED_PHI_STATE_NO)
VEC_quick_push (def_blocks_p, vars, def_map);
vars = VEC_alloc (var_info_p, heap, htab_elements (var_infos));
FOR_EACH_HTAB_ELEMENT (var_infos, info, var_info_p, hi)
if (info->need_phi_state != NEED_PHI_STATE_NO)
VEC_quick_push (var_info_p, vars, info);
/* Do two stages to avoid code generation differences for UID
differences but no UID ordering differences. */
VEC_qsort (def_blocks_p, vars, insert_phi_nodes_compare_def_blocks);
VEC_qsort (var_info_p, vars, insert_phi_nodes_compare_var_infos);
FOR_EACH_VEC_ELT (def_blocks_p, vars, i, def_map)
FOR_EACH_VEC_ELT (var_info_p, vars, i, info)
{
bitmap idf = compute_idf (def_map->def_blocks, dfs);
insert_phi_nodes_for (def_map->var, idf, false);
bitmap idf = compute_idf (info->def_blocks.def_blocks, dfs);
insert_phi_nodes_for (info->var, idf, false);
BITMAP_FREE (idf);
}
VEC_free(def_blocks_p, heap, vars);
VEC_free(var_info_p, heap, vars);
timevar_pop (TV_TREE_INSERT_PHI_NODES);
}
@ -1634,7 +1675,7 @@ dump_tree_ssa (FILE *file)
fprintf (file, "SSA renaming information for %s\n\n", funcname);
dump_def_blocks (file);
dump_var_infos (file);
dump_defs_stack (file, -1);
dump_currdefs (file);
dump_tree_ssa_stats (file);
@ -1667,17 +1708,13 @@ htab_statistics (FILE *file, htab_t htab)
void
dump_tree_ssa_stats (FILE *file)
{
if (def_blocks)
fprintf (file, "\nHash table statistics:\n");
if (def_blocks)
if (var_infos)
{
fprintf (file, " def_blocks: ");
htab_statistics (file, def_blocks);
fprintf (file, "\nHash table statistics:\n");
fprintf (file, " var_infos: ");
htab_statistics (file, var_infos);
fprintf (file, "\n");
}
if (def_blocks)
fprintf (file, "\n");
}
@ -1690,71 +1727,57 @@ debug_tree_ssa_stats (void)
}
/* Hashing and equality functions for DEF_BLOCKS. */
/* Hashing and equality functions for VAR_INFOS. */
static hashval_t
def_blocks_hash (const void *p)
var_info_hash (const void *p)
{
return htab_hash_pointer
((const void *)((const struct def_blocks_d *)p)->var);
return DECL_UID (((const struct var_info_d *)p)->var);
}
static int
def_blocks_eq (const void *p1, const void *p2)
var_info_eq (const void *p1, const void *p2)
{
return ((const struct def_blocks_d *)p1)->var
== ((const struct def_blocks_d *)p2)->var;
return ((const struct var_info_d *)p1)->var
== ((const struct var_info_d *)p2)->var;
}
/* Free memory allocated by one entry in DEF_BLOCKS. */
static void
def_blocks_free (void *p)
{
struct def_blocks_d *entry = (struct def_blocks_d *) p;
BITMAP_FREE (entry->def_blocks);
BITMAP_FREE (entry->phi_blocks);
BITMAP_FREE (entry->livein_blocks);
free (entry);
}
/* Callback for htab_traverse to dump the DEF_BLOCKS hash table. */
/* Callback for htab_traverse to dump the VAR_INFOS hash table. */
static int
debug_def_blocks_r (void **slot, void *data)
debug_var_infos_r (void **slot, void *data)
{
FILE *file = (FILE *) data;
struct def_blocks_d *db_p = (struct def_blocks_d *) *slot;
struct var_info_d *db_p = (struct var_info_d *) *slot;
fprintf (file, "VAR: ");
print_generic_expr (file, db_p->var, dump_flags);
bitmap_print (file, db_p->def_blocks, ", DEF_BLOCKS: { ", "}");
bitmap_print (file, db_p->livein_blocks, ", LIVEIN_BLOCKS: { ", "}");
bitmap_print (file, db_p->phi_blocks, ", PHI_BLOCKS: { ", "}\n");
bitmap_print (file, db_p->def_blocks.def_blocks, ", DEF_BLOCKS: { ", "}");
bitmap_print (file, db_p->def_blocks.livein_blocks, ", LIVEIN_BLOCKS: { ", "}");
bitmap_print (file, db_p->def_blocks.phi_blocks, ", PHI_BLOCKS: { ", "}\n");
return 1;
}
/* Dump the DEF_BLOCKS hash table on FILE. */
/* Dump the VAR_INFOS hash table on FILE. */
void
dump_def_blocks (FILE *file)
dump_var_infos (FILE *file)
{
fprintf (file, "\n\nDefinition and live-in blocks:\n\n");
if (def_blocks)
htab_traverse (def_blocks, debug_def_blocks_r, file);
if (var_infos)
htab_traverse (var_infos, debug_var_infos_r, file);
}
/* Dump the DEF_BLOCKS hash table on stderr. */
/* Dump the VAR_INFOS hash table on stderr. */
DEBUG_FUNCTION void
debug_def_blocks (void)
debug_var_infos (void)
{
dump_def_blocks (stderr);
dump_var_infos (stderr);
}
@ -2245,7 +2268,7 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what)
if (dump_file && (dump_flags & TDF_STATS))
{
dump_dfa_stats (dump_file);
if (def_blocks)
if (var_infos)
dump_tree_ssa_stats (dump_file);
}
@ -2322,18 +2345,14 @@ mark_def_site_blocks (void)
static void
init_ssa_renamer (void)
{
tree var;
referenced_var_iterator rvi;
cfun->gimple_df->in_ssa_p = false;
/* Allocate memory for the DEF_BLOCKS hash table. */
gcc_assert (def_blocks == NULL);
def_blocks = htab_create (num_referenced_vars, def_blocks_hash,
def_blocks_eq, def_blocks_free);
gcc_assert (var_infos == NULL);
var_infos = htab_create (VEC_length (tree, cfun->local_decls),
var_info_hash, var_info_eq, NULL);
FOR_EACH_REFERENCED_VAR (cfun, var, rvi)
set_current_def (var, NULL_TREE);
bitmap_obstack_initialize (&update_ssa_obstack);
}
@ -2342,12 +2361,14 @@ init_ssa_renamer (void)
static void
fini_ssa_renamer (void)
{
if (def_blocks)
if (var_infos)
{
htab_delete (def_blocks);
def_blocks = NULL;
htab_delete (var_infos);
var_infos = NULL;
}
bitmap_obstack_release (&update_ssa_obstack);
cfun->gimple_df->in_ssa_p = true;
}
@ -2825,8 +2846,6 @@ delete_update_ssa (void)
BITMAP_FREE (blocks_with_phis_to_rewrite);
BITMAP_FREE (blocks_to_update);
bitmap_obstack_release (&update_ssa_obstack);
update_ssa_initialized_fn = NULL;
}
@ -3146,23 +3165,6 @@ update_ssa (unsigned update_flags)
insert_phi_p = (update_flags != TODO_update_ssa_no_phi);
if (insert_phi_p)
{
/* If the caller requested PHI nodes to be added, initialize
live-in information data structures (DEF_BLOCKS). */
/* For each SSA name N, the DEF_BLOCKS table describes where the
name is defined, which blocks have PHI nodes for N, and which
blocks have uses of N (i.e., N is live-on-entry in those
blocks). */
def_blocks = htab_create (num_ssa_names, def_blocks_hash,
def_blocks_eq, def_blocks_free);
}
else
{
def_blocks = NULL;
}
/* If there are names defined in the replacement table, prepare
definition and use sites for all the names in NEW_SSA_NAMES and
OLD_SSA_NAMES. */
@ -3181,6 +3183,10 @@ update_ssa (unsigned update_flags)
/* Next, determine the block at which to start the renaming process. */
if (!bitmap_empty_p (SYMS_TO_RENAME (cfun)))
{
/* If we rename bare symbols initialize the mapping to
auxiliar info we need to keep track of. */
var_infos = htab_create (47, var_info_hash, var_info_eq, NULL);
/* If we have to rename some symbols from scratch, we need to
start the process at the root of the CFG. FIXME, it should
be possible to determine the nearest block that had a

View File

@ -380,15 +380,8 @@ replace_ssa_name_symbol (tree ssa_name, tree sym)
static unsigned int
release_dead_ssa_names (void)
{
tree t;
unsigned i, j;
int n = VEC_length (tree, FREE_SSANAMES (cfun));
referenced_var_iterator rvi;
/* Current defs point to various dead SSA names that in turn point to
eventually dead variables so a bunch of memory is held live. */
FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
set_current_def (t, NULL);
/* Now release the freelist. */
VEC_free (tree, gc, FREE_SSANAMES (cfun));