gimple-fold.c (maybe_fold_reference): Open-code relevant constant folding.
authorRichard Guenther <rguenther@suse.de>
Wed, 16 Mar 2011 11:36:30 +0000 (11:36 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 16 Mar 2011 11:36:30 +0000 (11:36 +0000)
2011-03-16  Richard Guenther  <rguenther@suse.de>

* gimple-fold.c (maybe_fold_reference): Open-code relevant
constant folding.  Move MEM_REF canonicalization first.
Rely on fold_const_aggregate_ref for initializer folding.
* tree-ssa-ccp.c (ccp_fold): Handle constant vector extracts.

* gcc.dg/tree-ssa/pr14814.c: Adjust.
* gcc.dg/tree-ssa/ssa-ccp-19.c: Likewise.

From-SVN: r171043

gcc/ChangeLog
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr14814.c
gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-19.c
gcc/tree-ssa-ccp.c

index e5f4c4ed4975e1f9702c1b1603e968bf1874c4df..f42547c88fbb59eb16c75b63de026d3b942e820c 100644 (file)
@@ -1,3 +1,10 @@
+2011-03-16  Richard Guenther  <rguenther@suse.de>
+
+       * gimple-fold.c (maybe_fold_reference): Open-code relevant
+       constant folding.  Move MEM_REF canonicalization first.
+       Rely on fold_const_aggregate_ref for initializer folding.
+       * tree-ssa-ccp.c (ccp_fold): Handle constant vector extracts.
+
 2011-03-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/48136
index abc2273adf8cddbdeddabb1d6c179cda812289b4..158cb05802d629b419673ab3a2133c36fa4e04a8 100644 (file)
@@ -560,23 +560,50 @@ maybe_fold_reference (tree expr, bool is_lhs)
   tree *t = &expr;
   tree result;
 
-  if (!is_lhs
-      && (result = fold_const_aggregate_ref (expr))
-      && is_gimple_min_invariant (result))
-    return result;
+  if ((TREE_CODE (expr) == VIEW_CONVERT_EXPR
+       || TREE_CODE (expr) == REALPART_EXPR
+       || TREE_CODE (expr) == IMAGPART_EXPR)
+      && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
+    return fold_unary_loc (EXPR_LOCATION (expr),
+                          TREE_CODE (expr),
+                          TREE_TYPE (expr),
+                          TREE_OPERAND (expr, 0));
+  else if (TREE_CODE (expr) == BIT_FIELD_REF
+          && CONSTANT_CLASS_P (TREE_OPERAND (expr, 0)))
+    return fold_ternary_loc (EXPR_LOCATION (expr),
+                            TREE_CODE (expr),
+                            TREE_TYPE (expr),
+                            TREE_OPERAND (expr, 0),
+                            TREE_OPERAND (expr, 1),
+                            TREE_OPERAND (expr, 2));
+
+  while (handled_component_p (*t))
+    t = &TREE_OPERAND (*t, 0);
 
-  /* ???  We might want to open-code the relevant remaining cases
-     to avoid using the generic fold.  */
-  if (handled_component_p (*t)
-      && CONSTANT_CLASS_P (TREE_OPERAND (*t, 0)))
+  /* Canonicalize MEM_REFs invariant address operand.  Do this first
+     to avoid feeding non-canonical MEM_REFs elsewhere.  */
+  if (TREE_CODE (*t) == MEM_REF
+      && !is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0)))
     {
-      tree tem = fold (*t);
-      if (tem != *t)
-       return tem;
+      bool volatile_p = TREE_THIS_VOLATILE (*t);
+      tree tem = fold_binary (MEM_REF, TREE_TYPE (*t),
+                             TREE_OPERAND (*t, 0),
+                             TREE_OPERAND (*t, 1));
+      if (tem)
+       {
+         TREE_THIS_VOLATILE (tem) = volatile_p;
+         *t = tem;
+         tem = maybe_fold_reference (expr, is_lhs);
+         if (tem)
+           return tem;
+         return expr;
+       }
     }
 
