diff options
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/passes.c | 12 | ||||
-rw-r--r-- | gcc/tree-flow.h | 2 | ||||
-rw-r--r-- | gcc/tree-pass.h | 6 | ||||
-rw-r--r-- | gcc/tree-sra.c | 7 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 81 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 21 | ||||
-rw-r--r-- | gcc/tree.h | 5 |
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; |