From 454e3ba345c2263563562b489bdb81fcc8e71105 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Sun, 16 Aug 2026 18:50:54 +0000 Subject: [PATCH] Report failed block copies in the backward threader [PR126906] When back_jt_path_registry::duplicate_thread_path fails, the registered path is 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. 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 91c2c1788ef..54d2c419423 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, @@ -2416,7 +2421,10 @@ back_jt_path_registry::duplicate_thread_path (edge entry, || (loop->header == entry->dest && region[i] != exit->src && EDGE_COUNT (region[i]->succs) > 1)) - return false; + { + *failure_reason = "Path crosses loops"; + return false; + } } initialize_original_copy_tables (); @@ -2645,16 +2653,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