diff --git a/gcc/cfganal.cc b/gcc/cfganal.cc index 79c627a1716..d76d47a5dc3 100644 --- a/gcc/cfganal.cc +++ b/gcc/cfganal.cc @@ -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 ("% 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. */ diff --git a/gcc/cfganal.h b/gcc/cfganal.h index ac637de2b5a..bb402390db1 100644 --- a/gcc/cfganal.h +++ b/gcc/cfganal.h @@ -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); diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index 3ee4989f4b0..3bf9bd1e981 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -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 () diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc index 8e64863cda2..2f5a390404c 100644 --- a/gcc/tree-ssa-loop-ch.cc +++ b/gcc/tree-ssa-loop-ch.cc @@ -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 candidates; auto_vec > copied; + mark_dfs_back_edges (); path_range_query *query = new path_range_query; for (auto loop : loops_list (cfun, 0)) { diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc index 3ca65b32216..3519aca84cd 100644 --- a/gcc/tree-ssa-threadbackward.cc +++ b/gcc/tree-ssa-threadbackward.cc @@ -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 ()