diff options
author | dberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-25 19:17:26 +0000 |
---|---|---|
committer | dberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-25 19:17:26 +0000 |
commit | 604eef2cbd1a1c2dd2b268b3f5e4eedeb70c3983 (patch) | |
tree | 224a37b6b651b721ab029a9a7063751f561e976e /gcc | |
parent | c2c965913f11f7a2a85aff51f95818fa8a084ec3 (diff) | |
download | gcc-604eef2cbd1a1c2dd2b268b3f5e4eedeb70c3983.tar.gz |
2006-03-25 Daniel Berlin <dberlin@dberlin.org>
PR tree-optimization/26804
* tree.h (DECL_CALL_CLOBBERED): New macro.
(tree_decl_common): Add call_clobbered_flag.
* tree-flow-inline.h (is_call_clobbered): Use DECL_CALL_CLOBBERED.
(mark_call_clobbered): Set DECL_CALL_CLOBBERED.
(clear_call_clobbered): Clear DECL_CALL_CLOBBERED.
(mark_non_addressable): Ditto.
* tree-ssa.c (verify_call_clobbered): New function.
(verify_alias_info): Use it.
* tree-pass.h (pass_reset_cc_flags): New prototype.
* tree-ssa-alias.c (pass_reset_cc_flags): New structure.
(reset_cc_flags): New function.
* passes.c (init_optimization_passes): Call reset_cc_flags after
initializing referenced_vars.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112380 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/passes.c | 1 | ||||
-rw-r--r-- | gcc/tree-flow-inline.h | 11 | ||||
-rw-r--r-- | gcc/tree-pass.h | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 31 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 41 | ||||
-rw-r--r-- | gcc/tree.h | 11 |
7 files changed, 110 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index acaf8b6e4b8..3dc469ac2d3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2006-03-25 Daniel Berlin <dberlin@dberlin.org> + + PR tree-optimization/26804 + * tree.h (DECL_CALL_CLOBBERED): New macro. + (tree_decl_common): Add call_clobbered_flag. + * tree-flow-inline.h (is_call_clobbered): Use DECL_CALL_CLOBBERED. + (mark_call_clobbered): Set DECL_CALL_CLOBBERED. + (clear_call_clobbered): Clear DECL_CALL_CLOBBERED. + (mark_non_addressable): Ditto. + * tree-ssa.c (verify_call_clobbered): New function. + (verify_alias_info): Use it. + * tree-pass.h (pass_reset_cc_flags): New prototype. + * tree-ssa-alias.c (pass_reset_cc_flags): New structure. + (reset_cc_flags): New function. + * passes.c (init_optimization_passes): Call reset_cc_flags after + initializing referenced_vars. + 2006-03-25 Uros Bizjak <uros@kss-loka.si> Roger Sayle <roger@eyesopen.com> diff --git a/gcc/passes.c b/gcc/passes.c index ab37f20798f..0ca4cf5df58 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -487,6 +487,7 @@ init_optimization_passes (void) p = &pass_all_optimizations.sub; NEXT_PASS (pass_referenced_vars); + NEXT_PASS (pass_reset_cc_flags); NEXT_PASS (pass_create_structure_vars); NEXT_PASS (pass_build_ssa); NEXT_PASS (pass_may_alias); diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 6a37b863c4c..f83c89c593a 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -821,7 +821,10 @@ loop_containing_stmt (tree stmt) static inline bool is_call_clobbered (tree var) { - return bitmap_bit_p (call_clobbered_vars, DECL_UID (var)); + if (!MTAG_P (var)) + return DECL_CALL_CLOBBERED (var); + else + return bitmap_bit_p (call_clobbered_vars, DECL_UID (var)); } /* Mark variable VAR as being clobbered by function calls. */ @@ -829,6 +832,8 @@ static inline void mark_call_clobbered (tree var, unsigned int escape_type) { var_ann (var)->escape_mask |= escape_type; + if (!MTAG_P (var)) + DECL_CALL_CLOBBERED (var) = true; bitmap_set_bit (call_clobbered_vars, DECL_UID (var)); } @@ -840,6 +845,8 @@ clear_call_clobbered (tree var) ann->escape_mask = 0; if (MTAG_P (var) && TREE_CODE (var) != STRUCT_FIELD_TAG) MTAG_GLOBAL (var) = 0; + if (!MTAG_P (var)) + DECL_CALL_CLOBBERED (var) = false; bitmap_clear_bit (call_clobbered_vars, DECL_UID (var)); } @@ -847,6 +854,8 @@ clear_call_clobbered (tree var) static inline void mark_non_addressable (tree var) { + if (!MTAG_P (var)) + DECL_CALL_CLOBBERED (var) = false; bitmap_clear_bit (call_clobbered_vars, DECL_UID (var)); TREE_ADDRESSABLE (var) = 0; } diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 6a457cabf63..134c4577b88 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -304,6 +304,7 @@ extern struct tree_opt_pass pass_uncprop; extern struct tree_opt_pass pass_return_slot; extern struct tree_opt_pass pass_reassoc; extern struct tree_opt_pass pass_rebuild_cgraph_edges; +extern struct tree_opt_pass pass_reset_cc_flags; /* IPA Passes */ extern struct tree_opt_pass pass_ipa_cp; diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 7b702f00765..e1fcb0be831 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -3193,3 +3193,34 @@ struct tree_opt_pass pass_create_structure_vars = TODO_dump_func, /* todo_flags_finish */ 0 /* letter */ }; + +/* Reset the DECL_CALL_CLOBBERED flags on our referenced vars. In + theory, this only needs to be done for globals. */ + +static unsigned int +reset_cc_flags (void) +{ + tree var; + referenced_var_iterator rvi; + + FOR_EACH_REFERENCED_VAR (var, rvi) + DECL_CALL_CLOBBERED (var) = false; + return 0; +} + +struct tree_opt_pass pass_reset_cc_flags = +{ + NULL, /* name */ + NULL, /* gate */ + reset_cc_flags, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + PROP_referenced_vars |PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 2dab5c6835d..14466124318 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -613,6 +613,46 @@ err: } +/* Verify the consistency of call clobbering information. */ +static void +verify_call_clobbering (void) +{ + unsigned int i; + bitmap_iterator bi; + tree var; + referenced_var_iterator rvi; + + /* At all times, the result of the DECL_CALL_CLOBBERED flag should + match the result of the call_clobbered_vars bitmap. Verify both + that everything in call_clobbered_vars is marked + DECL_CALL_CLOBBERED, and that everything marked + DECL_CALL_CLOBBERED is in call_clobbered_vars. */ + EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi) + { + var = referenced_var (i); + if (!MTAG_P (var) && !DECL_CALL_CLOBBERED (var)) + { + error ("variable in call_clobbered_vars but not marked DECL_CALL_CLOBBERED"); + debug_variable (var); + goto err; + } + } + FOR_EACH_REFERENCED_VAR (var, rvi) + { + if (!MTAG_P (var) && DECL_CALL_CLOBBERED (var) + && !bitmap_bit_p (call_clobbered_vars, DECL_UID (var))) + { + error ("variable marked DECL_CALL_CLOBBERED but not in call_clobbered_vars bitmap."); + debug_variable (var); + goto err; + } + } + return; + + err: + internal_error ("verify_call_clobbering failed"); +} + /* Verify the consistency of aliasing information. */ static void @@ -620,6 +660,7 @@ verify_alias_info (void) { verify_flow_sensitive_alias_info (); verify_name_tags (); + verify_call_clobbering (); verify_flow_insensitive_alias_info (); } diff --git a/gcc/tree.h b/gcc/tree.h index 04fe738e7b0..27f4b0fd76a 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2486,6 +2486,12 @@ struct tree_struct_field_tag GTY(()) #define DECL_COMPLEX_GIMPLE_REG_P(DECL) \ DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag +/* This is true if DECL is call clobbered in the current function. + The result of this flag should always be the same as + bitmap_bit_p (call_clobbered_vars, DECL_UID (decl)). */ +#define DECL_CALL_CLOBBERED(DECL) \ + DECL_COMMON_CHECK (DECL)->decl_common.call_clobbered_flag + struct tree_decl_common GTY(()) { struct tree_decl_minimal common; @@ -2523,9 +2529,10 @@ struct tree_decl_common GTY(()) /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR. */ unsigned decl_flag_3 : 1; - /* Logically, this would go in a theoretical base shared by var and parm - decl. */ + /* Logically, these two would go in a theoretical base shared by var and + parm decl. */ unsigned gimple_reg_flag : 1; + unsigned call_clobbered_flag : 1; union tree_decl_u1 { /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is |