aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2006-03-25 19:17:26 +0000
committerDaniel Berlin <dberlin@gcc.gnu.org>2006-03-25 19:17:26 +0000
commitfe1f8f442ef9952650c38ae0383498d41965775c (patch)
tree224a37b6b651b721ab029a9a7063751f561e976e /gcc
parent1d8b38a080f6862c5e0e1f407851e9b73c622e33 (diff)
downloadgcc-fe1f8f442ef9952650c38ae0383498d41965775c.zip
gcc-fe1f8f442ef9952650c38ae0383498d41965775c.tar.gz
gcc-fe1f8f442ef9952650c38ae0383498d41965775c.tar.bz2
re PR tree-optimization/26804 (Alias Time explosion)
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. From-SVN: r112380
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/passes.c1
-rw-r--r--gcc/tree-flow-inline.h11
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-ssa-alias.c31
-rw-r--r--gcc/tree-ssa.c41
-rw-r--r--gcc/tree.h11
7 files changed, 110 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index acaf8b6..3dc469a 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 ab37f20..0ca4cf5 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 6a37b86..f83c89c 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 6a457ca..134c457 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 7b702f0..e1fcb0b 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 2dab5c6..1446612 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 04fe738..27f4b0f 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