re PR tree-optimization/26804 (Alias Time explosion)
authorDaniel Berlin <dberlin@dberlin.org>
Sat, 25 Mar 2006 19:17:26 +0000 (19:17 +0000)
committerDaniel Berlin <dberlin@gcc.gnu.org>
Sat, 25 Mar 2006 19:17:26 +0000 (19:17 +0000)
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

gcc/ChangeLog
gcc/passes.c
gcc/tree-flow-inline.h
gcc/tree-pass.h
gcc/tree-ssa-alias.c
gcc/tree-ssa.c
gcc/tree.h

index acaf8b6e4b87048ecc0e0f017dca89e41ae3e2a2..3dc469ac2d3b13dae3c97789b694c60203e3fee8 100644 (file)
@@ -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>
 
index ab37f20798fd089256465a846cbc835acf195f89..0ca4cf5df5879831b192e8ef2d65cd7007020751 100644 (file)
@@ -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);
index 6a37b863c4c40d1ff348f83dcf57d5667115bcb5..f83c89c593ac1aa167dd700dc20aefe0e1372fba 100644 (file)
@@ -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;
 }
index 6a457cabf63cd6e181bcb3219bbf317f26eb832a..134c4577b88bfd3b17f66718e82c1e4438d43cc9 100644 (file)
@@ -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;
index 7b702f00765daf6de879d0b02f17b70fb6edd908..e1fcb0be8315f365e75589f759de64d38e23cae6 100644 (file)
@@ -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 */
+};
index 2dab5c6835d9a7109566e2b321626a62c3486379..14466124318b8556a10ecdd2e3be16bbf177395d 100644 (file)
@@ -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 ();
 }
 
index 04fe738e7b003a7e33ff5bd715021f2f0e94a10d..27f4b0fd76abd10c93951952cb89065a351e7f85 100644 (file)
@@ -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