]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/78496 (Missed opportunities for jump threading)
authorJeff Law <law@redhat.com>
Wed, 3 May 2017 16:33:45 +0000 (10:33 -0600)
committerJeff Law <law@gcc.gnu.org>
Wed, 3 May 2017 16:33:45 +0000 (10:33 -0600)
PR tree-optimization/78496
* tree-vrp.c (simplify_cond_using_ranges_1): Renamed
from simplify_cond_using_ranges.  Split off code to walk
backwards through casts into ...
(simplify_cond_using_ranges_2): New function.
(simplify_stmt_using_ranges): Call simplify_cond_using_ranges_1.
(execute_vrp): After identifying jump threads, call
simplify_cond_using_ranges_2.

PR tree-optimization/78496
* gcc.dg/tree-ssa/ssa-thread-15.c: New test.

From-SVN: r247556

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-15.c [new file with mode: 0644]
gcc/tree-vrp.c

index 5cb7dee02542f1f4989987566b4e697a6762258d..456419014b3bcf4bd469b52093325c7b8ce0f68b 100644 (file)
@@ -1,3 +1,14 @@
+2017-05-03  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/78496
+       * tree-vrp.c (simplify_cond_using_ranges_1): Renamed
+       from simplify_cond_using_ranges.  Split off code to walk
+       backwards through casts into ...
+       (simplify_cond_using_ranges_2): New function.
+       (simplify_stmt_using_ranges): Call simplify_cond_using_ranges_1.
+       (execute_vrp): After identifying jump threads, call
+       simplify_cond_using_ranges_2.
+
 2017-05-03  Jan Hubicka  <hubicka@ucw.cz>
 
        PR bootstrap/80609
index 596468d33e928c35fe6f5ff5b7034bc85fe302ee..55a44e4635a11957266bef38be63374b6ebc817d 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-03  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/78496
+       * gcc.dg/tree-ssa/ssa-thread-15.c: New test.
+
 2017-05-03  Uros Bizjak  <ubizjak@gmail.com>
 
        * g++.dg/lto/pr79671_0.C (foo): Fix asm constraints.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-15.c
new file mode 100644 (file)
index 0000000..f73268c
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do compile } */ 
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+/* We should thread the if (!in_loop) completely leaving
+   just two conditionals.  */
+/* { dg-final { scan-tree-dump-times "if \\(" 2 "vrp1" } } */
+
+
+union tree_node;
+typedef union tree_node *tree;
+
+enum size_type_kind
+{
+  SIZETYPE,
+  SSIZETYPE,
+  BITSIZETYPE,
+  SBITSIZETYPE,
+  TYPE_KIND_LAST
+};
+extern tree size_int_kind (long, enum size_type_kind);
+
+
+
+typedef struct
+{
+
+  tree base, step;
+
+} affine_iv;
+
+struct loop
+{
+
+  int num;
+};
+extern unsigned char simple_iv ();
+
+unsigned char
+dr_analyze_innermost (struct loop *loop, tree poffset)
+{
+  affine_iv offset_iv;
+  unsigned char in_loop = (loop && loop->num);
+
+
+  if (in_loop)
+    simple_iv ();
+
+  if (!in_loop)
+    offset_iv.step = size_int_kind (0, SSIZETYPE);
+
+}
index df5e42674917125e4895c241e4bc65ad8f025af1..6a4035dc9247bff74b6c2fb906bfecb29225d8c9 100644 (file)
@@ -9977,7 +9977,7 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
    the original conditional.  */
 
 static bool
-simplify_cond_using_ranges (gcond *stmt)
+simplify_cond_using_ranges_1 (gcond *stmt)
 {
   tree op0 = gimple_cond_lhs (stmt);
   tree op1 = gimple_cond_rhs (stmt);
@@ -10080,6 +10080,22 @@ simplify_cond_using_ranges (gcond *stmt)
            }
        }
     }
+  return false;
+}
+
+/* STMT is a conditional at the end of a basic block.
+
+   If the conditional is of the form SSA_NAME op constant and the SSA_NAME
+   was set via a type conversion, try to replace the SSA_NAME with the RHS
+   of the type conversion.  Doing so makes the conversion dead which helps
+   subsequent passes.  */
+
+static void
+simplify_cond_using_ranges_2 (gcond *stmt)
+{
+  tree op0 = gimple_cond_lhs (stmt);
+  tree op1 = gimple_cond_rhs (stmt);
+  enum tree_code cond_code = gimple_cond_code (stmt);
 
   /* If we have a comparison of an SSA_NAME (OP0) against a constant,
      see if OP0 was set by a type conversion where the source of
@@ -10097,7 +10113,7 @@ simplify_cond_using_ranges (gcond *stmt)
 
       if (!is_gimple_assign (def_stmt)
          || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
-       return false;
+       return;
 
       innerop = gimple_assign_rhs1 (def_stmt);
 
@@ -10142,12 +10158,16 @@ simplify_cond_using_ranges (gcond *stmt)
              tree newconst = fold_convert (TREE_TYPE (innerop), op1);
              gimple_cond_set_lhs (stmt, innerop);
              gimple_cond_set_rhs (stmt, newconst);
-             return true;
+             update_stmt (stmt);
+             if (dump_file && (dump_flags & TDF_DETAILS))
+               {
+                 fprintf (dump_file, "Folded into: ");
+                 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+                 fprintf (dump_file, "\n");
+               }
            }
        }
     }
-
-  return false;
 }
 
 /* Simplify a switch statement using the value range of the switch
@@ -10746,7 +10766,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
        }
     }
   else if (gimple_code (stmt) == GIMPLE_COND)
-    return simplify_cond_using_ranges (as_a <gcond *> (stmt));
+    return simplify_cond_using_ranges_1 (as_a <gcond *> (stmt));
   else if (gimple_code (stmt) == GIMPLE_SWITCH)
     return simplify_switch_using_ranges (as_a <gswitch *> (stmt));
   else if (is_gimple_call (stmt)
@@ -11759,6 +11779,21 @@ execute_vrp (bool warn_array_bounds_p)
      the datastructures built by VRP.  */
   identify_jump_threads ();
 
+  /* A comparison of an SSA_NAME against a constant where the SSA_NAME
+     was set by a type conversion can often be rewritten to use the
+     RHS of the type conversion.
+
+     However, doing so inhibits jump threading through the comparison.
+     So that transformation is not performed until after jump threading
+     is complete.  */
+  basic_block bb;
+  FOR_EACH_BB_FN (bb, cfun)
+    {
+      gimple *last = last_stmt (bb);
+      if (last && gimple_code (last) == GIMPLE_COND)
+       simplify_cond_using_ranges_2 (as_a <gcond *> (last));
+    }
+
   vrp_free_lattice ();
 
   free_numbers_of_iterations_estimates (cfun);