OSDN Git Service

* tree-vect-transform.c (vect_min_worthwhile_factor): Declare.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-copy.c
index e657bdb..11da27a 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"
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "basic-block.h"
 #include "output.h"
-#include "errors.h"
 #include "expr.h"
 #include "function.h"
 #include "diagnostic.h"
@@ -360,9 +359,7 @@ stmt_may_generate_copy (tree stmt)
   /* If we are not doing store copy-prop, statements with loads and/or
      stores will never generate a useful copy.  */
   if (!do_store_copy_prop
-      && (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))
+      && !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
     return false;
 
   /* Otherwise, the only statements that generate useful copies are
@@ -477,24 +474,31 @@ static void
 dump_copy_of (FILE *dump_file, tree var)
 {
   tree val;
+  sbitmap visited;
 
   print_generic_expr (dump_file, var, dump_flags);
 
   if (TREE_CODE (var) != SSA_NAME)
     return;
-
+    
+  visited = sbitmap_alloc (num_ssa_names);
+  sbitmap_zero (visited);
+  SET_BIT (visited, SSA_NAME_VERSION (var));
+  
   fprintf (dump_file, " copy-of chain: ");
 
   val = var;
   print_generic_expr (dump_file, val, 0);
   fprintf (dump_file, " ");
-  while (copy_of[SSA_NAME_VERSION (val)].value
-         && copy_of[SSA_NAME_VERSION (val)].value != val)
+  while (copy_of[SSA_NAME_VERSION (val)].value)
     {
       fprintf (dump_file, "-> ");
       val = copy_of[SSA_NAME_VERSION (val)].value;
       print_generic_expr (dump_file, val, 0);
       fprintf (dump_file, " ");
+      if (TEST_BIT (visited, SSA_NAME_VERSION (val)))
+        break;
+      SET_BIT (visited, SSA_NAME_VERSION (val));
     }
 
   val = get_copy_of_val (var)->value;
@@ -504,6 +508,8 @@ dump_copy_of (FILE *dump_file, tree var)
     fprintf (dump_file, "[COPY]");
   else
     fprintf (dump_file, "[NOT A COPY]");
+  
+  sbitmap_free (visited);
 }
 
 
@@ -596,27 +602,18 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
 {
   enum ssa_prop_result retval;
   tree cond;
-  use_optype uses;
 
   cond = COND_EXPR_COND (stmt);
-  uses = STMT_USE_OPS (stmt);
   retval = SSA_PROP_VARYING;
 
   /* The only conditionals that we may be able to compute statically
-     are predicates involving at least one SSA_NAME.  */
-  if (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison
-      && NUM_USES (uses) >= 1)
+     are predicates involving two SSA_NAMEs.  */
+  if (COMPARISON_CLASS_P (cond)
+      && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
+      && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
     {
-      unsigned i;
-      tree *orig;
-
-      /* Save the original operands.  */
-      orig = xmalloc (sizeof (tree) * NUM_USES (uses));
-      for (i = 0; i < NUM_USES (uses); i++)
-       {
-         orig[i] = USE_OP (uses, i);
-         SET_USE_OP (uses, i, get_last_copy_of (USE_OP (uses, i)));
-       }
+      tree op0 = get_last_copy_of (TREE_OPERAND (cond, 0));
+      tree op1 = get_last_copy_of (TREE_OPERAND (cond, 1));
 
       /* See if we can determine the predicate's value.  */
       if (dump_file && (dump_flags & TDF_DETAILS))
@@ -626,21 +623,20 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
          print_generic_stmt (dump_file, cond, 0);
        }
 
-      /* We can fold COND only and get a useful result only when we
-        have the same SSA_NAME on both sides of a comparison
-        operator.  */
-      if (TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
-         && TREE_OPERAND (cond, 0) == TREE_OPERAND (cond, 1))
+      /* We can fold COND and get a useful result only when we have
+        the same SSA_NAME on both sides of a comparison operator.  */
+      if (op0 == op1)
        {
-         *taken_edge_p = find_taken_edge (bb_for_stmt (stmt), fold (cond));
-         if (*taken_edge_p)
-           retval = SSA_PROP_INTERESTING;
+         tree folded_cond = fold_binary (TREE_CODE (cond), boolean_type_node,
+                                         op0, op1);
+         if (folded_cond)
+           {
+             basic_block bb = bb_for_stmt (stmt);
+             *taken_edge_p = find_taken_edge (bb, folded_cond);
+             if (*taken_edge_p)
+               retval = SSA_PROP_INTERESTING;
+           }
        }
-
-      /* Restore the original operands.  */
-      for (i = 0; i < NUM_USES (uses); i++)
-       SET_USE_OP (uses, i, orig[i]);
-      free (orig);
     }
 
   if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
@@ -899,7 +895,7 @@ fini_copy_prop (void)
        copy_of[i].value = get_last_copy_of (var);
     }
 
-  substitute_and_fold (copy_of);
+  substitute_and_fold (copy_of, false);
 
   free (cached_last_copy_of);
   free (copy_of);