[PATCH] Remove more backedge threading support
authorJeff Law <law@redhat.com>
Sat, 7 Nov 2015 06:31:14 +0000 (23:31 -0700)
committerJeff Law <law@gcc.gnu.org>
Sat, 7 Nov 2015 06:31:14 +0000 (23:31 -0700)
* tree-ssa-threadedge.c (dummy_simplify): Remove.
(thread_around_empty_blocks): Remove backedge_seen_p argument.
If we thread to a backedge, then return false.  Update recursive
call to eliminate backedge_seen_p argument.
(thread_through_normal_block): Remove backedge_seen_p argument.
Remove backedge_seen_p argument from calls to
thread_around_empty_blocks.  Remove checks on backedge_seen_p.
If we thread to a backedge, then return 0.
(thread_across_edge): Remove bookkeeping for backedge_seen.  Don't
pass it to thread_through_normal_block or thread_through_empty_blocks.
For joiner handling, if we see a backedge, do not try normal
threading.

From-SVN: r229911

gcc/ChangeLog
gcc/tree-ssa-threadedge.c

index 90fbe5f466408d6adc598724be4e51076bef15cc..78dc3f04bdc9ed53daf673505ff2b3937289947b 100644 (file)
@@ -1,3 +1,18 @@
+2015-11-06  Jeff Law <jeff@redhat.com>
+
+       * tree-ssa-threadedge.c (dummy_simplify): Remove.
+       (thread_around_empty_blocks): Remove backedge_seen_p argument.
+       If we thread to a backedge, then return false.  Update recursive
+       call to eliminate backedge_seen_p argument.
+       (thread_through_normal_block): Remove backedge_seen_p argument.
+       Remove backedge_seen_p argument from calls to
+       thread_around_empty_blocks.  Remove checks on backedge_seen_p.
+       If we thread to a backedge, then return 0.
+       (thread_across_edge): Remove bookkeeping for backedge_seen.  Don't
+       pass it to thread_through_normal_block or thread_through_empty_blocks.
+       For joiner handling, if we see a backedge, do not try normal
+       threading.
+
 2015-11-06  Abderrazek Zaafrani  <a.zaafrani@samsung.com>
 
        * graphite-optimize-isl.c (optimize_isl): Call isl_union_map_is_equal.
index 9379198901fa43fab5e979b902a987405cb52d78..971fc528f635fdbb6c089d9a2fbad5799aaa53e1 100644 (file)
@@ -376,17 +376,6 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
   return stmt;
 }
 
-/* Once we have passed a backedge in the CFG when threading, we do not want to
-   utilize edge equivalences for simplification purpose.  They are no longer
-   necessarily valid.  We use this callback rather than the ones provided by
-   DOM/VRP to achieve that effect.  */
-static tree
-dummy_simplify (gimple *stmt1 ATTRIBUTE_UNUSED, gimple *stmt2 ATTRIBUTE_UNUSED,
-               class avail_exprs_stack *avail_exprs_stack ATTRIBUTE_UNUSED)
-{
-  return NULL_TREE;
-}
-
 /* Simplify the control statement at the end of the block E->dest.
 
    To avoid allocating memory unnecessarily, a scratch GIMPLE_COND
@@ -396,7 +385,7 @@ dummy_simplify (gimple *stmt1 ATTRIBUTE_UNUSED, gimple *stmt2 ATTRIBUTE_UNUSED,
    a condition using pass specific information.
 
    Return the simplified condition or NULL if simplification could
-   not be performed. 
+   not be performed.
 
    The available expression table is referenced via AVAIL_EXPRS_STACK.  */
 
@@ -707,7 +696,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
    return false.
 
    DUMMY_COND, HANDLE_DOMINATING_ASSERTS and SIMPLIFY are used to
-   try and simplify the condition at the end of TAKEN_EDGE->dest. 
+   try and simplify the condition at the end of TAKEN_EDGE->dest.
 
    The available expression table is referenced via AVAIL_EXPRS_STACK.  */
 
