aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog30
-rw-r--r--gcc/tree-flow.h9
-rw-r--r--gcc/tree-into-ssa.c258
-rw-r--r--gcc/tree-ssanames.c7
4 files changed, 162 insertions, 142 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7dd882c..6b1851a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 454445d..301bd7e 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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;
};
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index ea433ed..da747bf 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -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)
+ if (TREE_CODE (var) == SSA_NAME)
+ db_p = &get_ssa_name_ann (var)->def_blocks;
+ else
+ db_p = &get_var_info (var)->def_blocks;
+
+ if (!db_p->def_blocks)
{
- 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;
+ 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);
}
- else
- db_p = (struct def_blocks_d *) *slot;
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)
-{
- return ((const struct def_blocks_d *)p1)->var
- == ((const struct def_blocks_d *)p2)->var;
-}
-
-
-/* Free memory allocated by one entry in DEF_BLOCKS. */
-
-static void
-def_blocks_free (void *p)
+var_info_eq (const void *p1, const void *p2)
{
- 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);
+ return ((const struct var_info_d *)p1)->var
+ == ((const struct var_info_d *)p2)->var;
}
-/* 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
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 35e8751..67c406f 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -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));