-  while (handled_component_p (*t))
-    t = &TREE_OPERAND (*t, 0);
+  if (!is_lhs
+      && (result = fold_const_aggregate_ref (expr))
+      && is_gimple_min_invariant (result))
+    return result;
 
   /* Fold back MEM_REFs to reference trees.  */
   if (TREE_CODE (*t) == MEM_REF
@@ -593,7 +620,7 @@ maybe_fold_reference (tree expr, bool is_lhs)
         compatibility.  */
       && types_compatible_p (TREE_TYPE (*t),
                             TREE_TYPE (TREE_OPERAND
-                                         (TREE_OPERAND (*t, 0), 0))))
+                                       (TREE_OPERAND (*t, 0), 0))))
     {
       tree tem;
       *t = TREE_OPERAND (TREE_OPERAND (*t, 0), 0);
@@ -602,24 +629,6 @@ maybe_fold_reference (tree expr, bool is_lhs)
        return tem;
       return expr;
     }
-  /* Canonicalize MEM_REFs invariant address operand.  */
-  else if (TREE_CODE (*t) == MEM_REF
-          && !is_gimple_mem_ref_addr (TREE_OPERAND (*t, 0)))
-    {
-      bool volatile_p = TREE_THIS_VOLATILE (*t);
-      tree tem = fold_binary (MEM_REF, TREE_TYPE (*t),
-                             TREE_OPERAND (*t, 0),
-                             TREE_OPERAND (*t, 1));
-      if (tem)
-       {
-         TREE_THIS_VOLATILE (tem) = volatile_p;
-         *t = tem;
-         tem = maybe_fold_reference (expr, is_lhs);
-         if (tem)
-           return tem;
-         return expr;
-       }
-    }
   else if (TREE_CODE (*t) == TARGET_MEM_REF)
     {
       tree tem = maybe_fold_tmr (*t);
@@ -632,20 +641,6 @@ maybe_fold_reference (tree expr, bool is_lhs)
          return expr;
        }
     }
-  else if (!is_lhs
-          && DECL_P (*t))
-    {
-      tree tem = get_symbol_constant_value (*t);
-      if (tem
-         && useless_type_conversion_p (TREE_TYPE (*t), TREE_TYPE (tem)))
-       {
-         *t = unshare_expr (tem);
-         tem = maybe_fold_reference (expr, is_lhs);
-         if (tem)
-           return tem;
-         return expr;
-       }
-    }
 
   return NULL_TREE;
 }
index 7e952dca4e53f1d0c5ad969be580588cc5c0c7b1..b3d5f8193fd95f6dd0279ca077816793976cfc22 100644 (file)
@@ -1,3 +1,8 @@
+2011-03-16  Richard Guenther  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/pr14814.c: Adjust.
+       * gcc.dg/tree-ssa/ssa-ccp-19.c: Likewise.
+
 2011-03-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/48136
index eb360551561c1b0e1899032ce8310467c2e394af..20608156f3c657a93633d4e2ab6546172742ba21 100644 (file)
@@ -18,5 +18,5 @@ int foo(const struct XX* r) {
   return 1;
 }
 
-/* { dg-final { scan-tree-dump-times "&" 0 "forwprop2" } } */
+/* { dg-final { scan-tree-dump-times "&" 0 "forwprop2" } } */
 /* { dg-final { cleanup-tree-dump "forwprop2" } } */
index ab4182246a35473d0177afd15f31eed8ea263437..c67373f017e615933da93bd09595fc2fd29583e9 100644 (file)
@@ -12,5 +12,5 @@ int g()
   return *i;  /* This should be turned into a.i */
 }
 
-/* { dg-final { scan-tree-dump "= a.i;" "ccp1" } } */
+/* { dg-final { scan-tree-dump "= MEM\\\[\\\(int \\\*\\\)&a\\\];" "ccp1" } } */
 /* { dg-final { cleanup-tree-dump "ccp1" } } */
index 8b8d996f5089c7edc8b8819c686484761ac60f05..4fc4316bb1c57509cf13ed78d0df7c4e76afe366 100644 (file)
@@ -1182,6 +1182,17 @@ ccp_fold (gimple stmt)
                                               TREE_CODE (rhs),
                                               TREE_TYPE (rhs), val);
                    }
+                 else if (TREE_CODE (rhs) == BIT_FIELD_REF
+                          && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
+                   {
+                     tree val = get_constant_value (TREE_OPERAND (rhs, 0));
+                     if (val)
+                       return fold_ternary_loc (EXPR_LOCATION (rhs),
+                                                TREE_CODE (rhs),
+                                                TREE_TYPE (rhs), val,
+                                                TREE_OPERAND (rhs, 1),
+                                                TREE_OPERAND (rhs, 2));
+                   }
                  else if (TREE_CODE (rhs) == MEM_REF
                           && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
                    {