re PR tree-optimization/71437 (Performance regression after r235817)
authorJeff Law <law@redhat.com>
Fri, 17 Mar 2017 15:01:56 +0000 (09:01 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 17 Mar 2017 15:01:56 +0000 (09:01 -0600)
PR tree-optimization/71437
* tree-vrp.c (simplify_stmt_for_jump_threading): Lookup the
conditional in the hash table first.
(vrp_dom_walker::before_dom_children): Extract condition from
ASSERT_EXPR.  Record condition, its inverion and any implied
conditions as well.

PR tree-optimization/71437
* gcc.dg/tree-ssa/pr71437.c: New test.
* gcc.dg/tree-ssa/20040305-1.c: Test earlier dump.
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Adjust for jump threads
now caught by VRP, but which were previously caught by DOM.

From-SVN: r246225

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c
gcc/testsuite/gcc.dg/tree-ssa/pr71437.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
gcc/tree-vrp.c

index cced3ce..71bebcf 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-17  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/71437
+       * tree-vrp.c (simplify_stmt_for_jump_threading): Lookup the
+       conditional in the hash table first.
+       (vrp_dom_walker::before_dom_children): Extract condition from
+       ASSERT_EXPR.  Record condition, its inverion and any implied
+       conditions as well.
+
 2017-03-17  Marek Polacek  <polacek@redhat.com>
            Markus Trippelsdorf  <markus@trippelsdorf.de>
 
index 144030e..ab4a49d 100644 (file)
@@ -1,3 +1,11 @@
+2017-03-17  Jeff Law  <law@redhat.com>
+
+       PR tree-optimization/71437
+       * gcc.dg/tree-ssa/pr71437.c: New test.
+       * gcc.dg/tree-ssa/20040305-1.c: Test earlier dump.
+       * gcc.dg/tree-ssa/ssa-dom-thread-4.c: Adjust for jump threads
+       now caught by VRP, but which were previously caught by DOM.
+
 2017-03-17  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/80075
index c173e5e..1093529 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-cddce3 -fdump-tree-forwprop1-details" } */
+/* { dg-options "-O2 -fdump-tree-dce2 -fdump-tree-forwprop1-details" } */
   
 int abarney[2];
 int afred[1];
@@ -25,6 +25,6 @@ void foo(int edx, int eax)
 /* Verify that we did a forward propagation.  */
 /* { dg-final { scan-tree-dump-times "gimple_simplified" 1 "forwprop1"} } */
 
-/* After cddce we should have two IF statements remaining as the other
+/* After dce we should have two IF statements remaining as the other
    two tests can be threaded.  */
-/* { dg-final { scan-tree-dump-times "if " 2 "cddce3"} } */
+/* { dg-final { scan-tree-dump-times "if " 2 "dce2"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71437.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71437.c
new file mode 100644 (file)
index 0000000..66a5405
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-ffast-math -O3 -fdump-tree-vrp1-details" } */
+
+int I = 50, J = 50;
+int S, L;
+const int *pL;
+const int *pS;
+
+void bar (float, float);
+
+void foo (int K)
+{
+  int k, i, j;
+  static float LD, SD;
+  for (k = 0 ; k < K; k++)
+    {
+        for( i = 0 ; i < ( I - 1 ) ; i++ )
+        {
+            if( ( L < pL[i+1] ) && ( L >= pL[i] ) )
+              break ;
+        }
+
+        if( i == ( I - 1 ) )
+          L = pL[i] ;
+        LD = (float)( L - pL[i] ) /
+                        (float)( pL[i + 1] - pL[i] ) ;
+
+        for( j = 0 ; j < ( J-1 ) ; j++ )
+        {
+            if( ( S < pS[j+1] ) && ( S >= pS[j] ) )
+              break ;
+        }
+
+        if( j == ( J - 1 ) )
+          S = pS[j] ;
+        SD = (float)( S - pS[j] ) /
+                         (float)( pS[j + 1] - pS[j] ) ;
+
+       bar (LD, SD);
+    }
+}
+/* { dg-final { scan-tree-dump-times "Threaded jump " 2 "vrp1" } } */
index 2dd9177..ed76e81 100644 (file)
@@ -57,8 +57,13 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
    we should thread all three, but due to a bug in the threading
    code we missed the edge when the first conditional is false
    (b_elt is zero, which means the second conditional is always
-   zero.  */
-/* { dg-final { scan-tree-dump-times "Threaded" 3 "dom2" { target { ! logical_op_short_circuit } } } } */
+   zero.  
+
+   The first two are caught by VRP1, the last is caught by DOM
+   along with another jump thread.  */
+/* { dg-final { scan-tree-dump-times "Threaded" 2 "vrp1" { target { ! logical_op_short_circuit } } } } */
+/* { dg-final { scan-tree-dump-times "Threaded" 2 "dom2" { target { ! logical_op_short_circuit } } } } */
+
 /* On targets that define LOGICAL_OP_NON_SHORT_CIRCUIT to 0, we split both
    "a_elt || b_elt" and "b_elt && kill_elt" into two conditions each,
    rather than using "(var1 != 0) op (var2 != 0)".  Also, as on other targets,
@@ -76,7 +81,6 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
         skipping the known-true "b_elt && kill_elt" in the second
         condition.
 
-   The !b_elt cases are picked up by VRP1 as jump threads.  The others
-   are optimized by DOM.  */
-/* { dg-final { scan-tree-dump-times "Threaded" 2 "vrp1" { target logical_op_short_circuit } } } */
+   All the cases are picked up by VRP1 as jump threads.  */
+/* { dg-final { scan-tree-dump-times "Threaded" 4 "vrp1" { target logical_op_short_circuit } } } */
 
index 4a09a57..26652e3 100644 (file)
@@ -10783,6 +10783,11 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
     class avail_exprs_stack *avail_exprs_stack ATTRIBUTE_UNUSED,
     basic_block bb)
 {
+  /* First see if the conditional is in the hash table.  */
+  tree cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, false, true);
+  if (cached_lhs && is_gimple_min_invariant (cached_lhs))
+    return cached_lhs;
+
   if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
     {
       tree op0 = gimple_cond_lhs (cond_stmt);
@@ -10915,10 +10920,19 @@ vrp_dom_walker::before_dom_children (basic_block bb)
       if (gimple_assign_single_p (stmt)
          && TREE_CODE (gimple_assign_rhs1 (stmt)) == ASSERT_EXPR)
        {
-         tree lhs = gimple_assign_lhs (stmt);
          tree rhs1 = gimple_assign_rhs1 (stmt);
+         tree cond = TREE_OPERAND (rhs1, 1);
+         tree inverted = invert_truthvalue (cond);
+         vec<cond_equivalence> p;
+         p.create (3);
+         record_conditions (&p, cond, inverted);
+         for (unsigned int i = 0; i < p.length (); i++)
+           m_avail_exprs_stack->record_cond (&p[i]);
+
+         tree lhs = gimple_assign_lhs (stmt);
          m_const_and_copies->record_const_or_copy (lhs,
                                                    TREE_OPERAND (rhs1, 0));
+         p.release ();
          continue;
        }
       break;