OSDN Git Service

PR tree-optimization/18463
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Sep 2005 07:09:20 +0000 (07:09 +0000)
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Sep 2005 07:09:20 +0000 (07:09 +0000)
* tree-chrec.c (chrec_convert): Return fold_converted chrec if
converting it directly is not possible.
(chrec_convert_aggressive): New function.
* tree-chrec.h (chrec_convert_aggressive): Declare.
* tree-scalar-evolution.c (instantiate_parameters_1, resolve_mixers):
Fold chrec conversions aggressively if asked to.
(instantiate_parameters): Modified because of changes in
instantiate_parameters_1.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@104443 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/tree-chrec.c
gcc/tree-chrec.h
gcc/tree-scalar-evolution.c

index ed36fd4..802e7a6 100644 (file)
@@ -1,3 +1,15 @@
+2005-09-20  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       PR tree-optimization/18463
+       * tree-chrec.c (chrec_convert): Return fold_converted chrec if
+       converting it directly is not possible.
+       (chrec_convert_aggressive): New function.
+       * tree-chrec.h (chrec_convert_aggressive): Declare.
+       * tree-scalar-evolution.c (instantiate_parameters_1, resolve_mixers):
+       Fold chrec conversions aggressively if asked to.
+       (instantiate_parameters): Modified because of changes in
+       instantiate_parameters_1.
+
 2005-09-19  Richard Henderson  <rth@redhat.com>
 
        * config/i386/sse.md (reduc_splus_v4sf): Rename from reduc_plus_v4sf.
index 88b27d8..0bf1d38 100644 (file)
@@ -1164,9 +1164,7 @@ chrec_convert (tree type, tree chrec, tree at_stmt)
              fprintf (dump_file, "\n)\n");
            }
 
-         /* Directly convert to "don't know": no worth dealing with
-            difficult cases.  */
-         return chrec_dont_know;
+         return fold_convert (type, chrec);
        }
 
       return build_polynomial_chrec (CHREC_VARIABLE (chrec),
@@ -1201,6 +1199,35 @@ chrec_convert (tree type, tree chrec, tree at_stmt)
   return res;
 }
 
+/* Convert CHREC to TYPE, without regard to signed overflows.  Returns the new
+   chrec if something else than what chrec_convert would do happens, NULL_TREE
+   otherwise.  */
+
+tree
+chrec_convert_aggressive (tree type, tree chrec)
+{
+  tree inner_type, left, right, lc, rc;
+
+  if (automatically_generated_chrec_p (chrec)
+      || TREE_CODE (chrec) != POLYNOMIAL_CHREC)
+    return NULL_TREE;
+
+  inner_type = TREE_TYPE (chrec);
+  if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
+    return NULL_TREE;
+
+  left = CHREC_LEFT (chrec);
+  right = CHREC_RIGHT (chrec);
+  lc = chrec_convert_aggressive (type, left);
+  if (!lc)
+    lc = chrec_convert (type, left, NULL_TREE);
+  rc = chrec_convert_aggressive (type, right);
+  if (!rc)
+    rc = chrec_convert (type, right, NULL_TREE);
+
+  return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
+}
+
 /* Returns the type of the chrec.  */
 
 tree 
index 6ef1b66..19719a6 100644 (file)
@@ -68,6 +68,7 @@ extern tree chrec_fold_plus (tree, tree, tree);
 extern tree chrec_fold_minus (tree, tree, tree);
 extern tree chrec_fold_multiply (tree, tree, tree);
 extern tree chrec_convert (tree, tree, tree);
+extern tree chrec_convert_aggressive (tree, tree);
 extern tree chrec_type (tree);
 
 /* Operations.  */
index 235edcd..82f814e 100644 (file)
@@ -1955,20 +1955,27 @@ loop_closed_phi_def (tree var)
 }
 
 /* Analyze all the parameters of the chrec that were left under a symbolic form,
-   with respect to LOOP.  CHREC is the chrec to instantiate.  If
-   ALLOW_SUPERLOOP_CHRECS is true, replacing loop invariants with
-   outer loop chrecs is done.  CACHE is the cache of already instantiated
-   values.  */
+   with respect to LOOP.  CHREC is the chrec to instantiate.  CACHE is the cache
+   of already instantiated values.  FLAGS modify the way chrecs are
+   instantiated.  */
 
+/* Values for FLAGS.  */
+enum
+{
+  INSERT_SUPERLOOP_CHRECS = 1,  /* Loop invariants are replaced with chrecs
+                                  in outer loops.  */
+  FOLD_CONVERSIONS = 2         /* The conversions that may wrap in
+                                  signed/pointer type are folded, as long as the
+                                  value of the chrec is preserved.  */
+};
+  
 static tree
