]> gcc.gnu.org Git - gcc.git/commitdiff
Move array_bounds warnings into a separate pass.
authorAndrew MacLeod <amacleod@redhat.com>
Wed, 5 Jun 2024 19:12:27 +0000 (15:12 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Mon, 10 Jun 2024 20:26:58 +0000 (16:26 -0400)
Array bounds checking is currently tied to VRP.  This causes issues with
using laternate VRP algorithms as well as experimenting with moving
the location of the warnings later.   This moves it to its own pass
and cleans up the vrp_pass object.

* gimple-array-bounds.cc (array_bounds_checker::array_bounds_checker):
Always use current range_query.
(pass_data_array_bounds): New.
(pass_array_bounds): New.
(make_pass_array_bounds): New.
* gimple-array-bounds.h  (array_bounds_checker): Adjust prototype.
* passes.def (pass_array_bounds): New.  Add after VRP1.
* timevar.def (TV_TREE_ARRAY_BOUNDS): New timevar.
* tree-pass.h (make_pass_array_bounds): Add prototype.
* tree-vrp.cc (execute_ranger_vrp): Remove warning param and do
not invoke array bounds warning pass.
(pass_vrp::pass_vrp): Adjust params.
(pass_vrp::close): Adjust parameters.
(pass_vrp::warn_array_bounds_p): Remove.
(make_pass_vrp): Remove warning param.
(make_pass_early_vrp): Remove warning param.
(make_pass_fast_vrp): Remove warning param.

gcc/gimple-array-bounds.cc
gcc/gimple-array-bounds.h
gcc/passes.def
gcc/timevar.def
gcc/tree-pass.h
gcc/tree-vrp.cc

index 2fa3d18d2952ece2f507f4448657b2c2c35d8950..1637a2fc4f490e9636cdd78a04fbd258e7bcef97 100644 (file)
@@ -38,10 +38,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "domwalk.h"
 #include "tree-cfg.h"
 #include "attribs.h"
+#include "tree-pass.h"
+#include "gimple-range.h"
 
-array_bounds_checker::array_bounds_checker (struct function *func,
-                                           range_query *qry)
-  : fun (func), m_ptr_qry (qry)
+// Always use the current range query for the bounds checker.
+array_bounds_checker::array_bounds_checker (struct function *func)
+  : fun (func), m_ptr_qry (get_range_query (func))
 {
   /* No-op.  */
 }
@@ -838,11 +840,7 @@ class check_array_bounds_dom_walker : public dom_walker
 {
 public:
   check_array_bounds_dom_walker (array_bounds_checker *checker)
-    : dom_walker (CDI_DOMINATORS,
-                 /* Discover non-executable edges, preserving EDGE_EXECUTABLE
-                    flags, so that we can merge in information on
-                    non-executable edges from vrp_folder .  */
-                 REACHABLE_BLOCKS_PRESERVING_FLAGS),
+    : dom_walker (CDI_DOMINATORS, REACHABLE_BLOCKS),
     checker (checker) { }
   ~check_array_bounds_dom_walker () {}
 
@@ -888,3 +886,52 @@ array_bounds_checker::check ()
   check_array_bounds_dom_walker w (this);
   w.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
 }
+
+const pass_data pass_data_array_bounds =
+{
+  GIMPLE_PASS, /* type */
+  "bounds", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_TREE_ARRAY_BOUNDS, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  ( 0 ),  /* No TODOs */
+};
+
+class pass_array_bounds : public gimple_opt_pass
+{
+public:
+  pass_array_bounds (gcc::context *ctxt, const pass_data &data_)
+    : gimple_opt_pass (data_, ctxt), data (data_)
+    { }
+
+  /* opt_pass methods: */
+  opt_pass * clone () final override
+    { return new pass_array_bounds (m_ctxt, data); }
+  bool gate (function *) final override
+    {
+      // Gate on the VRP pass to preserve previous behavior.
+      return flag_tree_vrp && (warn_array_bounds || warn_strict_flex_arrays);
+    }
+  unsigned int execute (function *fun) final override
+    {
+      calculate_dominance_info (CDI_DOMINATORS);
+      // Enable ranger as the current range query.
+      enable_ranger (fun, false);
+      array_bounds_checker array_checker (fun);
+      array_checker.check ();
+      disable_ranger (fun);
+      return 0;
+    }
+
+ private:
+  const pass_data &data;
+}; // class pass_array_bounds
+
+gimple_opt_pass *
+make_pass_array_bounds (gcc::context *ctxt)
+{
+  return new pass_array_bounds (ctxt, pass_data_array_bounds);
+}
index 3e077d0178ff36b019c636093e5c1a910441b8fe..aa7ca8e9730fae4329274549ecd28bf621e2a0e0 100644 (file)
@@ -27,7 +27,7 @@ class array_bounds_checker
   friend class check_array_bounds_dom_walker;
 
 public:
-  array_bounds_checker (struct function *, range_query *);
+  array_bounds_checker (struct function *);
   void check ();
 
 private:
index 1cbbd413097083021a96bd0e53d24e539f786114..041229e47a68e66d9eaa16f917b2cb334c0d95e2 100644 (file)
@@ -226,6 +226,7 @@ along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_merge_phi);
       NEXT_PASS (pass_thread_jumps_full, /*first=*/true);
       NEXT_PASS (pass_vrp, false /* final_p*/);
