OSDN Git Service

* config/i386/i386.md (*fop_<mode>_1_i387): Use SSE_FLOAT_MODE_P
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dse.c
index 3e0f04b..2f7e923 100644 (file)
@@ -1,5 +1,6 @@
 /* Dead store elimination
-   Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation,
+   Inc.
 
 This file is part of GCC.
 
@@ -101,19 +102,15 @@ static void dse_record_phis (struct dom_walk_data *, basic_block);
 static void dse_finalize_block (struct dom_walk_data *, basic_block);
 static void record_voperand_set (bitmap, bitmap *, unsigned int);
 
-static unsigned max_stmt_uid;  /* Maximal uid of a statement.  Uids to phi
-                                  nodes are assigned using the versions of
-                                  ssa names they define.  */
-
 /* Returns uid of statement STMT.  */
 
 static unsigned
 get_stmt_uid (tree stmt)
 {
   if (TREE_CODE (stmt) == PHI_NODE)
-    return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid;
+    return SSA_NAME_VERSION (PHI_RESULT (stmt)) + gimple_stmt_max_uid (cfun);
 
-  return stmt_ann (stmt)->uid;
+  return gimple_stmt_uid (stmt);
 }
 
 /* Set bit UID in bitmaps GLOBAL and *LOCAL, creating *LOCAL as needed.  */
@@ -211,7 +208,7 @@ memory_address_same (tree store1, tree store2)
 }
 
 /* Return true if there is a stmt that kills the lhs of STMT and is in the
-   virtual def-use chain of STMT without a use inbetween the kill and STMT.
+   virtual def-use chain of STMT without a use in between the kill and STMT.
    Returns false if no such stmt is found.
    *FIRST_USE_P is set to the first use of the single virtual def of
    STMT.  *USE_P is set to the vop killed by *USE_STMT.  */
@@ -288,7 +285,6 @@ dse_possible_dead_store_p (tree stmt,
   vuse_vec_p vv;
   tree defvar = NULL_TREE, temp;
   tree prev_defvar = NULL_TREE;
-  stmt_ann_t ann = stmt_ann (stmt);
 
   /* We want to verify that each virtual definition in STMT has
      precisely one use and that all the virtual definitions are
@@ -313,6 +309,14 @@ dse_possible_dead_store_p (tree stmt,
       gcc_assert (*use_p != NULL_USE_OPERAND_P);
       *first_use_p = *use_p;
 
+      /* ???  If we hit a PHI_NODE we could skip to the PHI_RESULT uses.
+        Don't bother to do that for now.  */
+      if (TREE_CODE (temp) == PHI_NODE)
+       {
+         fail = true;
+         break;
+       }
+
       /* In the case of memory partitions, we may get:
 
           # MPT.764_162 = VDEF <MPT.764_161(D)>
@@ -356,33 +360,10 @@ dse_possible_dead_store_p (tree stmt,
 
   if (fail)
     {
-      record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+      record_voperand_set (dse_gd->stores, &bd->stores, gimple_stmt_uid (stmt));
       return false;
     }
 
-  /* Skip through any PHI nodes we have already seen if the PHI
-     represents the only use of this store.
-
-     Note this does not handle the case where the store has
-     multiple VDEFs which all reach a set of PHI nodes in the same block.  */
-  while (*use_p != NULL_USE_OPERAND_P
-        && TREE_CODE (*use_stmt) == PHI_NODE
-        && bitmap_bit_p (dse_gd->stores, get_stmt_uid (*use_stmt)))
-    {
-      /* A PHI node can both define and use the same SSA_NAME if
-        the PHI is at the top of a loop and the PHI_RESULT is
-        a loop invariant and copies have not been fully propagated.
-
-        The safe thing to do is exit assuming no optimization is
-        possible.  */
-      if (SSA_NAME_DEF_STMT (PHI_RESULT (*use_stmt)) == *use_stmt)
-       return false;
-
-      /* Skip past this PHI and loop again in case we had a PHI
-        chain.  */
-      single_imm_use (PHI_RESULT (*use_stmt), use_p, use_stmt);
-    }
-
   return true;
 }
 
@@ -450,7 +431,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
              memory location.  */
           if (!get_kill_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt))
             {
-              record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+              record_voperand_set (dse_gd->stores, &bd->stores, gimple_stmt_uid (stmt));
               return;
             }
         }
