OSDN Git Service

gcc/
[pf3gnuchains/gcc-fork.git] / gcc / tree-affine.c
index 8407df2..b67064b 100644 (file)
@@ -1,5 +1,5 @@
 /* Operations with affine combinations of trees.
-   Copyright (C) 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
    
 This file is part of GCC.
    
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dump.h"
 #include "pointer-set.h"
 #include "tree-affine.h"
-#include "tree-gimple.h"
+#include "gimple.h"
 #include "flags.h"
 
 /* Extends CST as appropriate for the affine combinations COMB.  */
@@ -567,11 +567,13 @@ struct name_expansion
    results.  */
 
 void
-aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
+aff_combination_expand (aff_tree *comb ATTRIBUTE_UNUSED,
+                       struct pointer_map_t **cache ATTRIBUTE_UNUSED)
 {
   unsigned i;
   aff_tree to_add, current, curre;
-  tree e, def, rhs;
+  tree e, rhs;
+  gimple def;
   double_int scale;
   void **slot;
   struct name_expansion *exp;
@@ -580,6 +582,8 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
   for (i = 0; i < comb->n; i++)
     {
       tree type, name;
+      enum tree_code code;
+
       e = comb->elts[i].val;
       type = TREE_TYPE (e);
       name = e;
@@ -591,54 +595,52 @@ aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
       if (TREE_CODE (name) != SSA_NAME)
        continue;
       def = SSA_NAME_DEF_STMT (name);
-      if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
-         || GIMPLE_STMT_OPERAND (def, 0) != name)
+      if (!is_gimple_assign (def) || gimple_assign_lhs (def) != name)
        continue;
 
-      rhs = GIMPLE_STMT_OPERAND (def, 1);
-      if (TREE_CODE (rhs) != SSA_NAME
-         && !EXPR_P (rhs)
-         && !is_gimple_min_invariant (rhs))
+      code = gimple_assign_rhs_code (def);
+      if (code != SSA_NAME
+         && !IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+         && (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
+             || !is_gimple_min_invariant (gimple_assign_rhs1 (def))))
        continue;
 
       /* We do not know whether the reference retains its value at the
         place where the expansion is used.  */
-      if (REFERENCE_CLASS_P (rhs))
+      if (TREE_CODE_CLASS (code) == tcc_reference)
        continue;
 
       if (!*cache)
        *cache = pointer_map_create ();
       slot = pointer_map_insert (*cache, e);
-      exp = *slot;
+      exp = (struct name_expansion *) *slot;
 
       if (!exp)
        {
          exp = XNEW (struct name_expansion);
          exp->in_progress = 1;
          *slot = exp;
-         if (e != name)
+         /* In principle this is a generally valid folding, but
+            it is not unconditionally an optimization, so do it
+            here and not in fold_unary.  */
+         /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
+            than the type of X and overflow for the type of X is
+            undefined.  */
+         if (e != name
+             && INTEGRAL_TYPE_P (type)
+             && INTEGRAL_TYPE_P (TREE_TYPE (name))
+             && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (name))
+             && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (name))
+             && (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
+             && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
+           rhs = fold_build2 (code, type,
+                              fold_convert (type, gimple_assign_rhs1 (def)),
+                              fold_convert (type, gimple_assign_rhs2 (def)));
+         else
            {
-             /* In principle this is a generally valid folding, but
-                it is not unconditionally an optimization, so do it
-                here and not in fold_unary.  */
-             /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
-                than the type of X and overflow for the type of X is
-                undefined.  */
-             if (INTEGRAL_TYPE_P (type)
-                 && INTEGRAL_TYPE_P (TREE_TYPE (rhs))
-                 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs))
-                 && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs))
-                 && (TREE_CODE (rhs) == PLUS_EXPR
-                     || TREE_CODE (rhs) == MINUS_EXPR
-                     || TREE_CODE (rhs) == MULT_EXPR)
-                 && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
-               {
-                 rhs = fold_build2 (TREE_CODE (rhs), type,
-                                    fold_convert (type, TREE_OPERAND (rhs, 0)),
-                                    fold_convert (type, TREE_OPERAND (rhs, 1)));
-               }
-             else
-               rhs = fold_convert (type, rhs);
+             rhs = gimple_assign_rhs_to_tree (def);
+             if (e != name)
+               rhs = fold_convert (type, rhs);
            }
          tree_to_aff_combination_expand (rhs, comb->type, &current, cache);
          exp->expansion = current;
@@ -690,7 +692,7 @@ static bool
 free_name_expansion (const void *key ATTRIBUTE_UNUSED, void **value,
                     void *data ATTRIBUTE_UNUSED)
 {
-  struct name_expansion *exp = *value;
+  struct name_expansion *const exp = (struct name_expansion *) *value;
 
   free (exp);
   return true;