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:
parent
635504510a
commit
83ad3a96eb
5 changed files with 42 additions and 1 deletions
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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 ()
|
||||
|
|
Loading…
Add table
Reference in a new issue