OSDN Git Service

2005-06-28 Thomas Koenig <Thomas.Koenig@online.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa.c
index 8efbdde..1a09ef9 100644 (file)
@@ -15,8 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA.  */
 #include "hard-reg-set.h"
 #include "basic-block.h"
 #include "output.h"
-#include "errors.h"
 #include "expr.h"
 #include "function.h"
 #include "diagnostic.h"
@@ -45,6 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #include "hashtab.h"
 #include "tree-dump.h"
 #include "tree-pass.h"
+#include "toplev.h"
 
 /* Remove the corresponding arguments from the PHI nodes in E's
    destination block and redirect it to DEST.  Return redirected edge.
@@ -493,7 +493,8 @@ err:
   internal_error ("verify_flow_sensitive_alias_info failed.");
 }
 
-DEF_VEC_MALLOC_P (bitmap);
+DEF_VEC_P (bitmap);
+DEF_VEC_ALLOC_P (bitmap,heap);
 
 /* Verify that all name tags have different points to sets.
    This algorithm takes advantage of the fact that every variable with the
@@ -512,8 +513,8 @@ verify_name_tags (void)
   size_t i;  
   size_t j;
   bitmap first, second;  
-  VEC (tree) *name_tag_reps = NULL;
-  VEC (bitmap) *pt_vars_for_reps = NULL;
+  VEC(tree,heap) *name_tag_reps = NULL;
+  VEC(bitmap,heap) *pt_vars_for_reps = NULL;
   bitmap type_aliases = BITMAP_ALLOC (NULL);
 
   /* First we compute the name tag representatives and their points-to sets.  */
@@ -539,8 +540,8 @@ verify_name_tags (void)
       if (pi->pt_vars == NULL)
        continue;
 
-      VEC_safe_push (tree, name_tag_reps, ptr);
-      VEC_safe_push (bitmap, pt_vars_for_reps, pi->pt_vars);
+      VEC_safe_push (tree, heap, name_tag_reps, ptr);
+      VEC_safe_push (bitmap, heap, pt_vars_for_reps, pi->pt_vars);
 
       /* Verify that alias set of PTR's type tag is a superset of the
         alias set of PTR's name tag.  */
@@ -605,7 +606,10 @@ verify_name_tags (void)
        }
     } 
 
-  VEC_free (bitmap, pt_vars_for_reps);
+  /* We do not have to free the bitmaps or trees in the vectors, as
+     they are not owned by us.  */
+  VEC_free (bitmap, heap, pt_vars_for_reps);
+  VEC_free (tree, heap, name_tag_reps);
   BITMAP_FREE (type_aliases);
   return;
   
@@ -640,6 +644,10 @@ verify_ssa (bool check_modified_stmt)
   enum dom_state orig_dom_state = dom_computed[CDI_DOMINATORS];
   bitmap names_defined_in_bb = BITMAP_ALLOC (NULL);
 
+  gcc_assert (!need_ssa_update_p ());
+
+  verify_stmts ();
+
   timevar_push (TV_TREE_SSA_VERIFY);
 
   /* Keep track of SSA names present in the IL.  */
@@ -701,8 +709,8 @@ verify_ssa (bool check_modified_stmt)
 
          if (check_modified_stmt && stmt_modified_p (stmt))
            {
-             error ("Stmt (0x%x) marked modified after optimization pass : ",
-                    (unsigned long)stmt);
+             error ("Stmt (%p) marked modified after optimization pass : ",
+                    (void *)stmt);
              print_generic_stmt (stderr, stmt, TDF_VOPS);
              goto err;
            }
@@ -717,8 +725,7 @@ verify_ssa (bool check_modified_stmt)
 
              if (base_address
                  && SSA_VAR_P (base_address)
-                 && NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0
-                 && NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) == 0)
+                 && ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
                {
                  error ("Statement makes a memory store, but has no "
                         "V_MAY_DEFS nor V_MUST_DEFS");
@@ -729,7 +736,7 @@ verify_ssa (bool check_modified_stmt)
 
 
          if (stmt_ann (stmt)->makes_aliased_stores 
-             && NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0)
+             && ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF))
            {
              error ("Statement makes aliased stores, but has no V_MAY_DEFS");
              print_generic_stmt (stderr, stmt, TDF_VOPS);
@@ -747,9 +754,7 @@ verify_ssa (bool check_modified_stmt)
            }
 
          FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
-           {
-             bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
-           }
+           bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
        }
 
       bitmap_clear (names_defined_in_bb);
@@ -759,6 +764,7 @@ verify_ssa (bool check_modified_stmt)
   verify_alias_info ();
 
   free (definition_block);
