OSDN Git Service

* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Procedure>: Set default
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-math-opts.c
index c0ddc8a..2ca17c7 100644 (file)
@@ -1,18 +1,19 @@
 /* Global, SSA-based optimizations using mathematical identities.
-   Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-   
+   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
+
 This file is part of GCC.
-   
+
 GCC is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
 Free Software Foundation; either version 3, or (at your option) any
 later version.
-   
+
 GCC is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the 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 COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
@@ -312,7 +313,7 @@ insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ,
       recip_def = make_rename_temp (type, "reciptmp");
       new_stmt = gimple_build_assign_with_ops (RDIV_EXPR, recip_def,
                                               build_one_cst (type), def);
-  
+
       if (occ->bb_has_division)
         {
           /* Case 1: insert before an existing division.  */
@@ -418,7 +419,7 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
          count++;
        }
     }
-  
+
   /* Do the expensive part only if we can hope to optimize something.  */
   threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
   if (count >= threshold)
@@ -563,6 +564,7 @@ execute_cse_reciprocals (void)
                  if (fail)
                    continue;
 
+                 gimple_replace_lhs (stmt1, arg1);
                  gimple_call_set_fndecl (stmt1, fndecl);
                  update_stmt (stmt1);
 
@@ -736,7 +738,7 @@ execute_cse_sincos_1 (tree name)
 
        gsi = gsi_for_stmt (use_stmt);
        gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
-       gsi_remove (&gsi, true); 
+       gsi_remove (&gsi, true);
     }
 
   VEC_free(gimple, heap, stmts);
@@ -939,15 +941,18 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
        {
          /* Set up the symbolic number N by setting each byte to a
             value between 1 and the byte size of rhs1.  The highest
-            order byte is set to 1 and the lowest order byte to
-            n.size.  */
+            order byte is set to n->size and the lowest order
+            byte to 1.  */
          n->size = TYPE_PRECISION (TREE_TYPE (rhs1));
          if (n->size % BITS_PER_UNIT != 0)
            return NULL_TREE;
          n->size /= BITS_PER_UNIT;
          n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 :
-                 (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708);
-         n->n >>= (sizeof (HOST_WIDEST_INT) - n->size) * BITS_PER_UNIT;
+                 (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201);
+
+         if (n->size < (int)sizeof (HOST_WIDEST_INT))
+           n->n &= ((unsigned HOST_WIDEST_INT)1 <<
+                    (n->size * BITS_PER_UNIT)) - 1;
 
          source_expr1 = rhs1;
        }
@@ -987,9 +992,9 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
              {
                /* If STMT casts to a smaller type mask out the bits not
                   belonging to the target type.  */
-               n->size = type_size / BITS_PER_UNIT;
                n->n &= ((unsigned HOST_WIDEST_INT)1 << type_size) - 1;
              }
+           n->size = type_size / BITS_PER_UNIT;
          }
          break;
        default:
@@ -1050,11 +1055,11 @@ static tree
 find_bswap (gimple stmt)
 {
 /* The number which the find_bswap result should match in order to
-   have a full byte swap.  The insignificant bytes are masked out
-   before using it.  */
+   have a full byte swap.  The number is shifted to the left according
+   to the size of the symbolic number before using it.  */
   unsigned HOST_WIDEST_INT cmp =
     sizeof (HOST_WIDEST_INT) < 8 ? 0 :
-    (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201;
+    (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708;
 
   struct symbolic_number n;
   tree source_expr;
@@ -1078,7 +1083,7 @@ find_bswap (gimple stmt)
        ((unsigned HOST_WIDEST_INT)1 << (n.size * BITS_PER_UNIT)) - 1;
 
       n.n &= mask;
-      cmp &= mask;
+      cmp >>= (sizeof (HOST_WIDEST_INT) - n.size) * BITS_PER_UNIT;
     }
 
   /* A complete byte swap should make the symbolic number to start
@@ -1110,8 +1115,9 @@ execute_optimize_bswap (void)
               && optab_handler (bswap_optab, SImode)->insn_code !=
               CODE_FOR_nothing);
   bswap64_p = (built_in_decls[BUILT_IN_BSWAP64]
-              && optab_handler (bswap_optab, DImode)->insn_code !=
-              CODE_FOR_nothing);
+              && (optab_handler (bswap_optab, DImode)->insn_code !=
+                  CODE_FOR_nothing
+                  || (bswap32_p && word_mode == SImode)));
 
   if (!bswap32_p && !bswap64_p)
     return 0;