Assert that backedges are available in path solver.
authorAldy Hernandez <aldyh@redhat.com>
Fri, 21 Jan 2022 12:04:20 +0000 (13:04 +0100)
committerAldy Hernandez <aldyh@redhat.com>
Thu, 3 Feb 2022 13:06:45 +0000 (14:06 +0100)
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.

gcc/cfganal.cc
gcc/cfganal.h
gcc/gimple-range-path.cc
gcc/tree-ssa-loop-ch.cc
gcc/tree-ssa-threadbackward.cc

index 79c627a..d76d47a 100644 (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.  */
index ac637de..bb40239 100644 (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);
index 3ee4989..3bf9bd1 100644 (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 ()
index 8e64863..2f5a390 100644 (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))
     {
index 3ca65b3..3519aca 100644 (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 ()