+      NEXT_PASS (pass_array_bounds);
       NEXT_PASS (pass_dse);
       NEXT_PASS (pass_dce);
       /* pass_stdarg is always run and at this point we execute
index 8e2168e08176e8882c50a5267258a39cd5191e76..6fc368591387ffa9d427e12535a152a48ff1dd1a 100644 (file)
@@ -161,6 +161,7 @@ DEFTIMEVAR (TV_TREE_VRP              , "tree VRP")
 DEFTIMEVAR (TV_TREE_VRP_THREADER     , "tree VRP threader")
 DEFTIMEVAR (TV_TREE_EARLY_VRP        , "tree Early VRP")
 DEFTIMEVAR (TV_TREE_FAST_VRP         , "tree Fast VRP")
+DEFTIMEVAR (TV_TREE_ARRAY_BOUNDS     , "warn array bounds")
 DEFTIMEVAR (TV_TREE_COPY_PROP        , "tree copy propagation")
 DEFTIMEVAR (TV_FIND_REFERENCED_VARS  , "tree find ref. vars")
 DEFTIMEVAR (TV_TREE_PTA                     , "tree PTA")
index 29267589eeb38468be431bb90fc348dd4a4bff33..edebb2be245d912119b1e2c07d52994bf10e1201 100644 (file)
@@ -470,6 +470,7 @@ extern gimple_opt_pass *make_pass_fre (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_check_data_deps (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_copy_prop (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_isolate_erroneous_paths (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_array_bounds (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_early_vrp (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_fast_vrp (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_vrp (gcc::context *ctxt);
index 1c7b451d8fb12ef2b0aac35b35ba4674a6764273..1f6b578f2530235c0d2c102a81b6280a816add21 100644 (file)
@@ -1095,8 +1095,7 @@ private:
   from anywhere to perform a VRP pass, including from EVRP.  */
 
 unsigned int
-execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p,
-                   bool final_p)
+execute_ranger_vrp (struct function *fun, bool final_p)
 {
   loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
@@ -1113,27 +1112,6 @@ execute_ranger_vrp (struct function *fun, bool warn_array_bounds_p,
   if (dump_file && (dump_flags & TDF_DETAILS))
     ranger->dump (dump_file);
 
-  if ((warn_array_bounds || warn_strict_flex_arrays) && warn_array_bounds_p)
-    {
-      // Set all edges as executable, except those ranger says aren't.
-      int non_exec_flag = ranger->non_executable_edge_flag;
-      basic_block bb;
-      FOR_ALL_BB_FN (bb, fun)
-       {
-         edge_iterator ei;
-         edge e;
-         FOR_EACH_EDGE (e, ei, bb->succs)
-           if (e->flags & non_exec_flag)
-             e->flags &= ~EDGE_EXECUTABLE;
-           else
-             e->flags |= EDGE_EXECUTABLE;
-       }
-      scev_reset ();
-      array_bounds_checker array_checker (fun, ranger);
-      array_checker.check ();
-    }
-
-
   if (Value_Range::supports_type_p (TREE_TYPE
                                     (TREE_TYPE (current_function_decl)))
       && flag_ipa_vrp
@@ -1330,14 +1308,13 @@ const pass_data pass_data_fast_vrp =
 class pass_vrp : public gimple_opt_pass
 {
 public:
-  pass_vrp (gcc::context *ctxt, const pass_data &data_, bool warn_p)
-    : gimple_opt_pass (data_, ctxt), data (data_),
-      warn_array_bounds_p (warn_p), final_p (false)
+  pass_vrp (gcc::context *ctxt, const pass_data &data_)
+    : gimple_opt_pass (data_, ctxt), data (data_), final_p (false)
     { }
 
   /* opt_pass methods: */
   opt_pass * clone () final override
-    { return new pass_vrp (m_ctxt, data, false); }
+    { return new pass_vrp (m_ctxt, data); }
   void set_pass_param (unsigned int n, bool param) final override
     {
       gcc_assert (n == 0);
@@ -1350,12 +1327,11 @@ public:
       if (&data == &pass_data_fast_vrp)
        return execute_fast_vrp (fun);
 
-      return execute_ranger_vrp (fun, warn_array_bounds_p, final_p);
+      return execute_ranger_vrp (fun, final_p);
     }
 
  private:
   const pass_data &data;
-  bool warn_array_bounds_p;
   bool final_p;
 }; // class pass_vrp
 
@@ -1426,19 +1402,19 @@ public:
 gimple_opt_pass *
 make_pass_vrp (gcc::context *ctxt)
 {
-  return new pass_vrp (ctxt, pass_data_vrp, true);
+  return new pass_vrp (ctxt, pass_data_vrp);
 }
 
 gimple_opt_pass *
 make_pass_early_vrp (gcc::context *ctxt)
 {
-  return new pass_vrp (ctxt, pass_data_early_vrp, false);
+  return new pass_vrp (ctxt, pass_data_early_vrp);
 }
 
 gimple_opt_pass *
 make_pass_fast_vrp (gcc::context *ctxt)
 {
-  return new pass_vrp (ctxt, pass_data_fast_vrp, false);
+  return new pass_vrp (ctxt, pass_data_fast_vrp);
 }
 
 gimple_opt_pass *
This page took 0.071212 seconds and 5 git commands to generate.