aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/gimple-ssa.h3
-rw-r--r--gcc/passes.c9
-rw-r--r--gcc/tree-ssanames.c24
-rw-r--r--gcc/tree-ssanames.h1
5 files changed, 49 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ba82953..dd723b8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2015-09-30 Bernd Schmidt <bernds@redhat.com>
+
+ * gimple-ssa.h (gimple_df): Add free_ssanames_queue field.
+ * passes.c: Include tree-ssanames.h.
+ (execute_function_todo): Flush the pending free SSA_NAMEs after
+ eliminating unreachable basic blocks.
+ * tree-ssanames.c (FREE_SSANAMES_QUEUE): new.
+ (init_ssanames): Initialize FREE_SSANAMES_QUEUE.
+ (fini_ssanames): Finalize FREE_SSANAMES_QUEUE.
+ (flush_ssanames_freelist): New function.
+ (release_ssaname_fn): Put released names on the queue.
+ (pass_release_ssa_names::execute): Call flush_ssanames_freelist.
+ * tree-ssanames.h (flush_ssanames_freelist): Declare.
+
2015-09-30 Thomas Schwinge <thomas@codesourcery.com>
* config/i386/intelmic-mkoffload.c (main): Parse "-v" flag.
diff --git a/gcc/gimple-ssa.h b/gcc/gimple-ssa.h
index c89071e..39551da 100644
--- a/gcc/gimple-ssa.h
+++ b/gcc/gimple-ssa.h
@@ -90,6 +90,9 @@ struct GTY(()) gimple_df {
/* Free list of SSA_NAMEs. */
vec<tree, va_gc> *free_ssanames;
+ /* Queue of SSA_NAMEs to be freed at the next opportunity. */
+ vec<tree, va_gc> *free_ssanames_queue;
+
/* Hashtable holding definition for symbol. If this field is not NULL, it
means that the first reference to this variable in the function is a
USE or a VUSE. In those cases, the SSA renamer creates an SSA name
diff --git a/gcc/passes.c b/gcc/passes.c
index d06a293..5b41102 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgrtl.h"
#include "tree-ssa-live.h" /* For remove_unused_locals. */
#include "tree-cfgcleanup.h"
+#include "tree-ssanames.h"
using namespace gcc;
@@ -1913,6 +1914,14 @@ execute_function_todo (function *fn, void *data)
{
cleanup_tree_cfg ();
+ /* Once unreachable nodes have been removed from the CFG,
+ there can't be any lingering references to released
+ SSA_NAMES (because there is no more unreachable code).
+
+ Thus, now is the time to flush the SSA_NAMEs freelist. */
+ if (fn->gimple_df)
+ flush_ssaname_freelist ();
+
/* When cleanup_tree_cfg merges consecutive blocks, it may
perform some simplistic propagation when removing single
valued PHI nodes. This propagation may, in turn, cause the
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 7235dc3..64e2379 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -70,6 +70,7 @@ unsigned int ssa_name_nodes_reused;
unsigned int ssa_name_nodes_created;
#define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames
+#define FREE_SSANAMES_QUEUE(fun) (fun)->gimple_df->free_ssanames_queue
/* Initialize management of SSA_NAMEs to default SIZE. If SIZE is
@@ -92,6 +93,7 @@ init_ssanames (struct function *fn, int size)
least 50 elements reserved in it. */
SSANAMES (fn)->quick_push (NULL_TREE);
FREE_SSANAMES (fn) = NULL;
+ FREE_SSANAMES_QUEUE (fn) = NULL;
fn->gimple_df->ssa_renaming_needed = 0;
fn->gimple_df->rename_vops = 0;
@@ -104,6 +106,7 @@ fini_ssanames (void)
{
vec_free (SSANAMES (cfun));
vec_free (FREE_SSANAMES (cfun));
+ vec_free (FREE_SSANAMES_QUEUE (cfun));
}
/* Dump some simple statistics regarding the re-use of SSA_NAME nodes. */
@@ -115,6 +118,22 @@ ssanames_print_statistics (void)
fprintf (stderr, "SSA_NAME nodes reused: %u\n", ssa_name_nodes_reused);
}
+/* Move all SSA_NAMEs from FREE_SSA_NAMES_QUEUE to FREE_SSA_NAMES.
+
+ We do not, but should have a mode to verify the state of the SSA_NAMEs
+ lists. In particular at this point every name must be in the IL,
+ on the free list or in the queue. Anything else is an error. */
+
+void
+flush_ssaname_freelist (void)
+{
+ while (!vec_safe_is_empty (FREE_SSANAMES_QUEUE (cfun)))
+ {
+ tree t = FREE_SSANAMES_QUEUE (cfun)->pop ();
+ vec_safe_push (FREE_SSANAMES (cfun), t);
+ }
+}
+
/* Return an SSA_NAME node for variable VAR defined in statement STMT
in function FN. STMT may be an empty statement for artificial
references (e.g., default definitions created when a variable is
@@ -349,8 +368,8 @@ release_ssa_name_fn (struct function *fn, tree var)
/* Note this SSA_NAME is now in the first list. */
SSA_NAME_IN_FREE_LIST (var) = 1;
- /* And finally put it on the free list. */
- vec_safe_push (FREE_SSANAMES (fn), var);
+ /* And finally queue it so that it will be put on the free list. */
+ vec_safe_push (FREE_SSANAMES_QUEUE (fn), var);
}
}
@@ -631,6 +650,7 @@ unsigned int
pass_release_ssa_names::execute (function *fun)
{
unsigned i, j;
+ flush_ssaname_freelist ();
int n = vec_safe_length (FREE_SSANAMES (fun));
/* Now release the freelist. */
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index 5688ca5..a915d8f 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -98,6 +98,7 @@ extern void reset_flow_sensitive_info (tree);
extern void reset_flow_sensitive_info_in_bb (basic_block);
extern void release_defs (gimple *);
extern void replace_ssa_name_symbol (tree, tree);
+extern void flush_ssaname_freelist (void);
/* Return an SSA_NAME node for variable VAR defined in statement STMT