-instantiate_parameters_1 (struct loop *loop, tree chrec,
-                         bool allow_superloop_chrecs,
-                         htab_t cache)
+instantiate_parameters_1 (struct loop *loop, tree chrec, int flags, htab_t cache)
 {
   tree res, op0, op1, op2;
   basic_block def_bb;
   struct loop *def_loop;
+
   if (automatically_generated_chrec_p (chrec)
       || is_gimple_min_invariant (chrec))
     return chrec;
@@ -1981,7 +1988,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
       /* A parameter (or loop invariant and we do not want to include
         evolutions in outer loops), nothing to do.  */
       if (!def_bb
-         || (!allow_superloop_chrecs
+         || (!(flags & INSERT_SUPERLOOP_CHRECS)
              && !flow_bb_inside_loop_p (loop, def_bb)))
        return chrec;
 
@@ -2036,8 +2043,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
        }
 
       else if (res != chrec_dont_know)
-       res = instantiate_parameters_1 (loop, res, allow_superloop_chrecs,
-                                       cache);
+       res = instantiate_parameters_1 (loop, res, flags, cache);
 
       bitmap_clear_bit (already_instantiated, SSA_NAME_VERSION (chrec));
 
@@ -2047,12 +2053,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
 
     case POLYNOMIAL_CHREC:
       op0 = instantiate_parameters_1 (loop, CHREC_LEFT (chrec),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
        return chrec_dont_know;
 
       op1 = instantiate_parameters_1 (loop, CHREC_RIGHT (chrec),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op1 == chrec_dont_know)
        return chrec_dont_know;
 
@@ -2063,12 +2069,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
 
     case PLUS_EXPR:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
        return chrec_dont_know;
 
       op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op1 == chrec_dont_know)
        return chrec_dont_know;
 
@@ -2079,12 +2085,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
 
     case MINUS_EXPR:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
        return chrec_dont_know;
 
       op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op1 == chrec_dont_know)
        return chrec_dont_know;
 
@@ -2095,12 +2101,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
 
     case MULT_EXPR:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
        return chrec_dont_know;
 
       op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op1 == chrec_dont_know)
        return chrec_dont_know;
 
@@ -2113,10 +2119,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
         return chrec_dont_know;
 
+      if (flags & FOLD_CONVERSIONS)
+       {
+         tree tmp = chrec_convert_aggressive (TREE_TYPE (chrec), op0);
+         if (tmp)
+           return tmp;
+       }
+
       if (op0 == TREE_OPERAND (chrec, 0))
        return chrec;
 
@@ -2136,17 +2149,17 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
     {
     case 3:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
        return chrec_dont_know;
 
       op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op1 == chrec_dont_know)
        return chrec_dont_know;
 
       op2 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 2),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op2 == chrec_dont_know)
         return chrec_dont_know;
 
@@ -2160,12 +2173,12 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
 
     case 2:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
        return chrec_dont_know;
 
       op1 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 1),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op1 == chrec_dont_know)
         return chrec_dont_know;
 
@@ -2176,7 +2189,7 @@ instantiate_parameters_1 (struct loop *loop, tree chrec,
            
     case 1:
       op0 = instantiate_parameters_1 (loop, TREE_OPERAND (chrec, 0),
-                                     allow_superloop_chrecs, cache);
+                                     flags, cache);
       if (op0 == chrec_dont_know)
         return chrec_dont_know;
       if (op0 == TREE_OPERAND (chrec, 0))
@@ -2214,7 +2227,7 @@ instantiate_parameters (struct loop *loop,
       fprintf (dump_file, ")\n");
     }
  
-  res = instantiate_parameters_1 (loop, chrec, true, cache);
+  res = instantiate_parameters_1 (loop, chrec, INSERT_SUPERLOOP_CHRECS, cache);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -2229,13 +2242,15 @@ instantiate_parameters (struct loop *loop,
 }
 
 /* Similar to instantiate_parameters, but does not introduce the
-   evolutions in outer loops for LOOP invariants in CHREC.  */
+   evolutions in outer loops for LOOP invariants in CHREC, and does not
+   care about causing overflows, as long as they do not affect value
+   of an expression.  */
 
 static tree
 resolve_mixers (struct loop *loop, tree chrec)
 {
   htab_t cache = htab_create (10, hash_scev_info, eq_scev_info, del_scev_info);
-  tree ret = instantiate_parameters_1 (loop, chrec, false, cache);
+  tree ret = instantiate_parameters_1 (loop, chrec, FOLD_CONVERSIONS, cache);
   htab_delete (cache);
   return ret;
 }