summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/passes.c12
-rw-r--r--gcc/tree-flow.h2
-rw-r--r--gcc/tree-pass.h6
-rw-r--r--gcc/tree-sra.c7
-rw-r--r--gcc/tree-ssa-alias.c81
-rw-r--r--gcc/tree-ssa-forwprop.c5
-rw-r--r--gcc/tree-ssa-operands.c21
-rw-r--r--gcc/tree.h5
9 files changed, 150 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ce38f1879c1..c811f208323 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2006-02-20 Daniel Berlin <dberlin@dberlin.org>
+
+ * tree.h (struct tree_memory_tag): Add is_used_alone member.
+ (TMT_USED_ALONE): New macro.
+ * tree-pass.h (PROP_tmt_usage): New property.
+ (TODO_update_tmt_usage): New todo.
+ * tree-ssa-alias.c (updating_used_alone): New variable.
+ (recalculate_used_alone): New function.
+ (compute_may_aliases): Set updating_used_alone, call
+ recalculate_used_alone.
+ * tree-sra.c (pass_sra): Note that this pass destroys
+ PROP_tmt_usage, and add TODO_update_tmt_usage.
+ * tree-ssa-forwprop.c (pass_forwprop): Ditto.
+ * tree-flow.h (updating_used_alone): Prototype.
+ (recalculate_used_alone): Ditto.
+ * passes.c (execute_todo): Add code to set updating_used_alone,
+ and call recalculate.
+ * tree-ssa-operands.c (add_virtual_operand): Only append bare def
+ for clobber if used alone, and add assert to verify used_alone
+ status.
+
2006-02-20 Angel Nunez Mencias <anunez@de.ibm.com>
* config/s390/s390.c (legitimize_pic_address): Assertions checking
diff --git a/gcc/passes.c b/gcc/passes.c
index e088be11e89..43efc7f88f0 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -718,8 +718,12 @@ execute_todo (unsigned int flags)
flags &= ~last_verified;
if (!flags)
return;
+
+ /* Always recalculate TMT usage before doing anything else. */
+ if (flags & TODO_update_tmt_usage)
+ recalculate_used_alone ();
- /* Always cleanup the CFG before doing anything else. */
+ /* Always cleanup the CFG before trying to update SSA . */
if (flags & TODO_cleanup_cfg)
{
if (current_loops)
@@ -822,6 +826,9 @@ execute_one_pass (struct tree_opt_pass *pass)
gcc_assert ((curr_properties & pass->properties_required)
== pass->properties_required);
+ if (pass->properties_destroyed & PROP_tmt_usage)
+ updating_used_alone = true;
+
/* If a dump file name is present, open it if enabled. */
if (pass->static_pass_number != -1)
{
@@ -888,6 +895,9 @@ execute_one_pass (struct tree_opt_pass *pass)
dump_file = NULL;
}
+ if (pass->properties_destroyed & PROP_tmt_usage)
+ updating_used_alone = false;
+
return true;
}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 32b8c9f6da6..5f4bd5ead6f 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -938,4 +938,6 @@ void delete_alias_heapvars (void);
void swap_tree_operands (tree, tree *, tree *);
+extern void recalculate_used_alone (void);
+extern bool updating_used_alone;
#endif /* _TREE_FLOW_H */
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index baa60da96e3..658b6241c7e 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -152,6 +152,8 @@ struct dump_file_info
#define PROP_rtl (1 << 8)
#define PROP_alias (1 << 9)
#define PROP_gimple_lomp (1 << 10) /* lowered OpenMP directives */
+#define PROP_tmt_usage (1 << 11) /* which TMT's are
+ used alone. */
#define PROP_trees \
(PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp)
@@ -212,6 +214,10 @@ struct dump_file_info
for the passes that are handed to register_dump_files. */
#define TODO_set_props (1 << 12)
+/* Set by passes that may make TMT's that were previously never used
+ in statements, used. */
+#define TODO_update_tmt_usage (1 << 13)
+
#define TODO_update_ssa_any \
(TODO_update_ssa \
| TODO_update_ssa_no_phi \
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 37e2a3a5c4d..6d1a1781c1c 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2223,9 +2223,10 @@ struct tree_opt_pass pass_sra =
TV_TREE_SRA, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ PROP_tmt_usage, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_update_ssa
- | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
+ TODO_update_tmt_usage | TODO_dump_func /* todo_flags_finish */
+ | TODO_update_ssa
+ | TODO_ggc_collect | TODO_verify_ssa,
0 /* letter */
};
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index bb2c3ce5c9e..a32c8439657 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -392,6 +392,12 @@ set_initial_properties (struct alias_info *ai)
}
}
+/* This variable is set to true if we are updating the used alone
+ information for TMT's, or are in a pass that is going to break it
+ temporarily. */
+
+bool updating_used_alone;
+
/* Compute which variables need to be marked call clobbered because
their tag is call clobbered, and which tags need to be marked
global because they contain global variables. */
@@ -417,6 +423,76 @@ compute_call_clobbered (struct alias_info *ai)
compute_tag_properties ();
}
+
+/* Recalculate the used_alone information for TMT's . */
+void
+recalculate_used_alone (void)
+{
+ VEC (tree, heap) *calls = NULL;
+ block_stmt_iterator bsi;
+ basic_block bb;
+ tree stmt;
+ size_t i;
+ referenced_var_iterator rvi;
+ tree var;
+
+ /* First, reset all the TMT used alone bits to zero. */
+ updating_used_alone = true;
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ if (TREE_CODE (var) == TYPE_MEMORY_TAG)
+ TMT_USED_ALONE (var) = 0;
+
+ /* Walk all the statements.
+ Calls get put into a list of statements to update, since we will
+ need to update operands on them if we make any changes.
+ If we see a bare use of a TMT anywhere in a real virtual use or virtual
+ def, mark the TMT as used alone, and for renaming. */
+
+
+ FOR_EACH_BB (bb)
+ {
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ if (TREE_CODE (stmt) == CALL_EXPR
+ || (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
+ VEC_safe_push (tree, heap, calls, stmt);
+ else
+ {
+ ssa_op_iter iter;
+
+ FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter,
+ SSA_OP_VUSE | SSA_OP_VIRTUAL_DEFS)
+ {
+ tree svar = var;
+
+ if(TREE_CODE (var) == SSA_NAME)
+ svar = SSA_NAME_VAR (var);
+
+ if (TREE_CODE (svar) == TYPE_MEMORY_TAG)
+ {
+ if (!TMT_USED_ALONE (svar))
+ {
+ TMT_USED_ALONE (svar) = true;
+ mark_sym_for_renaming (svar);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Update the operands on all the calls we saw. */
+ if (calls)
+ {
+ for (i = 0; VEC_iterate (tree, calls, i, stmt); i++)
+ update_stmt (stmt);
+ }
+ VEC_free (tree, heap, calls);
+ updating_used_alone = false;
+}
+
/* Compute may-alias information for every variable referenced in function
FNDECL.
@@ -585,6 +661,7 @@ compute_may_aliases (void)
/* Deallocate memory used by aliasing data structures. */
delete_alias_info (ai);
+ updating_used_alone = true;
{
block_stmt_iterator bsi;
basic_block bb;
@@ -596,9 +673,11 @@ compute_may_aliases (void)
}
}
}
-
+ recalculate_used_alone ();
+ updating_used_alone = false;
}
+
struct tree_opt_pass pass_may_alias =
{
"alias", /* name */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 892edde7a36..bcd4a13a4e3 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1011,9 +1011,10 @@ struct tree_opt_pass pass_forwprop = {
PROP_cfg | PROP_ssa
| PROP_alias, /* properties_required */
0, /* properties_provided */
- 0, /* properties_destroyed */
+ PROP_tmt_usage, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
+ TODO_update_tmt_usage |TODO_dump_func /* todo_flags_finish */
+ | TODO_ggc_collect
| TODO_update_ssa | TODO_verify_ssa,
0 /* letter */
};
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 748ff5d62f6..de578a74df1 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1844,11 +1844,26 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
It is also necessary to add bare defs on clobbers for
TMT's, so that bare TMT uses caused by pruning all the
- aliases will link up properly with calls. */
+ aliases will link up properly with calls. In order to
+ keep the number of these bare defs we add down to the
+ minimum necessary, we keep track of which TMT's were used
+ alone in statement defs or vuses. */
+
if (v_ann->is_aliased
|| none_added
- || (TREE_CODE (var) == TYPE_MEMORY_TAG && for_clobber))
- append_v_may_def (var);
+ || (TREE_CODE (var) == TYPE_MEMORY_TAG && for_clobber
+ && TMT_USED_ALONE (var)))
+ {
+ /* Every bare tmt def we add should have TMT_USED_ALONE
+ set on it, or else we will get the wrong answer on
+ clobbers. */
+
+ if (none_added && !updating_used_alone && aliases_computed_p
+ && TREE_CODE (var) == TYPE_MEMORY_TAG)
+ gcc_assert (TMT_USED_ALONE (var));
+
+ append_v_may_def (var);
+ }
}
else
{
diff --git a/gcc/tree.h b/gcc/tree.h
index 3a321eb1872..61a1d470f44 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2310,10 +2310,15 @@ struct tree_memory_tag GTY(())
{
struct tree_decl_minimal common;
unsigned int is_global:1;
+ unsigned int is_used_alone:1;
};
#define MTAG_GLOBAL(NODE) (TREE_MEMORY_TAG_CHECK (NODE)->mtag.is_global)
+/* This flag is true if a TMT is used as the vdef or vuse operand directly,
+ because the access had all of the TMT's aliases pruned from it. */
+#define TMT_USED_ALONE(NODE) (TYPE_MEMORY_TAG_CHECK (NODE)->mtag.is_used_alone)
+
struct tree_struct_field_tag GTY(())
{
struct tree_memory_tag common;