@@ -470,24 +451,23 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
          vuse_vec_p vv;
          tree stmt_lhs;
 
-         if (LOADED_SYMS (use_stmt))
+         /* If use_stmt is or might be a nop assignment, e.g. for
+            struct { ... } S a, b, *p; ...
+            b = a; b = b;
+            or
+            b = a; b = *p; where p might be &b,
+            or
+            *p = a; *p = b; where p might be &b,
+            or
+            *p = *u; *p = *v; where p might be v, then USE_STMT
+            acts as a use as well as definition, so store in STMT
+            is not dead.  */
+         if (LOADED_SYMS (use_stmt)
+             && bitmap_intersect_p (LOADED_SYMS (use_stmt),
+                                    STORED_SYMS (use_stmt)))
            {
-             tree use_base
-               = get_base_address (GIMPLE_STMT_OPERAND (use_stmt, 0));
-             /* If use_stmt is or might be a nop assignment, e.g. for
-                struct { ... } S a, b, *p; ...
-                b = a; b = b;
-                or
-                b = a; b = *p; where p might be &b, then USE_STMT
-                acts as a use as well as definition, so store in STMT
-                is not dead.  */
-             if (TREE_CODE (use_base) == VAR_DECL
-                 && bitmap_bit_p (LOADED_SYMS (use_stmt),
-                                  DECL_UID (use_base)))
-               {
-                 record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
-                 return;
-               }
+             record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+             return;
            }
 
          if (dump_file && (dump_flags & TDF_DETAILS))
@@ -521,7 +501,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
          release_defs (stmt);
        }
 
-      record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+      record_voperand_set (dse_gd->stores, &bd->stores, gimple_stmt_uid (stmt));
     }
 }
 
@@ -572,18 +552,8 @@ tree_ssa_dse (void)
 {
   struct dom_walk_data walk_data;
   struct dse_global_data dse_gd;
-  basic_block bb;
 
-  /* Create a UID for each statement in the function.  Ordering of the
-     UIDs is not important for this pass.  */
-  max_stmt_uid = 0;
-  FOR_EACH_BB (bb)
-    {
-      block_stmt_iterator bsi;
-
-      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-       stmt_ann (bsi_stmt (bsi))->uid = max_stmt_uid++;
-    }
+  renumber_gimple_stmt_uids ();
 
   /* We might consider making this a property of each pass so that it
      can be [re]computed on an as-needed basis.  Particularly since
@@ -633,7 +603,10 @@ gate_dse (void)
   return flag_tree_dse != 0;
 }
 
-struct tree_opt_pass pass_dse = {
+struct gimple_opt_pass pass_dse = 
+{
+ {
+  GIMPLE_PASS,
   "dse",                       /* name */
   gate_dse,                    /* gate */
   tree_ssa_dse,                        /* execute */
@@ -649,8 +622,8 @@ struct tree_opt_pass pass_dse = {
   0,                           /* todo_flags_start */
   TODO_dump_func
     | TODO_ggc_collect
-    | TODO_verify_ssa,         /* todo_flags_finish */
-  0                            /* letter */
+    | TODO_verify_ssa          /* todo_flags_finish */
+ }
 };
 
 /* A very simple dead store pass eliminating write only local variables.
@@ -719,7 +692,7 @@ execute_simple_dse (void)
                if (TREE_THIS_VOLATILE (op))
                  dead = false;
 
-           /* Look for possible occurence var = indirect_ref (...) where
+           /* Look for possible occurrence var = indirect_ref (...) where
               indirect_ref itself is volatile.  */
 
            if (dead && TREE_THIS_VOLATILE (GIMPLE_STMT_OPERAND (stmt, 1)))
@@ -770,8 +743,10 @@ execute_simple_dse (void)
   return todo;
 }
 
-struct tree_opt_pass pass_simple_dse =
+struct gimple_opt_pass pass_simple_dse =
 {
+ {
+  GIMPLE_PASS,
   "sdse",                              /* name */
   NULL,                                        /* gate */
   execute_simple_dse,                  /* execute */
@@ -783,6 +758,6 @@ struct tree_opt_pass pass_simple_dse =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func,                      /* todo_flags_finish */
-  0                                    /* letter */
+  TODO_dump_func                       /* todo_flags_finish */
+ }
 };