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