When back_jt_path_registry::duplicate_thread_path fails, the
registered path was dropped silently: the dump shows "Registering jump
thread" with no matching outcome.  Every other way a thread dies is
reported -- the profitability FAILs, and the registry's other drops
via cancel_thread.  Report why the copy failed through cancel_thread
like everywhere else.

Tested on ppc64le Linux.

OK?

gcc/ChangeLog:
        PR tree-optimization/126906

        * tree-ssa-threadupdate.h
        (back_jt_path_registry::duplicate_thread_path): Add failure_reason
        argument.
        * tree-ssa-threadupdate.cc
        (back_jt_path_registry::duplicate_thread_path): Set
        *FAILURE_REASON on the two failing exits.
        (back_jt_path_registry::update_cfg): Cancel the path with the
        reason when duplicate_thread_path fails.
---
 gcc/tree-ssa-threadupdate.cc | 24 ++++++++++++++++++------
 gcc/tree-ssa-threadupdate.h  |  3 ++-
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/gcc/tree-ssa-threadupdate.cc b/gcc/tree-ssa-threadupdate.cc
index db3520b42fc..73a995815c0 100644
--- a/gcc/tree-ssa-threadupdate.cc
+++ b/gcc/tree-ssa-threadupdate.cc
@@ -2382,14 +2382,16 @@ back_jt_path_registry::adjust_paths_after_duplication 
(unsigned curr_path_num)
    CURRENT_PATH_NO is an index into the global paths[] table
    specifying the jump-thread path.
 
-   Returns false if it is unable to copy the region, true otherwise.  */
+   Returns false if it is unable to copy the region, true otherwise.
+   On failure *FAILURE_REASON says why.  */
 
 bool
 back_jt_path_registry::duplicate_thread_path (edge entry,
                                              edge exit,
                                              basic_block *region,
                                              unsigned n_region,
-                                             unsigned current_path_no)
+                                             unsigned current_path_no,
+                                             const char **failure_reason)
 {
   unsigned i;
   class loop *loop = entry->dest->loop_father;
@@ -2398,7 +2400,10 @@ back_jt_path_registry::duplicate_thread_path (edge entry,
   profile_count curr_count;
 
   if (!can_copy_bbs_p (region, n_region))
-    return false;
+    {
+      *failure_reason = "Cannot copy the blocks in the path";
+      return false;
+    }
 
   /* Some sanity checking.  Note that we do not check for all possible
      missuses of the functions.  I.e. if you ask to copy something weird,
@@ -2409,7 +2414,10 @@ back_jt_path_registry::duplicate_thread_path (edge entry,
       /* We do not handle subloops, i.e. all the blocks must belong to the
         same loop.  */
       if (region[i]->loop_father != loop)
-       return false;
+       {
+         *failure_reason = "Path crosses loops";
+         return false;
+       }
     }
 
   initialize_original_copy_tables ();
@@ -2638,16 +2646,20 @@ back_jt_path_registry::update_cfg (bool 
/*peel_loop_headers*/)
       for (unsigned int j = 0; j < len - 1; j++)
        region[j] = (*path)[j]->e->dest;
 
-      if (duplicate_thread_path (entry, exit, region, len - 1, 0))
+      const char *failure_reason = NULL;
+      if (duplicate_thread_path (entry, exit, region, len - 1, 0,
+                                &failure_reason))
        {
          /* We do not update dominance info.  */
          free_dominance_info (CDI_DOMINATORS);
          visited_starting_edges.add (entry);
          retval = true;
          m_num_threaded_edges++;
+         path->release ();
        }
+      else
+       cancel_thread (path, failure_reason);
 
-      path->release ();
       m_paths.unordered_remove (0);
       free (region);
     }
diff --git a/gcc/tree-ssa-threadupdate.h b/gcc/tree-ssa-threadupdate.h
index 7faac34fb8f..624bc10a64d 100644
--- a/gcc/tree-ssa-threadupdate.h
+++ b/gcc/tree-ssa-threadupdate.h
@@ -116,7 +116,8 @@ private:
   bool update_cfg (bool peel_loop_headers) override;
   void adjust_paths_after_duplication (unsigned curr_path_num);
   bool duplicate_thread_path (edge entry, edge exit, basic_block *region,
-                             unsigned n_region, unsigned current_path_no);
+                             unsigned n_region, unsigned current_path_no,
+                             const char **failure_reason);
   bool rewire_first_differing_edge (unsigned path_num, unsigned edge_num);
 };
 
-- 
2.47.3

Reply via email to