@@ -718,8 +707,7 @@ thread_around_empty_blocks (edge taken_edge,
                            bool handle_dominating_asserts,
                            pfn_simplify simplify,
                            bitmap visited,
-                           vec<jump_thread_edge *> *path,
-                           bool *backedge_seen_p)
+                           vec<jump_thread_edge *> *path)
 {
   basic_block bb = taken_edge->dest;
   gimple_stmt_iterator gsi;
@@ -754,23 +742,23 @@ thread_around_empty_blocks (edge taken_edge,
       if (single_succ_p (bb))
        {
          taken_edge = single_succ_edge (bb);
+
+         if ((taken_edge->flags & EDGE_DFS_BACK) != 0)
+           return false;
+
          if (!bitmap_bit_p (visited, taken_edge->dest->index))
            {
              jump_thread_edge *x
                = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
              path->safe_push (x);
              bitmap_set_bit (visited, taken_edge->dest->index);
-             *backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
-             if (*backedge_seen_p)
-               simplify = dummy_simplify;
              return thread_around_empty_blocks (taken_edge,
                                                 dummy_cond,
                                                 avail_exprs_stack,
                                                 handle_dominating_asserts,
                                                 simplify,
                                                 visited,
-                                                path,
-                                                backedge_seen_p);
+                                                path);
            }
        }
 
@@ -786,13 +774,6 @@ thread_around_empty_blocks (edge taken_edge,
       && gimple_code (stmt) != GIMPLE_SWITCH)
     return false;
 
-  /* If we have traversed a backedge, then we do not want to look
-     at certain expressions in the table that can not be relied upon.
-     Luckily the only code that looked at those expressions is the
-     SIMPLIFY callback, which we replace if we can no longer use it.  */
-  if (*backedge_seen_p)
-    simplify = dummy_simplify;
-
   /* Extract and simplify the condition.  */
   cond = simplify_control_stmt_condition (taken_edge, stmt,
                                          avail_exprs_stack, dummy_cond,
@@ -805,6 +786,9 @@ thread_around_empty_blocks (edge taken_edge,
     {
       taken_edge = find_taken_edge (bb, cond);
 
+      if ((taken_edge->flags & EDGE_DFS_BACK) != 0)
+       return false;
+
       if (bitmap_bit_p (visited, taken_edge->dest->index))
        return false;
       bitmap_set_bit (visited, taken_edge->dest->index);
@@ -812,9 +796,6 @@ thread_around_empty_blocks (edge taken_edge,
       jump_thread_edge *x
        = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK);
       path->safe_push (x);
-      *backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
-      if (*backedge_seen_p)
-       simplify = dummy_simplify;
 
       thread_around_empty_blocks (taken_edge,
                                  dummy_cond,
@@ -822,8 +803,7 @@ thread_around_empty_blocks (edge taken_edge,
                                  handle_dominating_asserts,
                                  simplify,
                                  visited,
-                                 path,
-                                 backedge_seen_p);
+                                 path);
       return true;
     }
 
@@ -871,14 +851,8 @@ thread_through_normal_block (edge e,
                             avail_exprs_stack *avail_exprs_stack,
                             pfn_simplify simplify,
                             vec<jump_thread_edge *> *path,
-                            bitmap visited,
-                            bool *backedge_seen_p)
+                            bitmap visited)
 {
-  /* If we have seen a backedge, then we rely solely on the FSM threader
-     to find jump threads.  */
-  if (*backedge_seen_p)
-    return 0;
-
   /* We want to record any equivalences created by traversing E.  */
   if (!handle_dominating_asserts)
     record_temporary_equivalences (e, const_and_copies, avail_exprs_stack);
@@ -948,6 +922,7 @@ thread_through_normal_block (edge e,
             address.  */
          if (dest == NULL
              || dest == e->dest
+             || (taken_edge->flags & EDGE_DFS_BACK) != 0
              || bitmap_bit_p (visited, dest->index))
            return 0;
 
@@ -958,15 +933,11 @@ thread_through_normal_block (edge e,
               jump_thread_edge *x
                = new jump_thread_edge (e, EDGE_START_JUMP_THREAD);
              path->safe_push (x);
-             *backedge_seen_p |= ((e->flags & EDGE_DFS_BACK) != 0);
            }
 
          jump_thread_edge *x
            = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_BLOCK);
          path->safe_push (x);
-         *backedge_seen_p |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
-         if (*backedge_seen_p)
-           simplify = dummy_simplify;
 
          /* See if we can thread through DEST as well, this helps capture
             secondary effects of threading without having to re-run DOM or
@@ -982,8 +953,7 @@ thread_through_normal_block (edge e,
                                      handle_dominating_asserts,
                                      simplify,
                                      visited,
-                                     path,
-                                     backedge_seen_p);
+                                     path);
          return 1;
        }
     }
@@ -993,18 +963,6 @@ thread_through_normal_block (edge e,
 /* We are exiting E->src, see if E->dest ends with a conditional
    jump which has a known value when reached via E.
 
-   Special care is necessary if E is a back edge in the CFG as we
-   may have already recorded equivalences for E->dest into our
-   various tables, including the result of the conditional at
-   the end of E->dest.  Threading opportunities are severely
-   limited in that case to avoid short-circuiting the loop
-   incorrectly.
-
-   Note it is quite common for the first block inside a loop to
-   end with a conditional which is either always true or always
-   false when reached via the loop backedge.  Thus we do not want
-   to blindly disable threading across a loop backedge.
-
    DUMMY_COND is a shared cond_expr used by condition simplification as scratch,
    to avoid allocating memory.
 
@@ -1029,7 +987,6 @@ thread_across_edge (gcond *dummy_cond,
                                      class avail_exprs_stack *))
 {
   bitmap visited = BITMAP_ALLOC (NULL);
-  bool backedge_seen;
 
   stmt_count = 0;
 
@@ -1037,16 +994,18 @@ thread_across_edge (gcond *dummy_cond,
   bitmap_clear (visited);
   bitmap_set_bit (visited, e->src->index);
   bitmap_set_bit (visited, e->dest->index);
-  backedge_seen = ((e->flags & EDGE_DFS_BACK) != 0);
-  if (backedge_seen)
-    simplify = dummy_simplify;
-
-  int threaded = thread_through_normal_block (e, dummy_cond,
-                                             handle_dominating_asserts,
-                                             const_and_copies,
-                                             avail_exprs_stack,
-                                             simplify, path,
-                                             visited, &backedge_seen);
+
+  int threaded;
+  if ((e->flags & EDGE_DFS_BACK) == 0)
+    threaded = thread_through_normal_block (e, dummy_cond,
+                                           handle_dominating_asserts,
+                                           const_and_copies,
+                                           avail_exprs_stack,
+                                           simplify, path,
+                                           visited);
+  else
+    threaded = 0;
+
   if (threaded > 0)
     {
       propagate_threaded_block_debug_into (path->last ()->e->dest,
@@ -1111,6 +1070,13 @@ thread_across_edge (gcond *dummy_cond,
     /* Look at each successor of E->dest to see if we can thread through it.  */
     FOR_EACH_EDGE (taken_edge, ei, e->dest->succs)
       {
+       if ((e->flags & EDGE_DFS_BACK) != 0
+           || (taken_edge->flags & EDGE_DFS_BACK) != 0)
+         {
+           find_jump_threads_backwards (taken_edge);
+           continue;
+         }
+
        /* Push a fresh marker so we can unwind the equivalences created
           for each of E->dest's successors.  */
        const_and_copies->push_marker ();
@@ -1132,21 +1098,13 @@ thread_across_edge (gcond *dummy_cond,
         x = new jump_thread_edge (taken_edge, EDGE_COPY_SRC_JOINER_BLOCK);
        path->safe_push (x);
        found = false;
-       backedge_seen = ((e->flags & EDGE_DFS_BACK) != 0);
-       backedge_seen |= ((taken_edge->flags & EDGE_DFS_BACK) != 0);
-       if (backedge_seen)
-         simplify = dummy_simplify;
        found = thread_around_empty_blocks (taken_edge,
                                            dummy_cond,
                                            avail_exprs_stack,
                                            handle_dominating_asserts,
                                            simplify,
                                            visited,
-                                           path,
-                                           &backedge_seen);
-
-       if (backedge_seen)
-         simplify = dummy_simplify;
+                                           path);
 
        if (!found)
          found = thread_through_normal_block (path->last ()->e, dummy_cond,
@@ -1154,7 +1112,7 @@ thread_across_edge (gcond *dummy_cond,
                                               const_and_copies,
                                               avail_exprs_stack,
                                               simplify, path,
-                                              visited, &backedge_seen) > 0;
+                                              visited) > 0;
 
        /* If we were able to thread through a successor of E->dest, then
           record the jump threading opportunity.  */