This avoids regressing gcc.dg/tree-ssa/pr21417.c with the fix for
PR72772 where after it a forwarder block no longer is present.
It's easy to simply create it when FSM threading faces the situation
that the edge ending the path enters a loop.

I also fixed the costs for obviously related anon SSA names (when
they are the same).

Bootstrap and regtest running on x86_64-unknown-linux-gnu, I'll apply
if that finishes successfully.

Richard.

2016-08-05  Richard Biener  <rguent...@suse.de>

        * tree-ssa-threadbackward.c: Include cfghooks.h.
        (profitable_jump_thread_path): Treat same SSA names related.
        (fsm_find_control_statement_thread_paths): When the taken edge
        enters a loop split it instead of giving up.

Index: gcc/tree-ssa-threadbackward.c
===================================================================
--- gcc/tree-ssa-threadbackward.c       (revision 239164)
+++ gcc/tree-ssa-threadbackward.c       (working copy)
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.
 #include "tree-pass.h"
 #include "gimple-ssa.h"
 #include "tree-phinodes.h"
+#include "cfghooks.h"
 
 static int max_threaded_paths;
 
@@ -206,8 +207,9 @@ profitable_jump_thread_path (vec<basic_b
                  /* Note that if both NAME and DST are anonymous
                     SSA_NAMEs, then we do not have enough information
                     to consider them associated.  */
-                 if ((SSA_NAME_VAR (dst) != SSA_NAME_VAR (name)
-                      || !SSA_NAME_VAR (dst))
+                 if (dst != name
+                     && (SSA_NAME_VAR (dst) != SSA_NAME_VAR (name)
+                         || !SSA_NAME_VAR (dst))
                      && !virtual_operand_p (dst))
                    ++n_insns;
                }
@@ -560,9 +562,13 @@ fsm_find_control_statement_thread_paths
          edge taken_edge = profitable_jump_thread_path (path, bbi, name, arg);
          if (taken_edge)
            {
+             /* If the taken edge is a loop entry avoid mashing two
+                loops into one with multiple latches by splitting
+                the edge.  */
              if (bb_loop_depth (taken_edge->src)
-                 >= bb_loop_depth (taken_edge->dest))
-               convert_and_register_jump_thread_path (path, taken_edge);
+                 < bb_loop_depth (taken_edge->dest))
+               split_edge (taken_edge);
+             convert_and_register_jump_thread_path (path, taken_edge);
              path->pop ();
            }
        }
@@ -586,9 +592,13 @@ fsm_find_control_statement_thread_paths
                                                     name, arg);
          if (taken_edge)
            {
+             /* If the taken edge is a loop entry avoid mashing two
+                loops into one with multiple latches by splitting
+                the edge.  */
              if (bb_loop_depth (taken_edge->src)
-                 >= bb_loop_depth (taken_edge->dest))
-               convert_and_register_jump_thread_path (path, taken_edge);
+                 < bb_loop_depth (taken_edge->dest))
+               split_edge (taken_edge);
+             convert_and_register_jump_thread_path (path, taken_edge);
              path->pop ();
            }
 

Reply via email to