+
   /* Restore the dominance information to its prior known state, so
      that we do not perturb the compiler's subsequent behavior.  */
   if (orig_dom_state == DOM_NONE)
@@ -780,7 +786,7 @@ err:
 void
 init_tree_ssa (void)
 {
-  VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
+  referenced_vars = VEC_alloc (tree, gc, 20);
   call_clobbered_vars = BITMAP_ALLOC (NULL);
   addressable_vars = BITMAP_ALLOC (NULL);
   init_ssanames ();
@@ -799,28 +805,42 @@ delete_tree_ssa (void)
   basic_block bb;
   block_stmt_iterator bsi;
 
+  /* Release any ssa_names still in use.  */
+  for (i = 0; i < num_ssa_names; i++)
+    {
+      tree var = ssa_name (i);
+      if (var && TREE_CODE (var) == SSA_NAME)
+        {
+         SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
+         SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
+       }
+      release_ssa_name (var);
+    }
+
   /* Remove annotations from every tree in the function.  */
   FOR_EACH_BB (bb)
-    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-      {
-       tree stmt = bsi_stmt (bsi);
-        release_defs (stmt);
-       ggc_free (stmt->common.ann);
-       stmt->common.ann = NULL;
-      }
-
-  /* Remove annotations from every referenced variable.  */
-  if (referenced_vars)
     {
-      for (i = 0; i < num_referenced_vars; i++)
+      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
        {
-         tree var = referenced_var (i);
-         ggc_free (var->common.ann);
-         var->common.ann = NULL;
+         tree stmt = bsi_stmt (bsi);
+         stmt_ann_t ann = get_stmt_ann (stmt);
+
+         free_ssa_operands (&ann->operands);
+         ann->addresses_taken = 0;
+         mark_stmt_modified (stmt);
        }
-      referenced_vars = NULL;
+      set_phi_nodes (bb, NULL);
     }
 
+  /* Remove annotations from every referenced variable.  */
+  for (i = 0; i < num_referenced_vars; i++)
+    {
+      tree var = referenced_var (i);
+      ggc_free (var->common.ann);
+      var->common.ann = NULL;
+    }
+  VEC_free (tree, gc, referenced_vars);
+
   fini_ssanames ();
   fini_phinodes ();
 
@@ -831,11 +851,12 @@ delete_tree_ssa (void)
   addressable_vars = NULL;
   modified_noreturn_calls = NULL;
   aliases_computed_p = false;
+  gcc_assert (!need_ssa_update_p ());
 }
 
 
-/* Return true if EXPR is a useless type conversion, otherwise return
-   false.  */
+/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
+   useless type conversion, otherwise return false.  */
 
 bool
 tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
@@ -866,8 +887,9 @@ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
           && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
     return true;
 
-  /* Pointers and references are equivalent once we get to GENERIC,
-     so strip conversions that just switch between them.  */
+  /* Pointers/references are equivalent if their pointed to types
+     are effectively the same.  This allows to strip conversions between
+     pointer types with different type qualifiers.  */
   else if (POINTER_TYPE_P (inner_type)
            && POINTER_TYPE_P (outer_type)
           && TYPE_REF_CAN_ALIAS_ALL (inner_type)
@@ -886,7 +908,9 @@ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
   else if (INTEGRAL_TYPE_P (inner_type)
            && INTEGRAL_TYPE_P (outer_type)
           && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
-          && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
+          && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)
+          && simple_cst_equal (TYPE_MAX_VALUE (inner_type), TYPE_MAX_VALUE (outer_type))
+          && simple_cst_equal (TYPE_MIN_VALUE (inner_type), TYPE_MIN_VALUE (outer_type)))
     {
       bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
       bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
@@ -935,9 +959,7 @@ stmt_references_memory_p (tree stmt)
   if (ann->has_volatile_ops)
     return true;
 
-  return (NUM_VUSES (VUSE_OPS (ann)) > 0
-         || NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
-         || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0);
+  return (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS));
 }
 
 /* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
@@ -1066,7 +1088,7 @@ walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
    warning text is in MSGID and LOCUS may contain a location or be null.  */
 
 static void
-warn_uninit (tree t, const char *msgid, void *data)
+warn_uninit (tree t, const char *gmsgid, void *data)
 {
   tree var = SSA_NAME_VAR (t);
   tree def = SSA_NAME_DEF_STMT (t);
@@ -1094,7 +1116,7 @@ warn_uninit (tree t, const char *msgid, void *data)
   locus = (context != NULL && EXPR_HAS_LOCATION (context)
           ? EXPR_LOCUS (context)
           : &DECL_SOURCE_LOCATION (var));
-  warning (msgid, locus, var);
+  warning (0, gmsgid, locus, var);
   TREE_NO_WARNING (var) = 1;
 }