Assert that backedges are available in path solver.

gcc/ChangeLog:

	* cfganal.cc (verify_marked_backedges): New.
	* cfganal.h (verify_marked_backedges): New.
	* gimple-range-path.cc (path_range_query::path_range_query):
	Verify freshness of back edges.
	* tree-ssa-loop-ch.cc (ch_base::copy_headers): Call
	mark_dfs_back_edges.
	* tree-ssa-threadbackward.cc (back_threader::back_threader): Move
	path_range_query construction after backedges have been
	updated.
This commit is contained in:
Aldy Hernandez 2022-01-21 13:04:20 +01:00
parent 635504510a
commit 83ad3a96eb
5 changed files with 42 additions and 1 deletions

View File

@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "cfganal.h"
#include "cfgloop.h"
#include "diagnostic.h"
namespace {
/* Store the data structures necessary for depth-first search. */
@ -141,6 +142,40 @@ mark_dfs_back_edges (void)
return mark_dfs_back_edges (cfun);
}
/* Return TRUE if EDGE_DFS_BACK is up to date for CFUN. */
void
verify_marked_backedges (struct function *fun)
{
auto_edge_flag saved_dfs_back (fun);
basic_block bb;
edge e;
edge_iterator ei;
// Save all the back edges...
FOR_EACH_BB_FN (bb, fun)
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (e->flags & EDGE_DFS_BACK)
{
e->flags |= saved_dfs_back;
e->flags &= ~EDGE_DFS_BACK;
}
}
// ...and verify that recalculating them agrees with the saved ones.
mark_dfs_back_edges ();
FOR_EACH_BB_FN (bb, fun)
FOR_EACH_EDGE (e, ei, bb->succs)
{
if (((e->flags & EDGE_DFS_BACK) != 0)
!= ((e->flags & saved_dfs_back) != 0))
internal_error ("%<verify_marked_backedges%> failed");
e->flags &= ~saved_dfs_back;
}
}
/* Find unreachable blocks. An unreachable block will have 0 in
the reachable bit in block->flags. A nonzero value indicates the
block is reachable. */

View File

@ -51,6 +51,7 @@ private:
extern bool mark_dfs_back_edges (struct function *);
extern bool mark_dfs_back_edges (void);
extern void verify_marked_backedges (struct function *);
extern void find_unreachable_blocks (void);
extern void verify_no_unreachable_blocks (void);
struct edge_list * create_edge_list (void);

View File

@ -48,6 +48,9 @@ path_range_query::path_range_query (bool resolve, gimple_ranger *ranger)
m_ranger = ranger;
m_oracle = new path_oracle (m_ranger->oracle ());
if (m_resolve && flag_checking)
verify_marked_backedges (cfun);
}
path_range_query::~path_range_query ()

View File

@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "value-range.h"
#include "gimple-range.h"
#include "gimple-range-path.h"
#include "cfganal.h"
/* Duplicates headers of loops if they are small enough, so that the statements
in the loop body are always executed when the loop is entered. This
@ -384,6 +385,7 @@ ch_base::copy_headers (function *fun)
auto_vec<loop_p> candidates;
auto_vec<std::pair<edge, loop_p> > copied;
mark_dfs_back_edges ();
path_range_query *query = new path_range_query;
for (auto loop : loops_list (cfun, 0))
{

View File

@ -142,12 +142,12 @@ back_threader::back_threader (function *fun, unsigned flags, bool first)
m_fun = fun;
m_flags = flags;
m_solver = new path_range_query (flags & BT_RESOLVE);
m_last_stmt = NULL;
// The path solver needs EDGE_DFS_BACK in resolving mode.
if (flags & BT_RESOLVE)
mark_dfs_back_edges ();
m_solver = new path_range_query (flags & BT_RESOLVE);
}
back_threader::~back_threader ()