Remove legacy EVRP code.

Message ID 20220627190358.126291-1-aldyh@redhat.com
State New
Headers
Series Remove legacy EVRP code. |

Commit Message

Aldy Hernandez June 27, 2022, 7:03 p.m. UTC
  With DOM converted to ranger, there are no longer any uses of the EVRP
engine.  For that matter, we haven't used the legacy mode in quite a
while, so I think it's safe to remove any associated code.

There are some methods in vr_values which should now be private, but I
didn't bother changing them, as most of the vr_values class will be
removed when VRP1 is converted to ranger.

Does anyone have any issues with me pushing this?

gcc/ChangeLog:

	* Makefile.in: Remove gimple-ssa-evrp.o and gimple-ssa-evrp-analyze.o.
	* flag-types.h (enum evrp_mode): Remove.
	* params.opt: Remove --param=evrp-mode.
	* tree-vrp.cc (make_pass_early_vrp): New.
	(pass_vrp::execute): Call early VRP instance.
	* gimple-ssa-evrp-analyze.cc: Removed.
	* gimple-ssa-evrp-analyze.h: Removed.
	* gimple-ssa-evrp.cc: Removed.
---
 gcc/Makefile.in                 |   2 -
 gcc/flag-types.h                |   9 -
 gcc/gimple-ssa-evrp-analyze.cc  | 456 --------------------------------
 gcc/gimple-ssa-evrp-analyze.h   |  58 ----
 gcc/gimple-ssa-evrp.cc          | 395 ---------------------------
 gcc/params.opt                  |  19 --
 gcc/testsuite/g++.dg/pr100774.C |   2 +-
 gcc/testsuite/gcc.dg/pr100781.c |   2 +-
 gcc/tree-vrp.cc                 |  34 ++-
 9 files changed, 31 insertions(+), 946 deletions(-)
 delete mode 100644 gcc/gimple-ssa-evrp-analyze.cc
 delete mode 100644 gcc/gimple-ssa-evrp-analyze.h
 delete mode 100644 gcc/gimple-ssa-evrp.cc
  

Comments

Richard Biener June 28, 2022, 7:37 a.m. UTC | #1
On Mon, Jun 27, 2022 at 9:04 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> With DOM converted to ranger, there are no longer any uses of the EVRP
> engine.  For that matter, we haven't used the legacy mode in quite a
> while, so I think it's safe to remove any associated code.
>
> There are some methods in vr_values which should now be private, but I
> didn't bother changing them, as most of the vr_values class will be
> removed when VRP1 is converted to ranger.
>
> Does anyone have any issues with me pushing this?

Fine with me.

> gcc/ChangeLog:
>
>         * Makefile.in: Remove gimple-ssa-evrp.o and gimple-ssa-evrp-analyze.o.
>         * flag-types.h (enum evrp_mode): Remove.
>         * params.opt: Remove --param=evrp-mode.
>         * tree-vrp.cc (make_pass_early_vrp): New.
>         (pass_vrp::execute): Call early VRP instance.
>         * gimple-ssa-evrp-analyze.cc: Removed.
>         * gimple-ssa-evrp-analyze.h: Removed.
>         * gimple-ssa-evrp.cc: Removed.
> ---
>  gcc/Makefile.in                 |   2 -
>  gcc/flag-types.h                |   9 -
>  gcc/gimple-ssa-evrp-analyze.cc  | 456 --------------------------------
>  gcc/gimple-ssa-evrp-analyze.h   |  58 ----
>  gcc/gimple-ssa-evrp.cc          | 395 ---------------------------
>  gcc/params.opt                  |  19 --
>  gcc/testsuite/g++.dg/pr100774.C |   2 +-
>  gcc/testsuite/gcc.dg/pr100781.c |   2 +-
>  gcc/tree-vrp.cc                 |  34 ++-
>  9 files changed, 31 insertions(+), 946 deletions(-)
>  delete mode 100644 gcc/gimple-ssa-evrp-analyze.cc
>  delete mode 100644 gcc/gimple-ssa-evrp-analyze.h
>  delete mode 100644 gcc/gimple-ssa-evrp.cc
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index b6dcc45a58a..86257a8b84f 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -1413,8 +1413,6 @@ OBJS = \
>         gimple-range-infer.o \
>         gimple-range-trace.o \
>         gimple-ssa-backprop.o \
> -       gimple-ssa-evrp.o \
> -       gimple-ssa-evrp-analyze.o \
>         gimple-ssa-isolate-paths.o \
>         gimple-ssa-nonnull-compare.o \
>         gimple-ssa-split-paths.o \
> diff --git a/gcc/flag-types.h b/gcc/flag-types.h
> index 2c8498169e0..a11f99af887 100644
> --- a/gcc/flag-types.h
> +++ b/gcc/flag-types.h
> @@ -479,15 +479,6 @@ enum threader_debug
>    THREADER_DEBUG_ALL = 1
>  };
>
> -/* EVRP mode.  */
> -enum evrp_mode
> -{
> -  EVRP_MODE_RVRP_ONLY,
> -  EVRP_MODE_EVRP_ONLY,
> -  EVRP_MODE_EVRP_FIRST,
> -  EVRP_MODE_RVRP_FIRST
> -};
> -
>  /* VRP modes.  */
>  enum vrp_mode
>  {
> diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
> deleted file mode 100644
> index 82142db7976..00000000000
> --- a/gcc/gimple-ssa-evrp-analyze.cc
> +++ /dev/null
> @@ -1,456 +0,0 @@
> -/* Support routines for Value Range Propagation (VRP).
> -   Copyright (C) 2005-2022 Free Software Foundation, Inc.
> -
> -This file is part of GCC.
> -
> -GCC is free software; you can redistribute it and/or modify
> -it under the terms of the GNU General Public License as published by
> -the Free Software Foundation; either version 3, or (at your option)
> -any later version.
> -
> -GCC is distributed in the hope that it will be useful,
> -but WITHOUT ANY WARRANTY; without even the implied warranty of
> -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> -GNU General Public License for more details.
> -
> -You should have received a copy of the GNU General Public License
> -along with GCC; see the file COPYING3.  If not see
> -<http://www.gnu.org/licenses/>.  */
> -
> -#include "config.h"
> -#include "system.h"
> -#include "coretypes.h"
> -#include "backend.h"
> -#include "tree.h"
> -#include "gimple.h"
> -#include "tree-pass.h"
> -#include "ssa.h"
> -#include "gimple-pretty-print.h"
> -#include "cfganal.h"
> -#include "gimple-iterator.h"
> -#include "gimple-fold.h"
> -#include "tree-eh.h"
> -#include "tree-cfg.h"
> -#include "tree-ssa-loop-manip.h"
> -#include "tree-ssa-loop.h"
> -#include "cfgloop.h"
> -#include "tree-scalar-evolution.h"
> -#include "tree-ssa-propagate.h"
> -#include "alloc-pool.h"
> -#include "domwalk.h"
> -#include "tree-cfgcleanup.h"
> -#include "vr-values.h"
> -#include "gimple-ssa-evrp-analyze.h"
> -
> -evrp_range_analyzer::evrp_range_analyzer (bool update_global_ranges)
> -  : stack (10), m_update_global_ranges (update_global_ranges)
> -{
> -  edge e;
> -  edge_iterator ei;
> -  basic_block bb;
> -  FOR_EACH_BB_FN (bb, cfun)
> -    {
> -      bb->flags &= ~BB_VISITED;
> -      FOR_EACH_EDGE (e, ei, bb->preds)
> -        e->flags |= EDGE_EXECUTABLE;
> -    }
> -}
> -
> -/* Push an unwinding marker onto the unwinding stack.  */
> -
> -void
> -evrp_range_analyzer::push_marker ()
> -{
> -  stack.safe_push (std::make_pair (NULL_TREE, (value_range_equiv *)NULL));
> -}
> -
> -/* Analyze ranges as we enter basic block BB.  */
> -
> -void
> -evrp_range_analyzer::enter (basic_block bb)
> -{
> -  if (!optimize)
> -    return;
> -  push_marker ();
> -  record_ranges_from_incoming_edge (bb);
> -  record_ranges_from_phis (bb);
> -  bb->flags |= BB_VISITED;
> -}
> -
> -/* Find new range for NAME such that (OP CODE LIMIT) is true.  */
> -value_range_equiv *
> -evrp_range_analyzer::try_find_new_range (tree name,
> -                                        tree op, tree_code code, tree limit)
> -{
> -  value_range_equiv vr;
> -  const value_range_equiv *old_vr = get_value_range (name);
> -
> -  /* Discover VR when condition is true.  */
> -  extract_range_for_var_from_comparison_expr (name, code, op, limit, &vr);
> -  /* If we found any usable VR, set the VR to ssa_name and create a
> -     PUSH old value in the stack with the old VR.  */
> -  if (!vr.undefined_p () && !vr.varying_p ())
> -    {
> -      if (old_vr->equal_p (vr, /*ignore_equivs=*/true))
> -       return NULL;
> -      value_range_equiv *new_vr = allocate_value_range_equiv ();
> -      new_vr->move (&vr);
> -      return new_vr;
> -    }
> -  return NULL;
> -}
> -
> -/* For LHS record VR in the SSA info.  */
> -void
> -evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range_equiv *vr)
> -{
> -  gcc_assert (m_update_global_ranges);
> -
> -  /* Set the SSA with the value range.  */
> -  if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
> -    {
> -      if (!vr->varying_p () && vr->constant_p ())
> -       set_range_info (lhs, *vr);
> -    }
> -  else if (POINTER_TYPE_P (TREE_TYPE (lhs))
> -          && range_includes_zero_p (vr) == 0)
> -    set_ptr_nonnull (lhs);
> -}
> -
> -/* Return true if all uses of NAME are dominated by STMT or feed STMT
> -   via a chain of single immediate uses.  */
> -
> -static bool
> -all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
> -{
> -  use_operand_p use_p, use2_p;
> -  imm_use_iterator iter;
> -  basic_block stmt_bb = gimple_bb (stmt);
> -
> -  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
> -    {
> -      gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
> -      if (use_stmt == stmt
> -         || is_gimple_debug (use_stmt)
> -         || (gimple_bb (use_stmt) != stmt_bb
> -             && dominated_by_p (CDI_DOMINATORS,
> -                                gimple_bb (use_stmt), stmt_bb)))
> -       continue;
> -      while (use_stmt != stmt
> -            && is_gimple_assign (use_stmt)
> -            && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
> -            && single_imm_use (gimple_assign_lhs (use_stmt),
> -                               &use2_p, &use_stmt2))
> -       use_stmt = use_stmt2;
> -      if (use_stmt != stmt)
> -       return false;
> -    }
> -  return true;
> -}
> -
> -void
> -evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
> -{
> -  edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
> -  if (pred_e)
> -    {
> -      gimple *stmt = last_stmt (pred_e->src);
> -      tree op0 = NULL_TREE;
> -
> -      if (stmt
> -         && gimple_code (stmt) == GIMPLE_COND
> -         && (op0 = gimple_cond_lhs (stmt))
> -         && TREE_CODE (op0) == SSA_NAME
> -         && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
> -             || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
> -       {
> -         if (dump_file && (dump_flags & TDF_DETAILS))
> -           {
> -             fprintf (dump_file, "Visiting controlling predicate ");
> -             print_gimple_stmt (dump_file, stmt, 0);
> -           }
> -         /* Entering a new scope.  Try to see if we can find a VR
> -            here.  */
> -         tree op1 = gimple_cond_rhs (stmt);
> -         if (TREE_OVERFLOW_P (op1))
> -           op1 = drop_tree_overflow (op1);
> -         tree_code code = gimple_cond_code (stmt);
> -
> -         auto_vec<assert_info, 8> asserts;
> -         register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
> -         if (TREE_CODE (op1) == SSA_NAME)
> -           register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
> -
> -         auto_vec<std::pair<tree, value_range_equiv *>, 8> vrs;
> -         for (unsigned i = 0; i < asserts.length (); ++i)
> -           {
> -             value_range_equiv *vr
> -               = try_find_new_range (asserts[i].name,
> -                                     asserts[i].expr,
> -                                     asserts[i].comp_code,
> -                                     asserts[i].val);
> -             if (vr)
> -               vrs.safe_push (std::make_pair (asserts[i].name, vr));
> -           }
> -
> -         /* If pred_e is really a fallthru we can record value ranges
> -            in SSA names as well.  */
> -         bool is_fallthru = assert_unreachable_fallthru_edge_p (pred_e);
> -
> -         /* Push updated ranges only after finding all of them to avoid
> -            ordering issues that can lead to worse ranges.  */
> -         for (unsigned i = 0; i < vrs.length (); ++i)
> -           {
> -             /* But make sure we do not weaken ranges like when
> -                getting first [64, +INF] and then ~[0, 0] from
> -                conditions like (s & 0x3cc0) == 0).  */
> -             const value_range_equiv *old_vr
> -               = get_value_range (vrs[i].first);
> -             value_range tem (*old_vr);
> -             tem.legacy_verbose_intersect (vrs[i].second);
> -             if (tem.equal_p (*old_vr))
> -               {
> -                 free_value_range (vrs[i].second);
> -                 continue;
> -               }
> -             push_value_range (vrs[i].first, vrs[i].second);
> -             if (is_fallthru
> -                 && m_update_global_ranges
> -                 && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt)
> -                 /* The condition must post-dominate the definition point.  */
> -                 && (SSA_NAME_IS_DEFAULT_DEF (vrs[i].first)
> -                     || (gimple_bb (SSA_NAME_DEF_STMT (vrs[i].first))
> -                         == pred_e->src)))
> -               {
> -                 set_ssa_range_info (vrs[i].first, vrs[i].second);
> -                 maybe_set_nonzero_bits (pred_e, vrs[i].first);
> -               }
> -           }
> -       }
> -    }
> -}
> -
> -void
> -evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
> -{
> -  /* Visit PHI stmts and discover any new VRs possible.  */
> -  bool has_unvisited_preds = false;
> -  edge_iterator ei;
> -  edge e;
> -  FOR_EACH_EDGE (e, ei, bb->preds)
> -    if (e->flags & EDGE_EXECUTABLE
> -       && !(e->src->flags & BB_VISITED))
> -      {
> -       has_unvisited_preds = true;
> -       break;
> -      }
> -
> -  for (gphi_iterator gpi = gsi_start_phis (bb);
> -       !gsi_end_p (gpi); gsi_next (&gpi))
> -    {
> -      gphi *phi = gpi.phi ();
> -      tree lhs = PHI_RESULT (phi);
> -      if (virtual_operand_p (lhs))
> -       continue;
> -
> -      /* Skips floats and other things we can't represent in a
> -        range.  */
> -      if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
> -       continue;
> -
> -      value_range_equiv vr_result;
> -      bool interesting = stmt_interesting_for_vrp (phi);
> -      if (!has_unvisited_preds && interesting)
> -       extract_range_from_phi_node (phi, &vr_result);
> -      else
> -       {
> -         vr_result.set_varying (TREE_TYPE (lhs));
> -         /* When we have an unvisited executable predecessor we can't
> -            use PHI arg ranges which may be still UNDEFINED but have
> -            to use VARYING for them.  But we can still resort to
> -            SCEV for loop header PHIs.  */
> -         class loop *l;
> -         if (scev_initialized_p ()
> -             && interesting
> -             && (l = loop_containing_stmt (phi))
> -             && l->header == gimple_bb (phi))
> -         adjust_range_with_scev (&vr_result, l, phi, lhs);
> -       }
> -      update_value_range (lhs, &vr_result);
> -
> -      /* Set the SSA with the value range.  */
> -      if (m_update_global_ranges)
> -       set_ssa_range_info (lhs, &vr_result);
> -    }
> -}
> -
> -/* Record ranges from STMT into our VR_VALUES class.  If TEMPORARY is
> -   true, then this is a temporary equivalence and should be recorded
> -   into the unwind table.  Othewise record the equivalence into the
> -   global table.  */
> -
> -void
> -evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
> -{
> -  tree output = NULL_TREE;
> -
> -  if (!optimize)
> -    return;
> -
> -  if (dyn_cast <gcond *> (stmt))
> -    ;
> -  else if (stmt_interesting_for_vrp (stmt))
> -    {
> -      edge taken_edge;
> -      value_range_equiv vr;
> -      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
> -      if (output)
> -       {
> -         /* Set the SSA with the value range.  There are two cases to
> -            consider.  First (the the most common) is we are processing
> -            STMT in a context where its resulting range globally holds
> -            and thus it can be reflected into the global ranges and need
> -            not be unwound as we leave scope.
> -
> -            The second case occurs if we are processing a statement in
> -            a context where the resulting range must not be reflected
> -            into the global tables and must be unwound as we leave
> -            the current context.  This happens in jump threading for
> -            example.  */
> -         if (!temporary)
> -           {
> -             /* Case one.  We can just update the underlying range
> -                information as well as the global information.  */
> -             update_value_range (output, &vr);
> -             if (m_update_global_ranges)
> -               set_ssa_range_info (output, &vr);
> -           }
> -         else
> -           {
> -             /* We're going to need to unwind this range.  We cannot
> -                use VR as that's a stack object.  We have to allocate
> -                a new range and push the old range onto the stack.  We
> -                also have to be very careful about sharing the underlying
> -                bitmaps.  Ugh.  */
> -             value_range_equiv *new_vr = allocate_value_range_equiv ();
> -             new_vr->set (vr.min (), vr.max (), NULL, vr.kind ());
> -             vr.equiv_clear ();
> -             push_value_range (output, new_vr);
> -           }
> -       }
> -      else
> -       set_defs_to_varying (stmt);
> -    }
> -  else
> -    set_defs_to_varying (stmt);
> -
> -  /* See if we can derive a range for any of STMT's operands.  */
> -  tree op;
> -  ssa_op_iter i;
> -  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
> -    {
> -      tree value;
> -      enum tree_code comp_code;
> -
> -      /* If OP is used in such a way that we can infer a value
> -         range for it, and we don't find a previous assertion for
> -         it, create a new assertion location node for OP.  */
> -      if (infer_value_range (stmt, op, &comp_code, &value))
> -       {
> -         /* If we are able to infer a nonzero value range for OP,
> -            then walk backwards through the use-def chain to see if OP
> -            was set via a typecast.
> -            If so, then we can also infer a nonzero value range
> -            for the operand of the NOP_EXPR.  */
> -         if (comp_code == NE_EXPR && integer_zerop (value))
> -           {
> -             tree t = op;
> -             gimple *def_stmt = SSA_NAME_DEF_STMT (t);
> -             while (is_gimple_assign (def_stmt)
> -                    && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
> -                    && TREE_CODE
> -                         (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
> -                    && POINTER_TYPE_P
> -                         (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
> -               {
> -                 t = gimple_assign_rhs1 (def_stmt);
> -                 def_stmt = SSA_NAME_DEF_STMT (t);
> -
> -                 /* Add VR when (T COMP_CODE value) condition is
> -                    true.  */
> -                 value_range_equiv *op_range
> -                   = try_find_new_range (t, t, comp_code, value);
> -                 if (op_range)
> -                   push_value_range (t, op_range);
> -               }
> -           }
> -         /* Add VR when (OP COMP_CODE value) condition is true.  */
> -         value_range_equiv *op_range = try_find_new_range (op, op,
> -                                                           comp_code, value);
> -         if (op_range)
> -           push_value_range (op, op_range);
> -       }
> -    }
> -}
> -
> -/* Unwind recorded ranges to their most recent state.  */
> -
> -void
> -evrp_range_analyzer::pop_to_marker (void)
> -{
> -  gcc_checking_assert (!stack.is_empty ());
> -  while (stack.last ().first != NULL_TREE)
> -    pop_value_range ();
> -  stack.pop ();
> -}
> -
> -/* Restore/pop VRs valid only for BB when we leave BB.  */
> -
> -void
> -evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
> -{
> -  if (!optimize)
> -    return;
> -  pop_to_marker ();
> -}
> -
> -
> -/* Push the Value Range of VAR to the stack and update it with new VR.  */
> -
> -void
> -evrp_range_analyzer::push_value_range (tree var, value_range_equiv *vr)
> -{
> -  if (dump_file && (dump_flags & TDF_DETAILS))
> -    {
> -      fprintf (dump_file, "pushing new range for ");
> -      print_generic_expr (dump_file, var);
> -      fprintf (dump_file, ": ");
> -      dump_value_range (dump_file, vr);
> -      fprintf (dump_file, "\n");
> -    }
> -  value_range_equiv *old_vr = swap_vr_value (var, vr);
> -  stack.safe_push (std::make_pair (var, old_vr));
> -}
> -
> -/* Pop a Value Range from the vrp_stack.  */
> -
> -void
> -evrp_range_analyzer::pop_value_range ()
> -{
> -  std::pair<tree, value_range_equiv *> e = stack.pop ();
> -  tree var = e.first;
> -  value_range_equiv *vr = e.second;
> -  if (dump_file && (dump_flags & TDF_DETAILS))
> -    {
> -      fprintf (dump_file, "popping range for ");
> -      print_generic_expr (dump_file, var);
> -      fprintf (dump_file, ", restoring ");
> -      dump_value_range (dump_file, vr);
> -      fprintf (dump_file, "\n");
> -    }
> -  /* We saved off a lattice entry, now give it back and release
> -     the one we popped.  */
> -  value_range_equiv *popped_vr = swap_vr_value (var, vr);
> -  if (popped_vr)
> -    free_value_range (popped_vr);
> -}
> diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
> deleted file mode 100644
> index 51c32099dc5..00000000000
> --- a/gcc/gimple-ssa-evrp-analyze.h
> +++ /dev/null
> @@ -1,58 +0,0 @@
> -/* Support routines for Value Range Propagation (VRP).
> -   Copyright (C) 2016-2022 Free Software Foundation, Inc.
> -
> -This file is part of GCC.
> -
> -GCC is free software; you can redistribute it and/or modify
> -it under the terms of the GNU General Public License as published by
> -the Free Software Foundation; either version 3, or (at your option)
> -any later version.
> -
> -GCC is distributed in the hope that it will be useful,
> -but WITHOUT ANY WARRANTY; without even the implied warranty of
> -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> -GNU General Public License for more details.
> -
> -You should have received a copy of the GNU General Public License
> -along with GCC; see the file COPYING3.  If not see
> -<http://www.gnu.org/licenses/>.  */
> -
> -#ifndef GCC_GIMPLE_SSA_EVRP_ANALYZE_H
> -#define GCC_GIMPLE_SSA_EVRP_ANALYZE_H
> -
> -class evrp_range_analyzer : public vr_values
> -{
> - public:
> -  evrp_range_analyzer (bool update_global_ranges);
> -  ~evrp_range_analyzer (void)
> -  {
> -    stack.release ();
> -  }
> -
> -  void enter (basic_block);
> -  void push_marker (void);
> -  void pop_to_marker (void);
> -  void leave (basic_block);
> -  void record_ranges_from_stmt (gimple *, bool);
> -
> -  /* Record a new unwindable range.  */
> -  void push_value_range (tree var, value_range_equiv *vr);
> -
> - private:
> -  DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
> -
> -  void pop_value_range ();
> -  value_range_equiv *try_find_new_range (tree, tree op, tree_code code,
> -                                        tree limit);
> -  void record_ranges_from_incoming_edge (basic_block);
> -  void record_ranges_from_phis (basic_block);
> -  void set_ssa_range_info (tree, value_range_equiv *);
> -
> -  /* STACK holds the old VR.  */
> -  auto_vec<std::pair <tree, value_range_equiv *> > stack;
> -
> -  /* True if we are updating global ranges, false otherwise.  */
> -  bool m_update_global_ranges;
> -};
> -
> -#endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
> diff --git a/gcc/gimple-ssa-evrp.cc b/gcc/gimple-ssa-evrp.cc
> deleted file mode 100644
> index 20388ed5431..00000000000
> --- a/gcc/gimple-ssa-evrp.cc
> +++ /dev/null
> @@ -1,395 +0,0 @@
> -/* Support routines for Value Range Propagation (VRP).
> -   Copyright (C) 2005-2022 Free Software Foundation, Inc.
> -
> -This file is part of GCC.
> -
> -GCC is free software; you can redistribute it and/or modify
> -it under the terms of the GNU General Public License as published by
> -the Free Software Foundation; either version 3, or (at your option)
> -any later version.
> -
> -GCC is distributed in the hope that it will be useful,
> -but WITHOUT ANY WARRANTY; without even the implied warranty of
> -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> -GNU General Public License for more details.
> -
> -You should have received a copy of the GNU General Public License
> -along with GCC; see the file COPYING3.  If not see
> -<http://www.gnu.org/licenses/>.  */
> -
> -#include "config.h"
> -#include "system.h"
> -#include "coretypes.h"
> -#include "backend.h"
> -#include "tree.h"
> -#include "gimple.h"
> -#include "tree-pass.h"
> -#include "ssa.h"
> -#include "gimple-pretty-print.h"
> -#include "cfganal.h"
> -#include "gimple-iterator.h"
> -#include "gimple-fold.h"
> -#include "tree-eh.h"
> -#include "tree-cfg.h"
> -#include "tree-ssa-loop-manip.h"
> -#include "tree-ssa-loop.h"
> -#include "cfgloop.h"
> -#include "tree-scalar-evolution.h"
> -#include "tree-ssa-propagate.h"
> -#include "alloc-pool.h"
> -#include "domwalk.h"
> -#include "tree-cfgcleanup.h"
> -#include "vr-values.h"
> -#include "gimple-ssa-evrp-analyze.h"
> -#include "gimple-range.h"
> -#include "fold-const.h"
> -#include "value-pointer-equiv.h"
> -#include "tree-vrp.h"
> -
> -// This is the classic EVRP folder which uses a dominator walk and pushes
> -// ranges into the next block if it is a single predecessor block.
> -
> -class evrp_folder : public substitute_and_fold_engine
> -{
> -public:
> -  evrp_folder () :
> -    substitute_and_fold_engine (),
> -    m_range_analyzer (/*update_global_ranges=*/true),
> -    simplifier (&m_range_analyzer)
> -  { }
> -
> -  ~evrp_folder ()
> -  {
> -    if (dump_file)
> -      {
> -       fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
> -       m_range_analyzer.dump (dump_file);
> -       fprintf (dump_file, "\n");
> -      }
> -  }
> -
> -  tree value_of_expr (tree name, gimple *stmt) override
> -  {
> -    return m_range_analyzer.value_of_expr (name, stmt);
> -  }
> -
> -  void pre_fold_bb (basic_block bb) override
> -  {
> -    if (dump_file && (dump_flags & TDF_DETAILS))
> -      fprintf (dump_file, "evrp visiting BB%d\n", bb->index);
> -    m_range_analyzer.enter (bb);
> -  }
> -
> -  void pre_fold_stmt (gimple *stmt) override
> -  {
> -    if (dump_file && (dump_flags & TDF_DETAILS))
> -      {
> -       fprintf (dump_file, "evrp visiting stmt ");
> -       print_gimple_stmt (dump_file, stmt, 0);
> -      }
> -    m_range_analyzer.record_ranges_from_stmt (stmt, false);
> -  }
> -
> -  bool fold_stmt (gimple_stmt_iterator *gsi) override
> -  {
> -    return simplifier.simplify (gsi);
> -  }
> -
> -  void post_fold_bb (basic_block bb) override
> -  {
> -    m_range_analyzer.leave (bb);
> -  }
> -
> -  void post_new_stmt (gimple *stmt) override
> -  {
> -    m_range_analyzer.set_defs_to_varying (stmt);
> -  }
> -
> -protected:
> -  DISABLE_COPY_AND_ASSIGN (evrp_folder);
> -  evrp_range_analyzer m_range_analyzer;
> -  simplify_using_ranges simplifier;
> -};
> -
> -// In a hybrid folder, start with an EVRP folder, and add the required
> -// fold_stmt bits to either try the ranger first or second.
> -//
> -// The 3 value_* routines will always query both EVRP and the ranger for
> -// a result, and ensure they return the same value.  If either returns a value
> -// when the other doesn't, it is flagged in the listing, and the discoverd
> -// value is returned.
> -//
> -// The simplifier is unable to process 2 different sources, thus we try to
> -// use one engine, and if it fails to simplify, try using the other engine.
> -// It is reported when the first attempt fails and the second succeeds.
> -
> -class hybrid_folder : public evrp_folder
> -{
> -public:
> -  hybrid_folder (bool evrp_first)
> -  {
> -    m_ranger = enable_ranger (cfun);
> -
> -    if (evrp_first)
> -      {
> -       first = &m_range_analyzer;
> -       first_exec_flag = 0;
> -       second = m_ranger;
> -       second_exec_flag = m_ranger->non_executable_edge_flag;
> -      }
> -     else
> -      {
> -       first = m_ranger;
> -       first_exec_flag = m_ranger->non_executable_edge_flag;
> -       second = &m_range_analyzer;
> -       second_exec_flag = 0;
> -      }
> -    m_pta = new pointer_equiv_analyzer (m_ranger);
> -  }
> -
> -  ~hybrid_folder ()
> -  {
> -    if (dump_file && (dump_flags & TDF_DETAILS))
> -      m_ranger->dump (dump_file);
> -
> -    m_ranger->export_global_ranges ();
> -    disable_ranger (cfun);
> -    delete m_pta;
> -  }
> -
> -  bool fold_stmt (gimple_stmt_iterator *gsi) override
> -    {
> -      simplifier.set_range_query (first, first_exec_flag);
> -      if (simplifier.simplify (gsi))
> -       return true;
> -
> -      simplifier.set_range_query (second, second_exec_flag);
> -      if (simplifier.simplify (gsi))
> -       {
> -         if (dump_file)
> -           fprintf (dump_file, "EVRP:hybrid: Second query simplifed stmt\n");
> -         return true;
> -       }
> -      return false;
> -    }
> -
> -  void pre_fold_stmt (gimple *stmt) override
> -  {
> -    evrp_folder::pre_fold_stmt (stmt);
> -    m_pta->visit_stmt (stmt);
> -  }
> -
> -  void pre_fold_bb (basic_block bb) override
> -  {
> -    evrp_folder::pre_fold_bb (bb);
> -    m_pta->enter (bb);
> -  }
> -
> -  void post_fold_bb (basic_block bb) override
> -  {
> -    evrp_folder::post_fold_bb (bb);
> -    m_pta->leave (bb);
> -  }
> -
> -  tree value_of_expr (tree name, gimple *) override;
> -  tree value_on_edge (edge, tree name) override;
> -  tree value_of_stmt (gimple *, tree name) override;
> -
> -private:
> -  DISABLE_COPY_AND_ASSIGN (hybrid_folder);
> -  gimple_ranger *m_ranger;
> -  range_query *first;
> -  int first_exec_flag;
> -  range_query *second;
> -  int second_exec_flag;
> -  pointer_equiv_analyzer *m_pta;
> -  tree choose_value (tree evrp_val, tree ranger_val);
> -};
> -
> -
> -tree
> -hybrid_folder::value_of_expr (tree op, gimple *stmt)
> -{
> -  tree evrp_ret = evrp_folder::value_of_expr (op, stmt);
> -  tree ranger_ret;
> -  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> -    ranger_ret = NULL;
> -  else
> -    {
> -      ranger_ret = m_ranger->value_of_expr (op, stmt);
> -      if (!ranger_ret && supported_pointer_equiv_p (op))
> -       ranger_ret = m_pta->get_equiv (op);
> -    }
> -  return choose_value (evrp_ret, ranger_ret);
> -}
> -
> -tree
> -hybrid_folder::value_on_edge (edge e, tree op)
> -{
> -  // Call evrp::value_of_expr directly.  Otherwise another dual call is made
> -  // via hybrid_folder::value_of_expr, but without an edge.
> -  tree evrp_ret = evrp_folder::value_of_expr (op, NULL);
> -  tree ranger_ret;
> -  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> -    ranger_ret = NULL;
> -  else
> -    {
> -      ranger_ret = m_ranger->value_on_edge (e, op);
> -      if (!ranger_ret && supported_pointer_equiv_p (op))
> -       ranger_ret = m_pta->get_equiv (op);
> -    }
> -  return choose_value (evrp_ret, ranger_ret);
> -}
> -
> -tree
> -hybrid_folder::value_of_stmt (gimple *stmt, tree op)
> -{
> -  // Call evrp::value_of_expr directly.  Otherwise another dual call is made
> -  // via hybrid_folder::value_of_expr, but without a stmt.
> -  tree evrp_ret;
> -  if (op)
> -    evrp_ret = evrp_folder::value_of_expr (op, NULL);
> -  else
> -    evrp_ret = NULL_TREE;
> -
> -  tree ranger_ret;
> -  if (op && TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> -    ranger_ret = NULL;
> -  else
> -    ranger_ret = m_ranger->value_of_stmt (stmt, op);
> -  return choose_value (evrp_ret, ranger_ret);
> -}
> -
> -// Given trees returned by EVRP and Ranger, choose/report the value to use
> -// by the folder.
> -
> -tree
> -hybrid_folder::choose_value (tree evrp_val, tree ranger_val)
> -{
> -  // If both found the same value, just return it.
> -  if (evrp_val && ranger_val && !compare_values (evrp_val, ranger_val))
> -    return evrp_val;
> -
> -  // If neither returned a value, return NULL_TREE.
> -  if (!ranger_val && !evrp_val)
> -    return NULL_TREE;
> -
> -  // Otherwise there is a discrepancy to flag.
> -  if (dump_file)
> -    {
> -      if (evrp_val && ranger_val)
> -       fprintf (dump_file, "EVRP:hybrid: Disagreement\n");
> -      if (evrp_val)
> -       {
> -         fprintf (dump_file, "EVRP:hybrid: EVRP found singleton ");
> -         print_generic_expr (dump_file, evrp_val);
> -         fprintf (dump_file, "\n");
> -       }
> -      if (ranger_val)
> -       {
> -         fprintf (dump_file, "EVRP:hybrid: RVRP found singleton ");
> -         print_generic_expr (dump_file, ranger_val);
> -         fprintf (dump_file, "\n");
> -       }
> -    }
> -
> -  // If one value was found, return it.
> -  if (!evrp_val)
> -    return ranger_val;
> -  if (!ranger_val)
> -    return evrp_val;
> -
> -  // If values are different, return the first calculated value.
> -  if (param_evrp_mode == EVRP_MODE_RVRP_FIRST)
> -    return ranger_val;
> -  return evrp_val;
> -}
> -
> -/* Main entry point for the early vrp pass which is a simplified non-iterative
> -   version of vrp where basic blocks are visited in dominance order.  Value
> -   ranges discovered in early vrp will also be used by ipa-vrp.  */
> -
> -static unsigned int
> -execute_early_vrp ()
> -{
> -  if (param_evrp_mode == EVRP_MODE_RVRP_ONLY)
> -    return execute_ranger_vrp (cfun, false);
> -
> -  /* Ideally this setup code would move into the ctor for the folder
> -     However, this setup can change the number of blocks which
> -     invalidates the internal arrays that are set up by the dominator
> -     walker in substitute_and_fold_engine.  */
> -  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
> -  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
> -  scev_initialize ();
> -  calculate_dominance_info (CDI_DOMINATORS);
> -
> -  // Only the last 2 bits matter for choosing the folder.
> -  switch (param_evrp_mode)
> -    {
> -    case EVRP_MODE_EVRP_ONLY:
> -      {
> -       evrp_folder folder;
> -       folder.substitute_and_fold ();
> -       break;
> -      }
> -    case EVRP_MODE_EVRP_FIRST:
> -      {
> -       hybrid_folder folder (true);
> -       folder.substitute_and_fold ();
> -       break;
> -      }
> -    case EVRP_MODE_RVRP_FIRST:
> -      {
> -       hybrid_folder folder (false);
> -       folder.substitute_and_fold ();
> -       break;
> -      }
> -    default:
> -      gcc_unreachable ();
> -    }
> -
> -  scev_finalize ();
> -  loop_optimizer_finalize ();
> -  return 0;
> -}
> -
> -namespace {
> -
> -const pass_data pass_data_early_vrp =
> -{
> -  GIMPLE_PASS, /* type */
> -  "evrp", /* name */
> -  OPTGROUP_NONE, /* optinfo_flags */
> -  TV_TREE_EARLY_VRP, /* tv_id */
> -  PROP_ssa, /* properties_required */
> -  0, /* properties_provided */
> -  0, /* properties_destroyed */
> -  0, /* todo_flags_start */
> -  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
> -};
> -
> -class pass_early_vrp : public gimple_opt_pass
> -{
> -public:
> -  pass_early_vrp (gcc::context *ctxt)
> -    : gimple_opt_pass (pass_data_early_vrp, ctxt)
> -    {}
> -
> -  /* opt_pass methods: */
> -  opt_pass * clone () { return new pass_early_vrp (m_ctxt); }
> -  virtual bool gate (function *)
> -    {
> -      return flag_tree_vrp != 0;
> -    }
> -  virtual unsigned int execute (function *)
> -    { return execute_early_vrp (); }
> -
> -}; // class pass_vrp
> -} // anon namespace
> -
> -gimple_opt_pass *
> -make_pass_early_vrp (gcc::context *ctxt)
> -{
> -  return new pass_early_vrp (ctxt);
> -}
> diff --git a/gcc/params.opt b/gcc/params.opt
> index bcf1423671a..2f9c9cf27dd 100644
> --- a/gcc/params.opt
> +++ b/gcc/params.opt
> @@ -134,25 +134,6 @@ Maximum number of basic blocks before EVRP uses a sparse cache.
>  Common Joined UInteger Var(param_evrp_switch_limit) Init(50) Optimization Param
>  Maximum number of outgoing edges in a switch before EVRP will not process it.
>
> --param=evrp-mode=
> -Common Joined Var(param_evrp_mode) Enum(evrp_mode) Init(EVRP_MODE_RVRP_ONLY) Param Optimization
> ---param=evrp-mode=[legacy|ranger|legacy-first|ranger-first] Specifies the mode Early VRP should operate in.
> -
> -Enum
> -Name(evrp_mode) Type(enum evrp_mode) UnknownError(unknown evrp mode %qs)
> -
> -EnumValue
> -Enum(evrp_mode) String(legacy) Value(EVRP_MODE_EVRP_ONLY)
> -
> -EnumValue
> -Enum(evrp_mode) String(ranger) Value(EVRP_MODE_RVRP_ONLY)
> -
> -EnumValue
> -Enum(evrp_mode) String(legacy-first) Value(EVRP_MODE_EVRP_FIRST)
> -
> -EnumValue
> -Enum(evrp_mode) String(ranger-first) Value(EVRP_MODE_RVRP_FIRST)
> -
>  -param=fsm-scale-path-blocks=
>  Common Joined UInteger Var(param_fsm_scale_path_blocks) Init(3) IntegerRange(1, 10) Param Optimization
>  Scale factor to apply to the number of blocks in a threading path when comparing to the number of (scaled) statements.
> diff --git a/gcc/testsuite/g++.dg/pr100774.C b/gcc/testsuite/g++.dg/pr100774.C
> index 345fcfa0d01..63320ef73fc 100644
> --- a/gcc/testsuite/g++.dg/pr100774.C
> +++ b/gcc/testsuite/g++.dg/pr100774.C
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -fno-tree-forwprop --param=evrp-mode=ranger -fcompare-debug  " } */
> +/* { dg-options "-O2 -fno-tree-forwprop -fcompare-debug  " } */
>
>  extern void __attribute__((noreturn)) error();
>
> diff --git a/gcc/testsuite/gcc.dg/pr100781.c b/gcc/testsuite/gcc.dg/pr100781.c
> index c0e008a3ba5..96f0a7a6012 100644
> --- a/gcc/testsuite/gcc.dg/pr100781.c
> +++ b/gcc/testsuite/gcc.dg/pr100781.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 --param=evrp-mode=ranger -fcompare-debug  " } */
> +/* { dg-options "-O2 -fcompare-debug  " } */
>
>  struct a {
>    int b;
> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> index 30022dac108..7b4e2917340 100644
> --- a/gcc/tree-vrp.cc
> +++ b/gcc/tree-vrp.cc
> @@ -4388,17 +4388,30 @@ const pass_data pass_data_vrp =
>    ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
>  };
>
> +const pass_data pass_data_early_vrp =
> +{
> +  GIMPLE_PASS, /* type */
> +  "evrp", /* name */
> +  OPTGROUP_NONE, /* optinfo_flags */
> +  TV_TREE_EARLY_VRP, /* tv_id */
> +  PROP_ssa, /* properties_required */
> +  0, /* properties_provided */
> +  0, /* properties_destroyed */
> +  0, /* todo_flags_start */
> +  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
> +};
> +
>  static int vrp_pass_num = 0;
>  class pass_vrp : public gimple_opt_pass
>  {
>  public:
> -  pass_vrp (gcc::context *ctxt)
> -    : gimple_opt_pass (pass_data_vrp, ctxt), warn_array_bounds_p (false),
> -      my_pass (++vrp_pass_num)
> +  pass_vrp (gcc::context *ctxt, const pass_data &data_)
> +    : gimple_opt_pass (data_, ctxt), data (data_), warn_array_bounds_p (false),
> +      my_pass (vrp_pass_num++)
>    {}
>
>    /* opt_pass methods: */
> -  opt_pass * clone () { return new pass_vrp (m_ctxt); }
> +  opt_pass * clone () { return new pass_vrp (m_ctxt, data); }
>    void set_pass_param (unsigned int n, bool param)
>      {
>        gcc_assert (n == 0);
> @@ -4407,6 +4420,10 @@ public:
>    virtual bool gate (function *) { return flag_tree_vrp != 0; }
>    virtual unsigned int execute (function *fun)
>      {
> +      // Early VRP pass.
> +      if (my_pass == 0)
> +       return execute_ranger_vrp (fun, /*warn_array_bounds_p=*/false);
> +
>        if ((my_pass == 1 && param_vrp1_mode == VRP_MODE_RANGER)
>           || (my_pass == 2 && param_vrp2_mode == VRP_MODE_RANGER))
>         return execute_ranger_vrp (fun, warn_array_bounds_p);
> @@ -4414,6 +4431,7 @@ public:
>      }
>
>   private:
> +  const pass_data &data;
>    bool warn_array_bounds_p;
>    int my_pass;
>  }; // class pass_vrp
> @@ -4423,5 +4441,11 @@ public:
>  gimple_opt_pass *
>  make_pass_vrp (gcc::context *ctxt)
>  {
> -  return new pass_vrp (ctxt);
> +  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);
>  }
> --
> 2.36.1
>
  
Aldy Hernandez June 28, 2022, 12:45 p.m. UTC | #2
Since Andrew, Jeff, and Richi have all agreed, I have pushed the patch.

Thanks.
Aldy

On Tue, Jun 28, 2022 at 9:37 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Mon, Jun 27, 2022 at 9:04 PM Aldy Hernandez <aldyh@redhat.com> wrote:
> >
> > With DOM converted to ranger, there are no longer any uses of the EVRP
> > engine.  For that matter, we haven't used the legacy mode in quite a
> > while, so I think it's safe to remove any associated code.
> >
> > There are some methods in vr_values which should now be private, but I
> > didn't bother changing them, as most of the vr_values class will be
> > removed when VRP1 is converted to ranger.
> >
> > Does anyone have any issues with me pushing this?
>
> Fine with me.
>
> > gcc/ChangeLog:
> >
> >         * Makefile.in: Remove gimple-ssa-evrp.o and gimple-ssa-evrp-analyze.o.
> >         * flag-types.h (enum evrp_mode): Remove.
> >         * params.opt: Remove --param=evrp-mode.
> >         * tree-vrp.cc (make_pass_early_vrp): New.
> >         (pass_vrp::execute): Call early VRP instance.
> >         * gimple-ssa-evrp-analyze.cc: Removed.
> >         * gimple-ssa-evrp-analyze.h: Removed.
> >         * gimple-ssa-evrp.cc: Removed.
> > ---
> >  gcc/Makefile.in                 |   2 -
> >  gcc/flag-types.h                |   9 -
> >  gcc/gimple-ssa-evrp-analyze.cc  | 456 --------------------------------
> >  gcc/gimple-ssa-evrp-analyze.h   |  58 ----
> >  gcc/gimple-ssa-evrp.cc          | 395 ---------------------------
> >  gcc/params.opt                  |  19 --
> >  gcc/testsuite/g++.dg/pr100774.C |   2 +-
> >  gcc/testsuite/gcc.dg/pr100781.c |   2 +-
> >  gcc/tree-vrp.cc                 |  34 ++-
> >  9 files changed, 31 insertions(+), 946 deletions(-)
> >  delete mode 100644 gcc/gimple-ssa-evrp-analyze.cc
> >  delete mode 100644 gcc/gimple-ssa-evrp-analyze.h
> >  delete mode 100644 gcc/gimple-ssa-evrp.cc
> >
> > diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> > index b6dcc45a58a..86257a8b84f 100644
> > --- a/gcc/Makefile.in
> > +++ b/gcc/Makefile.in
> > @@ -1413,8 +1413,6 @@ OBJS = \
> >         gimple-range-infer.o \
> >         gimple-range-trace.o \
> >         gimple-ssa-backprop.o \
> > -       gimple-ssa-evrp.o \
> > -       gimple-ssa-evrp-analyze.o \
> >         gimple-ssa-isolate-paths.o \
> >         gimple-ssa-nonnull-compare.o \
> >         gimple-ssa-split-paths.o \
> > diff --git a/gcc/flag-types.h b/gcc/flag-types.h
> > index 2c8498169e0..a11f99af887 100644
> > --- a/gcc/flag-types.h
> > +++ b/gcc/flag-types.h
> > @@ -479,15 +479,6 @@ enum threader_debug
> >    THREADER_DEBUG_ALL = 1
> >  };
> >
> > -/* EVRP mode.  */
> > -enum evrp_mode
> > -{
> > -  EVRP_MODE_RVRP_ONLY,
> > -  EVRP_MODE_EVRP_ONLY,
> > -  EVRP_MODE_EVRP_FIRST,
> > -  EVRP_MODE_RVRP_FIRST
> > -};
> > -
> >  /* VRP modes.  */
> >  enum vrp_mode
> >  {
> > diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
> > deleted file mode 100644
> > index 82142db7976..00000000000
> > --- a/gcc/gimple-ssa-evrp-analyze.cc
> > +++ /dev/null
> > @@ -1,456 +0,0 @@
> > -/* Support routines for Value Range Propagation (VRP).
> > -   Copyright (C) 2005-2022 Free Software Foundation, Inc.
> > -
> > -This file is part of GCC.
> > -
> > -GCC is free software; you can redistribute it and/or modify
> > -it under the terms of the GNU General Public License as published by
> > -the Free Software Foundation; either version 3, or (at your option)
> > -any later version.
> > -
> > -GCC is distributed in the hope that it will be useful,
> > -but WITHOUT ANY WARRANTY; without even the implied warranty of
> > -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > -GNU General Public License for more details.
> > -
> > -You should have received a copy of the GNU General Public License
> > -along with GCC; see the file COPYING3.  If not see
> > -<http://www.gnu.org/licenses/>.  */
> > -
> > -#include "config.h"
> > -#include "system.h"
> > -#include "coretypes.h"
> > -#include "backend.h"
> > -#include "tree.h"
> > -#include "gimple.h"
> > -#include "tree-pass.h"
> > -#include "ssa.h"
> > -#include "gimple-pretty-print.h"
> > -#include "cfganal.h"
> > -#include "gimple-iterator.h"
> > -#include "gimple-fold.h"
> > -#include "tree-eh.h"
> > -#include "tree-cfg.h"
> > -#include "tree-ssa-loop-manip.h"
> > -#include "tree-ssa-loop.h"
> > -#include "cfgloop.h"
> > -#include "tree-scalar-evolution.h"
> > -#include "tree-ssa-propagate.h"
> > -#include "alloc-pool.h"
> > -#include "domwalk.h"
> > -#include "tree-cfgcleanup.h"
> > -#include "vr-values.h"
> > -#include "gimple-ssa-evrp-analyze.h"
> > -
> > -evrp_range_analyzer::evrp_range_analyzer (bool update_global_ranges)
> > -  : stack (10), m_update_global_ranges (update_global_ranges)
> > -{
> > -  edge e;
> > -  edge_iterator ei;
> > -  basic_block bb;
> > -  FOR_EACH_BB_FN (bb, cfun)
> > -    {
> > -      bb->flags &= ~BB_VISITED;
> > -      FOR_EACH_EDGE (e, ei, bb->preds)
> > -        e->flags |= EDGE_EXECUTABLE;
> > -    }
> > -}
> > -
> > -/* Push an unwinding marker onto the unwinding stack.  */
> > -
> > -void
> > -evrp_range_analyzer::push_marker ()
> > -{
> > -  stack.safe_push (std::make_pair (NULL_TREE, (value_range_equiv *)NULL));
> > -}
> > -
> > -/* Analyze ranges as we enter basic block BB.  */
> > -
> > -void
> > -evrp_range_analyzer::enter (basic_block bb)
> > -{
> > -  if (!optimize)
> > -    return;
> > -  push_marker ();
> > -  record_ranges_from_incoming_edge (bb);
> > -  record_ranges_from_phis (bb);
> > -  bb->flags |= BB_VISITED;
> > -}
> > -
> > -/* Find new range for NAME such that (OP CODE LIMIT) is true.  */
> > -value_range_equiv *
> > -evrp_range_analyzer::try_find_new_range (tree name,
> > -                                        tree op, tree_code code, tree limit)
> > -{
> > -  value_range_equiv vr;
> > -  const value_range_equiv *old_vr = get_value_range (name);
> > -
> > -  /* Discover VR when condition is true.  */
> > -  extract_range_for_var_from_comparison_expr (name, code, op, limit, &vr);
> > -  /* If we found any usable VR, set the VR to ssa_name and create a
> > -     PUSH old value in the stack with the old VR.  */
> > -  if (!vr.undefined_p () && !vr.varying_p ())
> > -    {
> > -      if (old_vr->equal_p (vr, /*ignore_equivs=*/true))
> > -       return NULL;
> > -      value_range_equiv *new_vr = allocate_value_range_equiv ();
> > -      new_vr->move (&vr);
> > -      return new_vr;
> > -    }
> > -  return NULL;
> > -}
> > -
> > -/* For LHS record VR in the SSA info.  */
> > -void
> > -evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range_equiv *vr)
> > -{
> > -  gcc_assert (m_update_global_ranges);
> > -
> > -  /* Set the SSA with the value range.  */
> > -  if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
> > -    {
> > -      if (!vr->varying_p () && vr->constant_p ())
> > -       set_range_info (lhs, *vr);
> > -    }
> > -  else if (POINTER_TYPE_P (TREE_TYPE (lhs))
> > -          && range_includes_zero_p (vr) == 0)
> > -    set_ptr_nonnull (lhs);
> > -}
> > -
> > -/* Return true if all uses of NAME are dominated by STMT or feed STMT
> > -   via a chain of single immediate uses.  */
> > -
> > -static bool
> > -all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
> > -{
> > -  use_operand_p use_p, use2_p;
> > -  imm_use_iterator iter;
> > -  basic_block stmt_bb = gimple_bb (stmt);
> > -
> > -  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
> > -    {
> > -      gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
> > -      if (use_stmt == stmt
> > -         || is_gimple_debug (use_stmt)
> > -         || (gimple_bb (use_stmt) != stmt_bb
> > -             && dominated_by_p (CDI_DOMINATORS,
> > -                                gimple_bb (use_stmt), stmt_bb)))
> > -       continue;
> > -      while (use_stmt != stmt
> > -            && is_gimple_assign (use_stmt)
> > -            && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
> > -            && single_imm_use (gimple_assign_lhs (use_stmt),
> > -                               &use2_p, &use_stmt2))
> > -       use_stmt = use_stmt2;
> > -      if (use_stmt != stmt)
> > -       return false;
> > -    }
> > -  return true;
> > -}
> > -
> > -void
> > -evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
> > -{
> > -  edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
> > -  if (pred_e)
> > -    {
> > -      gimple *stmt = last_stmt (pred_e->src);
> > -      tree op0 = NULL_TREE;
> > -
> > -      if (stmt
> > -         && gimple_code (stmt) == GIMPLE_COND
> > -         && (op0 = gimple_cond_lhs (stmt))
> > -         && TREE_CODE (op0) == SSA_NAME
> > -         && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
> > -             || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
> > -       {
> > -         if (dump_file && (dump_flags & TDF_DETAILS))
> > -           {
> > -             fprintf (dump_file, "Visiting controlling predicate ");
> > -             print_gimple_stmt (dump_file, stmt, 0);
> > -           }
> > -         /* Entering a new scope.  Try to see if we can find a VR
> > -            here.  */
> > -         tree op1 = gimple_cond_rhs (stmt);
> > -         if (TREE_OVERFLOW_P (op1))
> > -           op1 = drop_tree_overflow (op1);
> > -         tree_code code = gimple_cond_code (stmt);
> > -
> > -         auto_vec<assert_info, 8> asserts;
> > -         register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
> > -         if (TREE_CODE (op1) == SSA_NAME)
> > -           register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
> > -
> > -         auto_vec<std::pair<tree, value_range_equiv *>, 8> vrs;
> > -         for (unsigned i = 0; i < asserts.length (); ++i)
> > -           {
> > -             value_range_equiv *vr
> > -               = try_find_new_range (asserts[i].name,
> > -                                     asserts[i].expr,
> > -                                     asserts[i].comp_code,
> > -                                     asserts[i].val);
> > -             if (vr)
> > -               vrs.safe_push (std::make_pair (asserts[i].name, vr));
> > -           }
> > -
> > -         /* If pred_e is really a fallthru we can record value ranges
> > -            in SSA names as well.  */
> > -         bool is_fallthru = assert_unreachable_fallthru_edge_p (pred_e);
> > -
> > -         /* Push updated ranges only after finding all of them to avoid
> > -            ordering issues that can lead to worse ranges.  */
> > -         for (unsigned i = 0; i < vrs.length (); ++i)
> > -           {
> > -             /* But make sure we do not weaken ranges like when
> > -                getting first [64, +INF] and then ~[0, 0] from
> > -                conditions like (s & 0x3cc0) == 0).  */
> > -             const value_range_equiv *old_vr
> > -               = get_value_range (vrs[i].first);
> > -             value_range tem (*old_vr);
> > -             tem.legacy_verbose_intersect (vrs[i].second);
> > -             if (tem.equal_p (*old_vr))
> > -               {
> > -                 free_value_range (vrs[i].second);
> > -                 continue;
> > -               }
> > -             push_value_range (vrs[i].first, vrs[i].second);
> > -             if (is_fallthru
> > -                 && m_update_global_ranges
> > -                 && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt)
> > -                 /* The condition must post-dominate the definition point.  */
> > -                 && (SSA_NAME_IS_DEFAULT_DEF (vrs[i].first)
> > -                     || (gimple_bb (SSA_NAME_DEF_STMT (vrs[i].first))
> > -                         == pred_e->src)))
> > -               {
> > -                 set_ssa_range_info (vrs[i].first, vrs[i].second);
> > -                 maybe_set_nonzero_bits (pred_e, vrs[i].first);
> > -               }
> > -           }
> > -       }
> > -    }
> > -}
> > -
> > -void
> > -evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
> > -{
> > -  /* Visit PHI stmts and discover any new VRs possible.  */
> > -  bool has_unvisited_preds = false;
> > -  edge_iterator ei;
> > -  edge e;
> > -  FOR_EACH_EDGE (e, ei, bb->preds)
> > -    if (e->flags & EDGE_EXECUTABLE
> > -       && !(e->src->flags & BB_VISITED))
> > -      {
> > -       has_unvisited_preds = true;
> > -       break;
> > -      }
> > -
> > -  for (gphi_iterator gpi = gsi_start_phis (bb);
> > -       !gsi_end_p (gpi); gsi_next (&gpi))
> > -    {
> > -      gphi *phi = gpi.phi ();
> > -      tree lhs = PHI_RESULT (phi);
> > -      if (virtual_operand_p (lhs))
> > -       continue;
> > -
> > -      /* Skips floats and other things we can't represent in a
> > -        range.  */
> > -      if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
> > -       continue;
> > -
> > -      value_range_equiv vr_result;
> > -      bool interesting = stmt_interesting_for_vrp (phi);
> > -      if (!has_unvisited_preds && interesting)
> > -       extract_range_from_phi_node (phi, &vr_result);
> > -      else
> > -       {
> > -         vr_result.set_varying (TREE_TYPE (lhs));
> > -         /* When we have an unvisited executable predecessor we can't
> > -            use PHI arg ranges which may be still UNDEFINED but have
> > -            to use VARYING for them.  But we can still resort to
> > -            SCEV for loop header PHIs.  */
> > -         class loop *l;
> > -         if (scev_initialized_p ()
> > -             && interesting
> > -             && (l = loop_containing_stmt (phi))
> > -             && l->header == gimple_bb (phi))
> > -         adjust_range_with_scev (&vr_result, l, phi, lhs);
> > -       }
> > -      update_value_range (lhs, &vr_result);
> > -
> > -      /* Set the SSA with the value range.  */
> > -      if (m_update_global_ranges)
> > -       set_ssa_range_info (lhs, &vr_result);
> > -    }
> > -}
> > -
> > -/* Record ranges from STMT into our VR_VALUES class.  If TEMPORARY is
> > -   true, then this is a temporary equivalence and should be recorded
> > -   into the unwind table.  Othewise record the equivalence into the
> > -   global table.  */
> > -
> > -void
> > -evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
> > -{
> > -  tree output = NULL_TREE;
> > -
> > -  if (!optimize)
> > -    return;
> > -
> > -  if (dyn_cast <gcond *> (stmt))
> > -    ;
> > -  else if (stmt_interesting_for_vrp (stmt))
> > -    {
> > -      edge taken_edge;
> > -      value_range_equiv vr;
> > -      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
> > -      if (output)
> > -       {
> > -         /* Set the SSA with the value range.  There are two cases to
> > -            consider.  First (the the most common) is we are processing
> > -            STMT in a context where its resulting range globally holds
> > -            and thus it can be reflected into the global ranges and need
> > -            not be unwound as we leave scope.
> > -
> > -            The second case occurs if we are processing a statement in
> > -            a context where the resulting range must not be reflected
> > -            into the global tables and must be unwound as we leave
> > -            the current context.  This happens in jump threading for
> > -            example.  */
> > -         if (!temporary)
> > -           {
> > -             /* Case one.  We can just update the underlying range
> > -                information as well as the global information.  */
> > -             update_value_range (output, &vr);
> > -             if (m_update_global_ranges)
> > -               set_ssa_range_info (output, &vr);
> > -           }
> > -         else
> > -           {
> > -             /* We're going to need to unwind this range.  We cannot
> > -                use VR as that's a stack object.  We have to allocate
> > -                a new range and push the old range onto the stack.  We
> > -                also have to be very careful about sharing the underlying
> > -                bitmaps.  Ugh.  */
> > -             value_range_equiv *new_vr = allocate_value_range_equiv ();
> > -             new_vr->set (vr.min (), vr.max (), NULL, vr.kind ());
> > -             vr.equiv_clear ();
> > -             push_value_range (output, new_vr);
> > -           }
> > -       }
> > -      else
> > -       set_defs_to_varying (stmt);
> > -    }
> > -  else
> > -    set_defs_to_varying (stmt);
> > -
> > -  /* See if we can derive a range for any of STMT's operands.  */
> > -  tree op;
> > -  ssa_op_iter i;
> > -  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
> > -    {
> > -      tree value;
> > -      enum tree_code comp_code;
> > -
> > -      /* If OP is used in such a way that we can infer a value
> > -         range for it, and we don't find a previous assertion for
> > -         it, create a new assertion location node for OP.  */
> > -      if (infer_value_range (stmt, op, &comp_code, &value))
> > -       {
> > -         /* If we are able to infer a nonzero value range for OP,
> > -            then walk backwards through the use-def chain to see if OP
> > -            was set via a typecast.
> > -            If so, then we can also infer a nonzero value range
> > -            for the operand of the NOP_EXPR.  */
> > -         if (comp_code == NE_EXPR && integer_zerop (value))
> > -           {
> > -             tree t = op;
> > -             gimple *def_stmt = SSA_NAME_DEF_STMT (t);
> > -             while (is_gimple_assign (def_stmt)
> > -                    && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
> > -                    && TREE_CODE
> > -                         (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
> > -                    && POINTER_TYPE_P
> > -                         (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
> > -               {
> > -                 t = gimple_assign_rhs1 (def_stmt);
> > -                 def_stmt = SSA_NAME_DEF_STMT (t);
> > -
> > -                 /* Add VR when (T COMP_CODE value) condition is
> > -                    true.  */
> > -                 value_range_equiv *op_range
> > -                   = try_find_new_range (t, t, comp_code, value);
> > -                 if (op_range)
> > -                   push_value_range (t, op_range);
> > -               }
> > -           }
> > -         /* Add VR when (OP COMP_CODE value) condition is true.  */
> > -         value_range_equiv *op_range = try_find_new_range (op, op,
> > -                                                           comp_code, value);
> > -         if (op_range)
> > -           push_value_range (op, op_range);
> > -       }
> > -    }
> > -}
> > -
> > -/* Unwind recorded ranges to their most recent state.  */
> > -
> > -void
> > -evrp_range_analyzer::pop_to_marker (void)
> > -{
> > -  gcc_checking_assert (!stack.is_empty ());
> > -  while (stack.last ().first != NULL_TREE)
> > -    pop_value_range ();
> > -  stack.pop ();
> > -}
> > -
> > -/* Restore/pop VRs valid only for BB when we leave BB.  */
> > -
> > -void
> > -evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
> > -{
> > -  if (!optimize)
> > -    return;
> > -  pop_to_marker ();
> > -}
> > -
> > -
> > -/* Push the Value Range of VAR to the stack and update it with new VR.  */
> > -
> > -void
> > -evrp_range_analyzer::push_value_range (tree var, value_range_equiv *vr)
> > -{
> > -  if (dump_file && (dump_flags & TDF_DETAILS))
> > -    {
> > -      fprintf (dump_file, "pushing new range for ");
> > -      print_generic_expr (dump_file, var);
> > -      fprintf (dump_file, ": ");
> > -      dump_value_range (dump_file, vr);
> > -      fprintf (dump_file, "\n");
> > -    }
> > -  value_range_equiv *old_vr = swap_vr_value (var, vr);
> > -  stack.safe_push (std::make_pair (var, old_vr));
> > -}
> > -
> > -/* Pop a Value Range from the vrp_stack.  */
> > -
> > -void
> > -evrp_range_analyzer::pop_value_range ()
> > -{
> > -  std::pair<tree, value_range_equiv *> e = stack.pop ();
> > -  tree var = e.first;
> > -  value_range_equiv *vr = e.second;
> > -  if (dump_file && (dump_flags & TDF_DETAILS))
> > -    {
> > -      fprintf (dump_file, "popping range for ");
> > -      print_generic_expr (dump_file, var);
> > -      fprintf (dump_file, ", restoring ");
> > -      dump_value_range (dump_file, vr);
> > -      fprintf (dump_file, "\n");
> > -    }
> > -  /* We saved off a lattice entry, now give it back and release
> > -     the one we popped.  */
> > -  value_range_equiv *popped_vr = swap_vr_value (var, vr);
> > -  if (popped_vr)
> > -    free_value_range (popped_vr);
> > -}
> > diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
> > deleted file mode 100644
> > index 51c32099dc5..00000000000
> > --- a/gcc/gimple-ssa-evrp-analyze.h
> > +++ /dev/null
> > @@ -1,58 +0,0 @@
> > -/* Support routines for Value Range Propagation (VRP).
> > -   Copyright (C) 2016-2022 Free Software Foundation, Inc.
> > -
> > -This file is part of GCC.
> > -
> > -GCC is free software; you can redistribute it and/or modify
> > -it under the terms of the GNU General Public License as published by
> > -the Free Software Foundation; either version 3, or (at your option)
> > -any later version.
> > -
> > -GCC is distributed in the hope that it will be useful,
> > -but WITHOUT ANY WARRANTY; without even the implied warranty of
> > -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > -GNU General Public License for more details.
> > -
> > -You should have received a copy of the GNU General Public License
> > -along with GCC; see the file COPYING3.  If not see
> > -<http://www.gnu.org/licenses/>.  */
> > -
> > -#ifndef GCC_GIMPLE_SSA_EVRP_ANALYZE_H
> > -#define GCC_GIMPLE_SSA_EVRP_ANALYZE_H
> > -
> > -class evrp_range_analyzer : public vr_values
> > -{
> > - public:
> > -  evrp_range_analyzer (bool update_global_ranges);
> > -  ~evrp_range_analyzer (void)
> > -  {
> > -    stack.release ();
> > -  }
> > -
> > -  void enter (basic_block);
> > -  void push_marker (void);
> > -  void pop_to_marker (void);
> > -  void leave (basic_block);
> > -  void record_ranges_from_stmt (gimple *, bool);
> > -
> > -  /* Record a new unwindable range.  */
> > -  void push_value_range (tree var, value_range_equiv *vr);
> > -
> > - private:
> > -  DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
> > -
> > -  void pop_value_range ();
> > -  value_range_equiv *try_find_new_range (tree, tree op, tree_code code,
> > -                                        tree limit);
> > -  void record_ranges_from_incoming_edge (basic_block);
> > -  void record_ranges_from_phis (basic_block);
> > -  void set_ssa_range_info (tree, value_range_equiv *);
> > -
> > -  /* STACK holds the old VR.  */
> > -  auto_vec<std::pair <tree, value_range_equiv *> > stack;
> > -
> > -  /* True if we are updating global ranges, false otherwise.  */
> > -  bool m_update_global_ranges;
> > -};
> > -
> > -#endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
> > diff --git a/gcc/gimple-ssa-evrp.cc b/gcc/gimple-ssa-evrp.cc
> > deleted file mode 100644
> > index 20388ed5431..00000000000
> > --- a/gcc/gimple-ssa-evrp.cc
> > +++ /dev/null
> > @@ -1,395 +0,0 @@
> > -/* Support routines for Value Range Propagation (VRP).
> > -   Copyright (C) 2005-2022 Free Software Foundation, Inc.
> > -
> > -This file is part of GCC.
> > -
> > -GCC is free software; you can redistribute it and/or modify
> > -it under the terms of the GNU General Public License as published by
> > -the Free Software Foundation; either version 3, or (at your option)
> > -any later version.
> > -
> > -GCC is distributed in the hope that it will be useful,
> > -but WITHOUT ANY WARRANTY; without even the implied warranty of
> > -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > -GNU General Public License for more details.
> > -
> > -You should have received a copy of the GNU General Public License
> > -along with GCC; see the file COPYING3.  If not see
> > -<http://www.gnu.org/licenses/>.  */
> > -
> > -#include "config.h"
> > -#include "system.h"
> > -#include "coretypes.h"
> > -#include "backend.h"
> > -#include "tree.h"
> > -#include "gimple.h"
> > -#include "tree-pass.h"
> > -#include "ssa.h"
> > -#include "gimple-pretty-print.h"
> > -#include "cfganal.h"
> > -#include "gimple-iterator.h"
> > -#include "gimple-fold.h"
> > -#include "tree-eh.h"
> > -#include "tree-cfg.h"
> > -#include "tree-ssa-loop-manip.h"
> > -#include "tree-ssa-loop.h"
> > -#include "cfgloop.h"
> > -#include "tree-scalar-evolution.h"
> > -#include "tree-ssa-propagate.h"
> > -#include "alloc-pool.h"
> > -#include "domwalk.h"
> > -#include "tree-cfgcleanup.h"
> > -#include "vr-values.h"
> > -#include "gimple-ssa-evrp-analyze.h"
> > -#include "gimple-range.h"
> > -#include "fold-const.h"
> > -#include "value-pointer-equiv.h"
> > -#include "tree-vrp.h"
> > -
> > -// This is the classic EVRP folder which uses a dominator walk and pushes
> > -// ranges into the next block if it is a single predecessor block.
> > -
> > -class evrp_folder : public substitute_and_fold_engine
> > -{
> > -public:
> > -  evrp_folder () :
> > -    substitute_and_fold_engine (),
> > -    m_range_analyzer (/*update_global_ranges=*/true),
> > -    simplifier (&m_range_analyzer)
> > -  { }
> > -
> > -  ~evrp_folder ()
> > -  {
> > -    if (dump_file)
> > -      {
> > -       fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
> > -       m_range_analyzer.dump (dump_file);
> > -       fprintf (dump_file, "\n");
> > -      }
> > -  }
> > -
> > -  tree value_of_expr (tree name, gimple *stmt) override
> > -  {
> > -    return m_range_analyzer.value_of_expr (name, stmt);
> > -  }
> > -
> > -  void pre_fold_bb (basic_block bb) override
> > -  {
> > -    if (dump_file && (dump_flags & TDF_DETAILS))
> > -      fprintf (dump_file, "evrp visiting BB%d\n", bb->index);
> > -    m_range_analyzer.enter (bb);
> > -  }
> > -
> > -  void pre_fold_stmt (gimple *stmt) override
> > -  {
> > -    if (dump_file && (dump_flags & TDF_DETAILS))
> > -      {
> > -       fprintf (dump_file, "evrp visiting stmt ");
> > -       print_gimple_stmt (dump_file, stmt, 0);
> > -      }
> > -    m_range_analyzer.record_ranges_from_stmt (stmt, false);
> > -  }
> > -
> > -  bool fold_stmt (gimple_stmt_iterator *gsi) override
> > -  {
> > -    return simplifier.simplify (gsi);
> > -  }
> > -
> > -  void post_fold_bb (basic_block bb) override
> > -  {
> > -    m_range_analyzer.leave (bb);
> > -  }
> > -
> > -  void post_new_stmt (gimple *stmt) override
> > -  {
> > -    m_range_analyzer.set_defs_to_varying (stmt);
> > -  }
> > -
> > -protected:
> > -  DISABLE_COPY_AND_ASSIGN (evrp_folder);
> > -  evrp_range_analyzer m_range_analyzer;
> > -  simplify_using_ranges simplifier;
> > -};
> > -
> > -// In a hybrid folder, start with an EVRP folder, and add the required
> > -// fold_stmt bits to either try the ranger first or second.
> > -//
> > -// The 3 value_* routines will always query both EVRP and the ranger for
> > -// a result, and ensure they return the same value.  If either returns a value
> > -// when the other doesn't, it is flagged in the listing, and the discoverd
> > -// value is returned.
> > -//
> > -// The simplifier is unable to process 2 different sources, thus we try to
> > -// use one engine, and if it fails to simplify, try using the other engine.
> > -// It is reported when the first attempt fails and the second succeeds.
> > -
> > -class hybrid_folder : public evrp_folder
> > -{
> > -public:
> > -  hybrid_folder (bool evrp_first)
> > -  {
> > -    m_ranger = enable_ranger (cfun);
> > -
> > -    if (evrp_first)
> > -      {
> > -       first = &m_range_analyzer;
> > -       first_exec_flag = 0;
> > -       second = m_ranger;
> > -       second_exec_flag = m_ranger->non_executable_edge_flag;
> > -      }
> > -     else
> > -      {
> > -       first = m_ranger;
> > -       first_exec_flag = m_ranger->non_executable_edge_flag;
> > -       second = &m_range_analyzer;
> > -       second_exec_flag = 0;
> > -      }
> > -    m_pta = new pointer_equiv_analyzer (m_ranger);
> > -  }
> > -
> > -  ~hybrid_folder ()
> > -  {
> > -    if (dump_file && (dump_flags & TDF_DETAILS))
> > -      m_ranger->dump (dump_file);
> > -
> > -    m_ranger->export_global_ranges ();
> > -    disable_ranger (cfun);
> > -    delete m_pta;
> > -  }
> > -
> > -  bool fold_stmt (gimple_stmt_iterator *gsi) override
> > -    {
> > -      simplifier.set_range_query (first, first_exec_flag);
> > -      if (simplifier.simplify (gsi))
> > -       return true;
> > -
> > -      simplifier.set_range_query (second, second_exec_flag);
> > -      if (simplifier.simplify (gsi))
> > -       {
> > -         if (dump_file)
> > -           fprintf (dump_file, "EVRP:hybrid: Second query simplifed stmt\n");
> > -         return true;
> > -       }
> > -      return false;
> > -    }
> > -
> > -  void pre_fold_stmt (gimple *stmt) override
> > -  {
> > -    evrp_folder::pre_fold_stmt (stmt);
> > -    m_pta->visit_stmt (stmt);
> > -  }
> > -
> > -  void pre_fold_bb (basic_block bb) override
> > -  {
> > -    evrp_folder::pre_fold_bb (bb);
> > -    m_pta->enter (bb);
> > -  }
> > -
> > -  void post_fold_bb (basic_block bb) override
> > -  {
> > -    evrp_folder::post_fold_bb (bb);
> > -    m_pta->leave (bb);
> > -  }
> > -
> > -  tree value_of_expr (tree name, gimple *) override;
> > -  tree value_on_edge (edge, tree name) override;
> > -  tree value_of_stmt (gimple *, tree name) override;
> > -
> > -private:
> > -  DISABLE_COPY_AND_ASSIGN (hybrid_folder);
> > -  gimple_ranger *m_ranger;
> > -  range_query *first;
> > -  int first_exec_flag;
> > -  range_query *second;
> > -  int second_exec_flag;
> > -  pointer_equiv_analyzer *m_pta;
> > -  tree choose_value (tree evrp_val, tree ranger_val);
> > -};
> > -
> > -
> > -tree
> > -hybrid_folder::value_of_expr (tree op, gimple *stmt)
> > -{
> > -  tree evrp_ret = evrp_folder::value_of_expr (op, stmt);
> > -  tree ranger_ret;
> > -  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> > -    ranger_ret = NULL;
> > -  else
> > -    {
> > -      ranger_ret = m_ranger->value_of_expr (op, stmt);
> > -      if (!ranger_ret && supported_pointer_equiv_p (op))
> > -       ranger_ret = m_pta->get_equiv (op);
> > -    }
> > -  return choose_value (evrp_ret, ranger_ret);
> > -}
> > -
> > -tree
> > -hybrid_folder::value_on_edge (edge e, tree op)
> > -{
> > -  // Call evrp::value_of_expr directly.  Otherwise another dual call is made
> > -  // via hybrid_folder::value_of_expr, but without an edge.
> > -  tree evrp_ret = evrp_folder::value_of_expr (op, NULL);
> > -  tree ranger_ret;
> > -  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> > -    ranger_ret = NULL;
> > -  else
> > -    {
> > -      ranger_ret = m_ranger->value_on_edge (e, op);
> > -      if (!ranger_ret && supported_pointer_equiv_p (op))
> > -       ranger_ret = m_pta->get_equiv (op);
> > -    }
> > -  return choose_value (evrp_ret, ranger_ret);
> > -}
> > -
> > -tree
> > -hybrid_folder::value_of_stmt (gimple *stmt, tree op)
> > -{
> > -  // Call evrp::value_of_expr directly.  Otherwise another dual call is made
> > -  // via hybrid_folder::value_of_expr, but without a stmt.
> > -  tree evrp_ret;
> > -  if (op)
> > -    evrp_ret = evrp_folder::value_of_expr (op, NULL);
> > -  else
> > -    evrp_ret = NULL_TREE;
> > -
> > -  tree ranger_ret;
> > -  if (op && TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
> > -    ranger_ret = NULL;
> > -  else
> > -    ranger_ret = m_ranger->value_of_stmt (stmt, op);
> > -  return choose_value (evrp_ret, ranger_ret);
> > -}
> > -
> > -// Given trees returned by EVRP and Ranger, choose/report the value to use
> > -// by the folder.
> > -
> > -tree
> > -hybrid_folder::choose_value (tree evrp_val, tree ranger_val)
> > -{
> > -  // If both found the same value, just return it.
> > -  if (evrp_val && ranger_val && !compare_values (evrp_val, ranger_val))
> > -    return evrp_val;
> > -
> > -  // If neither returned a value, return NULL_TREE.
> > -  if (!ranger_val && !evrp_val)
> > -    return NULL_TREE;
> > -
> > -  // Otherwise there is a discrepancy to flag.
> > -  if (dump_file)
> > -    {
> > -      if (evrp_val && ranger_val)
> > -       fprintf (dump_file, "EVRP:hybrid: Disagreement\n");
> > -      if (evrp_val)
> > -       {
> > -         fprintf (dump_file, "EVRP:hybrid: EVRP found singleton ");
> > -         print_generic_expr (dump_file, evrp_val);
> > -         fprintf (dump_file, "\n");
> > -       }
> > -      if (ranger_val)
> > -       {
> > -         fprintf (dump_file, "EVRP:hybrid: RVRP found singleton ");
> > -         print_generic_expr (dump_file, ranger_val);
> > -         fprintf (dump_file, "\n");
> > -       }
> > -    }
> > -
> > -  // If one value was found, return it.
> > -  if (!evrp_val)
> > -    return ranger_val;
> > -  if (!ranger_val)
> > -    return evrp_val;
> > -
> > -  // If values are different, return the first calculated value.
> > -  if (param_evrp_mode == EVRP_MODE_RVRP_FIRST)
> > -    return ranger_val;
> > -  return evrp_val;
> > -}
> > -
> > -/* Main entry point for the early vrp pass which is a simplified non-iterative
> > -   version of vrp where basic blocks are visited in dominance order.  Value
> > -   ranges discovered in early vrp will also be used by ipa-vrp.  */
> > -
> > -static unsigned int
> > -execute_early_vrp ()
> > -{
> > -  if (param_evrp_mode == EVRP_MODE_RVRP_ONLY)
> > -    return execute_ranger_vrp (cfun, false);
> > -
> > -  /* Ideally this setup code would move into the ctor for the folder
> > -     However, this setup can change the number of blocks which
> > -     invalidates the internal arrays that are set up by the dominator
> > -     walker in substitute_and_fold_engine.  */
> > -  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
> > -  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
> > -  scev_initialize ();
> > -  calculate_dominance_info (CDI_DOMINATORS);
> > -
> > -  // Only the last 2 bits matter for choosing the folder.
> > -  switch (param_evrp_mode)
> > -    {
> > -    case EVRP_MODE_EVRP_ONLY:
> > -      {
> > -       evrp_folder folder;
> > -       folder.substitute_and_fold ();
> > -       break;
> > -      }
> > -    case EVRP_MODE_EVRP_FIRST:
> > -      {
> > -       hybrid_folder folder (true);
> > -       folder.substitute_and_fold ();
> > -       break;
> > -      }
> > -    case EVRP_MODE_RVRP_FIRST:
> > -      {
> > -       hybrid_folder folder (false);
> > -       folder.substitute_and_fold ();
> > -       break;
> > -      }
> > -    default:
> > -      gcc_unreachable ();
> > -    }
> > -
> > -  scev_finalize ();
> > -  loop_optimizer_finalize ();
> > -  return 0;
> > -}
> > -
> > -namespace {
> > -
> > -const pass_data pass_data_early_vrp =
> > -{
> > -  GIMPLE_PASS, /* type */
> > -  "evrp", /* name */
> > -  OPTGROUP_NONE, /* optinfo_flags */
> > -  TV_TREE_EARLY_VRP, /* tv_id */
> > -  PROP_ssa, /* properties_required */
> > -  0, /* properties_provided */
> > -  0, /* properties_destroyed */
> > -  0, /* todo_flags_start */
> > -  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
> > -};
> > -
> > -class pass_early_vrp : public gimple_opt_pass
> > -{
> > -public:
> > -  pass_early_vrp (gcc::context *ctxt)
> > -    : gimple_opt_pass (pass_data_early_vrp, ctxt)
> > -    {}
> > -
> > -  /* opt_pass methods: */
> > -  opt_pass * clone () { return new pass_early_vrp (m_ctxt); }
> > -  virtual bool gate (function *)
> > -    {
> > -      return flag_tree_vrp != 0;
> > -    }
> > -  virtual unsigned int execute (function *)
> > -    { return execute_early_vrp (); }
> > -
> > -}; // class pass_vrp
> > -} // anon namespace
> > -
> > -gimple_opt_pass *
> > -make_pass_early_vrp (gcc::context *ctxt)
> > -{
> > -  return new pass_early_vrp (ctxt);
> > -}
> > diff --git a/gcc/params.opt b/gcc/params.opt
> > index bcf1423671a..2f9c9cf27dd 100644
> > --- a/gcc/params.opt
> > +++ b/gcc/params.opt
> > @@ -134,25 +134,6 @@ Maximum number of basic blocks before EVRP uses a sparse cache.
> >  Common Joined UInteger Var(param_evrp_switch_limit) Init(50) Optimization Param
> >  Maximum number of outgoing edges in a switch before EVRP will not process it.
> >
> > --param=evrp-mode=
> > -Common Joined Var(param_evrp_mode) Enum(evrp_mode) Init(EVRP_MODE_RVRP_ONLY) Param Optimization
> > ---param=evrp-mode=[legacy|ranger|legacy-first|ranger-first] Specifies the mode Early VRP should operate in.
> > -
> > -Enum
> > -Name(evrp_mode) Type(enum evrp_mode) UnknownError(unknown evrp mode %qs)
> > -
> > -EnumValue
> > -Enum(evrp_mode) String(legacy) Value(EVRP_MODE_EVRP_ONLY)
> > -
> > -EnumValue
> > -Enum(evrp_mode) String(ranger) Value(EVRP_MODE_RVRP_ONLY)
> > -
> > -EnumValue
> > -Enum(evrp_mode) String(legacy-first) Value(EVRP_MODE_EVRP_FIRST)
> > -
> > -EnumValue
> > -Enum(evrp_mode) String(ranger-first) Value(EVRP_MODE_RVRP_FIRST)
> > -
> >  -param=fsm-scale-path-blocks=
> >  Common Joined UInteger Var(param_fsm_scale_path_blocks) Init(3) IntegerRange(1, 10) Param Optimization
> >  Scale factor to apply to the number of blocks in a threading path when comparing to the number of (scaled) statements.
> > diff --git a/gcc/testsuite/g++.dg/pr100774.C b/gcc/testsuite/g++.dg/pr100774.C
> > index 345fcfa0d01..63320ef73fc 100644
> > --- a/gcc/testsuite/g++.dg/pr100774.C
> > +++ b/gcc/testsuite/g++.dg/pr100774.C
> > @@ -1,5 +1,5 @@
> >  /* { dg-do compile } */
> > -/* { dg-options "-O2 -fno-tree-forwprop --param=evrp-mode=ranger -fcompare-debug  " } */
> > +/* { dg-options "-O2 -fno-tree-forwprop -fcompare-debug  " } */
> >
> >  extern void __attribute__((noreturn)) error();
> >
> > diff --git a/gcc/testsuite/gcc.dg/pr100781.c b/gcc/testsuite/gcc.dg/pr100781.c
> > index c0e008a3ba5..96f0a7a6012 100644
> > --- a/gcc/testsuite/gcc.dg/pr100781.c
> > +++ b/gcc/testsuite/gcc.dg/pr100781.c
> > @@ -1,5 +1,5 @@
> >  /* { dg-do compile } */
> > -/* { dg-options "-O2 --param=evrp-mode=ranger -fcompare-debug  " } */
> > +/* { dg-options "-O2 -fcompare-debug  " } */
> >
> >  struct a {
> >    int b;
> > diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> > index 30022dac108..7b4e2917340 100644
> > --- a/gcc/tree-vrp.cc
> > +++ b/gcc/tree-vrp.cc
> > @@ -4388,17 +4388,30 @@ const pass_data pass_data_vrp =
> >    ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
> >  };
> >
> > +const pass_data pass_data_early_vrp =
> > +{
> > +  GIMPLE_PASS, /* type */
> > +  "evrp", /* name */
> > +  OPTGROUP_NONE, /* optinfo_flags */
> > +  TV_TREE_EARLY_VRP, /* tv_id */
> > +  PROP_ssa, /* properties_required */
> > +  0, /* properties_provided */
> > +  0, /* properties_destroyed */
> > +  0, /* todo_flags_start */
> > +  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
> > +};
> > +
> >  static int vrp_pass_num = 0;
> >  class pass_vrp : public gimple_opt_pass
> >  {
> >  public:
> > -  pass_vrp (gcc::context *ctxt)
> > -    : gimple_opt_pass (pass_data_vrp, ctxt), warn_array_bounds_p (false),
> > -      my_pass (++vrp_pass_num)
> > +  pass_vrp (gcc::context *ctxt, const pass_data &data_)
> > +    : gimple_opt_pass (data_, ctxt), data (data_), warn_array_bounds_p (false),
> > +      my_pass (vrp_pass_num++)
> >    {}
> >
> >    /* opt_pass methods: */
> > -  opt_pass * clone () { return new pass_vrp (m_ctxt); }
> > +  opt_pass * clone () { return new pass_vrp (m_ctxt, data); }
> >    void set_pass_param (unsigned int n, bool param)
> >      {
> >        gcc_assert (n == 0);
> > @@ -4407,6 +4420,10 @@ public:
> >    virtual bool gate (function *) { return flag_tree_vrp != 0; }
> >    virtual unsigned int execute (function *fun)
> >      {
> > +      // Early VRP pass.
> > +      if (my_pass == 0)
> > +       return execute_ranger_vrp (fun, /*warn_array_bounds_p=*/false);
> > +
> >        if ((my_pass == 1 && param_vrp1_mode == VRP_MODE_RANGER)
> >           || (my_pass == 2 && param_vrp2_mode == VRP_MODE_RANGER))
> >         return execute_ranger_vrp (fun, warn_array_bounds_p);
> > @@ -4414,6 +4431,7 @@ public:
> >      }
> >
> >   private:
> > +  const pass_data &data;
> >    bool warn_array_bounds_p;
> >    int my_pass;
> >  }; // class pass_vrp
> > @@ -4423,5 +4441,11 @@ public:
> >  gimple_opt_pass *
> >  make_pass_vrp (gcc::context *ctxt)
> >  {
> > -  return new pass_vrp (ctxt);
> > +  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);
> >  }
> > --
> > 2.36.1
> >
>
  
Jeff Law June 28, 2022, 1:38 p.m. UTC | #3
On 6/28/2022 1:37 AM, Richard Biener via Gcc-patches wrote:
> On Mon, Jun 27, 2022 at 9:04 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>> With DOM converted to ranger, there are no longer any uses of the EVRP
>> engine.  For that matter, we haven't used the legacy mode in quite a
>> while, so I think it's safe to remove any associated code.
>>
>> There are some methods in vr_values which should now be private, but I
>> didn't bother changing them, as most of the vr_values class will be
>> removed when VRP1 is converted to ranger.
>>
>> Does anyone have any issues with me pushing this?
> Fine with me.
Likewise.
jeff
  

Patch

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b6dcc45a58a..86257a8b84f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1413,8 +1413,6 @@  OBJS = \
 	gimple-range-infer.o \
 	gimple-range-trace.o \
 	gimple-ssa-backprop.o \
-	gimple-ssa-evrp.o \
-	gimple-ssa-evrp-analyze.o \
 	gimple-ssa-isolate-paths.o \
 	gimple-ssa-nonnull-compare.o \
 	gimple-ssa-split-paths.o \
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 2c8498169e0..a11f99af887 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -479,15 +479,6 @@  enum threader_debug
   THREADER_DEBUG_ALL = 1
 };
 
-/* EVRP mode.  */
-enum evrp_mode
-{
-  EVRP_MODE_RVRP_ONLY,
-  EVRP_MODE_EVRP_ONLY,
-  EVRP_MODE_EVRP_FIRST,
-  EVRP_MODE_RVRP_FIRST
-};
-
 /* VRP modes.  */
 enum vrp_mode
 {
diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
deleted file mode 100644
index 82142db7976..00000000000
--- a/gcc/gimple-ssa-evrp-analyze.cc
+++ /dev/null
@@ -1,456 +0,0 @@ 
-/* Support routines for Value Range Propagation (VRP).
-   Copyright (C) 2005-2022 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "tree.h"
-#include "gimple.h"
-#include "tree-pass.h"
-#include "ssa.h"
-#include "gimple-pretty-print.h"
-#include "cfganal.h"
-#include "gimple-iterator.h"
-#include "gimple-fold.h"
-#include "tree-eh.h"
-#include "tree-cfg.h"
-#include "tree-ssa-loop-manip.h"
-#include "tree-ssa-loop.h"
-#include "cfgloop.h"
-#include "tree-scalar-evolution.h"
-#include "tree-ssa-propagate.h"
-#include "alloc-pool.h"
-#include "domwalk.h"
-#include "tree-cfgcleanup.h"
-#include "vr-values.h"
-#include "gimple-ssa-evrp-analyze.h"
-
-evrp_range_analyzer::evrp_range_analyzer (bool update_global_ranges)
-  : stack (10), m_update_global_ranges (update_global_ranges)
-{
-  edge e;
-  edge_iterator ei;
-  basic_block bb;
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      bb->flags &= ~BB_VISITED;
-      FOR_EACH_EDGE (e, ei, bb->preds)
-        e->flags |= EDGE_EXECUTABLE;
-    }
-}
-
-/* Push an unwinding marker onto the unwinding stack.  */
-
-void
-evrp_range_analyzer::push_marker ()
-{
-  stack.safe_push (std::make_pair (NULL_TREE, (value_range_equiv *)NULL));
-}
-
-/* Analyze ranges as we enter basic block BB.  */
-
-void
-evrp_range_analyzer::enter (basic_block bb)
-{
-  if (!optimize)
-    return;
-  push_marker ();
-  record_ranges_from_incoming_edge (bb);
-  record_ranges_from_phis (bb);
-  bb->flags |= BB_VISITED;
-}
-
-/* Find new range for NAME such that (OP CODE LIMIT) is true.  */
-value_range_equiv *
-evrp_range_analyzer::try_find_new_range (tree name,
-					 tree op, tree_code code, tree limit)
-{
-  value_range_equiv vr;
-  const value_range_equiv *old_vr = get_value_range (name);
-
-  /* Discover VR when condition is true.  */
-  extract_range_for_var_from_comparison_expr (name, code, op, limit, &vr);
-  /* If we found any usable VR, set the VR to ssa_name and create a
-     PUSH old value in the stack with the old VR.  */
-  if (!vr.undefined_p () && !vr.varying_p ())
-    {
-      if (old_vr->equal_p (vr, /*ignore_equivs=*/true))
-	return NULL;
-      value_range_equiv *new_vr = allocate_value_range_equiv ();
-      new_vr->move (&vr);
-      return new_vr;
-    }
-  return NULL;
-}
-
-/* For LHS record VR in the SSA info.  */
-void
-evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range_equiv *vr)
-{
-  gcc_assert (m_update_global_ranges);
-
-  /* Set the SSA with the value range.  */
-  if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
-    {
-      if (!vr->varying_p () && vr->constant_p ())
-	set_range_info (lhs, *vr);
-    }
-  else if (POINTER_TYPE_P (TREE_TYPE (lhs))
-	   && range_includes_zero_p (vr) == 0)
-    set_ptr_nonnull (lhs);
-}
-
-/* Return true if all uses of NAME are dominated by STMT or feed STMT
-   via a chain of single immediate uses.  */
-
-static bool
-all_uses_feed_or_dominated_by_stmt (tree name, gimple *stmt)
-{
-  use_operand_p use_p, use2_p;
-  imm_use_iterator iter;
-  basic_block stmt_bb = gimple_bb (stmt);
-
-  FOR_EACH_IMM_USE_FAST (use_p, iter, name)
-    {
-      gimple *use_stmt = USE_STMT (use_p), *use_stmt2;
-      if (use_stmt == stmt
-	  || is_gimple_debug (use_stmt)
-	  || (gimple_bb (use_stmt) != stmt_bb
-	      && dominated_by_p (CDI_DOMINATORS,
-				 gimple_bb (use_stmt), stmt_bb)))
-	continue;
-      while (use_stmt != stmt
-	     && is_gimple_assign (use_stmt)
-	     && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
-	     && single_imm_use (gimple_assign_lhs (use_stmt),
-				&use2_p, &use_stmt2))
-	use_stmt = use_stmt2;
-      if (use_stmt != stmt)
-	return false;
-    }
-  return true;
-}
-
-void
-evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
-{
-  edge pred_e = single_pred_edge_ignoring_loop_edges (bb, false);
-  if (pred_e)
-    {
-      gimple *stmt = last_stmt (pred_e->src);
-      tree op0 = NULL_TREE;
-
-      if (stmt
-	  && gimple_code (stmt) == GIMPLE_COND
-	  && (op0 = gimple_cond_lhs (stmt))
-	  && TREE_CODE (op0) == SSA_NAME
-	  && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))
-	      || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)))))
-	{
-	  if (dump_file && (dump_flags & TDF_DETAILS))
-	    {
-	      fprintf (dump_file, "Visiting controlling predicate ");
-	      print_gimple_stmt (dump_file, stmt, 0);
-	    }
-	  /* Entering a new scope.  Try to see if we can find a VR
-	     here.  */
-	  tree op1 = gimple_cond_rhs (stmt);
-	  if (TREE_OVERFLOW_P (op1))
-	    op1 = drop_tree_overflow (op1);
-	  tree_code code = gimple_cond_code (stmt);
-
-	  auto_vec<assert_info, 8> asserts;
-	  register_edge_assert_for (op0, pred_e, code, op0, op1, asserts);
-	  if (TREE_CODE (op1) == SSA_NAME)
-	    register_edge_assert_for (op1, pred_e, code, op0, op1, asserts);
-
-	  auto_vec<std::pair<tree, value_range_equiv *>, 8> vrs;
-	  for (unsigned i = 0; i < asserts.length (); ++i)
-	    {
-	      value_range_equiv *vr
-		= try_find_new_range (asserts[i].name,
-				      asserts[i].expr,
-				      asserts[i].comp_code,
-				      asserts[i].val);
-	      if (vr)
-		vrs.safe_push (std::make_pair (asserts[i].name, vr));
-	    }
-
-	  /* If pred_e is really a fallthru we can record value ranges
-	     in SSA names as well.  */
-	  bool is_fallthru = assert_unreachable_fallthru_edge_p (pred_e);
-
-	  /* Push updated ranges only after finding all of them to avoid
-	     ordering issues that can lead to worse ranges.  */
-	  for (unsigned i = 0; i < vrs.length (); ++i)
-	    {
-	      /* But make sure we do not weaken ranges like when
-	         getting first [64, +INF] and then ~[0, 0] from
-		 conditions like (s & 0x3cc0) == 0).  */
-	      const value_range_equiv *old_vr
-		= get_value_range (vrs[i].first);
-	      value_range tem (*old_vr);
-	      tem.legacy_verbose_intersect (vrs[i].second);
-	      if (tem.equal_p (*old_vr))
-		{
-		  free_value_range (vrs[i].second);
-		  continue;
-		}
-	      push_value_range (vrs[i].first, vrs[i].second);
-	      if (is_fallthru
-		  && m_update_global_ranges
-		  && all_uses_feed_or_dominated_by_stmt (vrs[i].first, stmt)
-		  /* The condition must post-dominate the definition point.  */
-		  && (SSA_NAME_IS_DEFAULT_DEF (vrs[i].first)
-		      || (gimple_bb (SSA_NAME_DEF_STMT (vrs[i].first))
-			  == pred_e->src)))
-		{
-		  set_ssa_range_info (vrs[i].first, vrs[i].second);
-		  maybe_set_nonzero_bits (pred_e, vrs[i].first);
-		}
-	    }
-	}
-    }
-}
-
-void
-evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
-{
-  /* Visit PHI stmts and discover any new VRs possible.  */
-  bool has_unvisited_preds = false;
-  edge_iterator ei;
-  edge e;
-  FOR_EACH_EDGE (e, ei, bb->preds)
-    if (e->flags & EDGE_EXECUTABLE
-	&& !(e->src->flags & BB_VISITED))
-      {
-	has_unvisited_preds = true;
-	break;
-      }
-
-  for (gphi_iterator gpi = gsi_start_phis (bb);
-       !gsi_end_p (gpi); gsi_next (&gpi))
-    {
-      gphi *phi = gpi.phi ();
-      tree lhs = PHI_RESULT (phi);
-      if (virtual_operand_p (lhs))
-	continue;
-
-      /* Skips floats and other things we can't represent in a
-	 range.  */
-      if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
-	continue;
-
-      value_range_equiv vr_result;
-      bool interesting = stmt_interesting_for_vrp (phi);
-      if (!has_unvisited_preds && interesting)
-	extract_range_from_phi_node (phi, &vr_result);
-      else
-	{
-	  vr_result.set_varying (TREE_TYPE (lhs));
-	  /* When we have an unvisited executable predecessor we can't
-	     use PHI arg ranges which may be still UNDEFINED but have
-	     to use VARYING for them.  But we can still resort to
-	     SCEV for loop header PHIs.  */
-	  class loop *l;
-	  if (scev_initialized_p ()
-	      && interesting
-	      && (l = loop_containing_stmt (phi))
-	      && l->header == gimple_bb (phi))
-	  adjust_range_with_scev (&vr_result, l, phi, lhs);
-	}
-      update_value_range (lhs, &vr_result);
-
-      /* Set the SSA with the value range.  */
-      if (m_update_global_ranges)
-	set_ssa_range_info (lhs, &vr_result);
-    }
-}
-
-/* Record ranges from STMT into our VR_VALUES class.  If TEMPORARY is
-   true, then this is a temporary equivalence and should be recorded
-   into the unwind table.  Othewise record the equivalence into the
-   global table.  */
-
-void
-evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
-{
-  tree output = NULL_TREE;
-
-  if (!optimize)
-    return;
-
-  if (dyn_cast <gcond *> (stmt))
-    ;
-  else if (stmt_interesting_for_vrp (stmt))
-    {
-      edge taken_edge;
-      value_range_equiv vr;
-      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
-      if (output)
-	{
-	  /* Set the SSA with the value range.  There are two cases to
-	     consider.  First (the the most common) is we are processing
-	     STMT in a context where its resulting range globally holds
-	     and thus it can be reflected into the global ranges and need
-	     not be unwound as we leave scope.
-
-	     The second case occurs if we are processing a statement in
-	     a context where the resulting range must not be reflected
-	     into the global tables and must be unwound as we leave
-	     the current context.  This happens in jump threading for
-	     example.  */
-	  if (!temporary)
-	    {
-	      /* Case one.  We can just update the underlying range
-		 information as well as the global information.  */
-	      update_value_range (output, &vr);
-	      if (m_update_global_ranges)
-		set_ssa_range_info (output, &vr);
-	    }
-	  else
-	    {
-	      /* We're going to need to unwind this range.  We cannot
-		 use VR as that's a stack object.  We have to allocate
-		 a new range and push the old range onto the stack.  We
-		 also have to be very careful about sharing the underlying
-		 bitmaps.  Ugh.  */
-	      value_range_equiv *new_vr = allocate_value_range_equiv ();
-	      new_vr->set (vr.min (), vr.max (), NULL, vr.kind ());
-	      vr.equiv_clear ();
-	      push_value_range (output, new_vr);
-	    }
-	}
-      else
-	set_defs_to_varying (stmt);
-    }
-  else
-    set_defs_to_varying (stmt);
-
-  /* See if we can derive a range for any of STMT's operands.  */
-  tree op;
-  ssa_op_iter i;
-  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
-    {
-      tree value;
-      enum tree_code comp_code;
-
-      /* If OP is used in such a way that we can infer a value
-         range for it, and we don't find a previous assertion for
-         it, create a new assertion location node for OP.  */
-      if (infer_value_range (stmt, op, &comp_code, &value))
-	{
-	  /* If we are able to infer a nonzero value range for OP,
-	     then walk backwards through the use-def chain to see if OP
-	     was set via a typecast.
-	     If so, then we can also infer a nonzero value range
-	     for the operand of the NOP_EXPR.  */
-	  if (comp_code == NE_EXPR && integer_zerop (value))
-	    {
-	      tree t = op;
-	      gimple *def_stmt = SSA_NAME_DEF_STMT (t);
-	      while (is_gimple_assign (def_stmt)
-		     && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
-		     && TREE_CODE
-			  (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
-		     && POINTER_TYPE_P
-			  (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
-		{
-		  t = gimple_assign_rhs1 (def_stmt);
-		  def_stmt = SSA_NAME_DEF_STMT (t);
-
-		  /* Add VR when (T COMP_CODE value) condition is
-		     true.  */
-		  value_range_equiv *op_range
-		    = try_find_new_range (t, t, comp_code, value);
-		  if (op_range)
-		    push_value_range (t, op_range);
-		}
-	    }
-	  /* Add VR when (OP COMP_CODE value) condition is true.  */
-	  value_range_equiv *op_range = try_find_new_range (op, op,
-							    comp_code, value);
-	  if (op_range)
-	    push_value_range (op, op_range);
-	}
-    }
-}
-
-/* Unwind recorded ranges to their most recent state.  */
-
-void
-evrp_range_analyzer::pop_to_marker (void)
-{
-  gcc_checking_assert (!stack.is_empty ());
-  while (stack.last ().first != NULL_TREE)
-    pop_value_range ();
-  stack.pop ();
-}
-
-/* Restore/pop VRs valid only for BB when we leave BB.  */
-
-void
-evrp_range_analyzer::leave (basic_block bb ATTRIBUTE_UNUSED)
-{
-  if (!optimize)
-    return;
-  pop_to_marker ();
-}
-
-
-/* Push the Value Range of VAR to the stack and update it with new VR.  */
-
-void
-evrp_range_analyzer::push_value_range (tree var, value_range_equiv *vr)
-{
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "pushing new range for ");
-      print_generic_expr (dump_file, var);
-      fprintf (dump_file, ": ");
-      dump_value_range (dump_file, vr);
-      fprintf (dump_file, "\n");
-    }
-  value_range_equiv *old_vr = swap_vr_value (var, vr);
-  stack.safe_push (std::make_pair (var, old_vr));
-}
-
-/* Pop a Value Range from the vrp_stack.  */
-
-void
-evrp_range_analyzer::pop_value_range ()
-{
-  std::pair<tree, value_range_equiv *> e = stack.pop ();
-  tree var = e.first;
-  value_range_equiv *vr = e.second;
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "popping range for ");
-      print_generic_expr (dump_file, var);
-      fprintf (dump_file, ", restoring ");
-      dump_value_range (dump_file, vr);
-      fprintf (dump_file, "\n");
-    }
-  /* We saved off a lattice entry, now give it back and release
-     the one we popped.  */
-  value_range_equiv *popped_vr = swap_vr_value (var, vr);
-  if (popped_vr)
-    free_value_range (popped_vr);
-}
diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
deleted file mode 100644
index 51c32099dc5..00000000000
--- a/gcc/gimple-ssa-evrp-analyze.h
+++ /dev/null
@@ -1,58 +0,0 @@ 
-/* Support routines for Value Range Propagation (VRP).
-   Copyright (C) 2016-2022 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef GCC_GIMPLE_SSA_EVRP_ANALYZE_H
-#define GCC_GIMPLE_SSA_EVRP_ANALYZE_H
-
-class evrp_range_analyzer : public vr_values
-{
- public:
-  evrp_range_analyzer (bool update_global_ranges);
-  ~evrp_range_analyzer (void)
-  {
-    stack.release ();
-  }
-
-  void enter (basic_block);
-  void push_marker (void);
-  void pop_to_marker (void);
-  void leave (basic_block);
-  void record_ranges_from_stmt (gimple *, bool);
-
-  /* Record a new unwindable range.  */
-  void push_value_range (tree var, value_range_equiv *vr);
-
- private:
-  DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
-
-  void pop_value_range ();
-  value_range_equiv *try_find_new_range (tree, tree op, tree_code code,
-					 tree limit);
-  void record_ranges_from_incoming_edge (basic_block);
-  void record_ranges_from_phis (basic_block);
-  void set_ssa_range_info (tree, value_range_equiv *);
-
-  /* STACK holds the old VR.  */
-  auto_vec<std::pair <tree, value_range_equiv *> > stack;
-
-  /* True if we are updating global ranges, false otherwise.  */
-  bool m_update_global_ranges;
-};
-
-#endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
diff --git a/gcc/gimple-ssa-evrp.cc b/gcc/gimple-ssa-evrp.cc
deleted file mode 100644
index 20388ed5431..00000000000
--- a/gcc/gimple-ssa-evrp.cc
+++ /dev/null
@@ -1,395 +0,0 @@ 
-/* Support routines for Value Range Propagation (VRP).
-   Copyright (C) 2005-2022 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "backend.h"
-#include "tree.h"
-#include "gimple.h"
-#include "tree-pass.h"
-#include "ssa.h"
-#include "gimple-pretty-print.h"
-#include "cfganal.h"
-#include "gimple-iterator.h"
-#include "gimple-fold.h"
-#include "tree-eh.h"
-#include "tree-cfg.h"
-#include "tree-ssa-loop-manip.h"
-#include "tree-ssa-loop.h"
-#include "cfgloop.h"
-#include "tree-scalar-evolution.h"
-#include "tree-ssa-propagate.h"
-#include "alloc-pool.h"
-#include "domwalk.h"
-#include "tree-cfgcleanup.h"
-#include "vr-values.h"
-#include "gimple-ssa-evrp-analyze.h"
-#include "gimple-range.h"
-#include "fold-const.h"
-#include "value-pointer-equiv.h"
-#include "tree-vrp.h"
-
-// This is the classic EVRP folder which uses a dominator walk and pushes
-// ranges into the next block if it is a single predecessor block.
-
-class evrp_folder : public substitute_and_fold_engine
-{
-public:
-  evrp_folder () :
-    substitute_and_fold_engine (),
-    m_range_analyzer (/*update_global_ranges=*/true),
-    simplifier (&m_range_analyzer)
-  { }
-
-  ~evrp_folder ()
-  {
-    if (dump_file)
-      {
-	fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
-	m_range_analyzer.dump (dump_file);
-	fprintf (dump_file, "\n");
-      }
-  }
-
-  tree value_of_expr (tree name, gimple *stmt) override
-  {
-    return m_range_analyzer.value_of_expr (name, stmt);
-  }
-
-  void pre_fold_bb (basic_block bb) override
-  {
-    if (dump_file && (dump_flags & TDF_DETAILS))
-      fprintf (dump_file, "evrp visiting BB%d\n", bb->index);
-    m_range_analyzer.enter (bb);
-  }
-
-  void pre_fold_stmt (gimple *stmt) override
-  {
-    if (dump_file && (dump_flags & TDF_DETAILS))
-      {
-	fprintf (dump_file, "evrp visiting stmt ");
-	print_gimple_stmt (dump_file, stmt, 0);
-      }
-    m_range_analyzer.record_ranges_from_stmt (stmt, false);
-  }
-
-  bool fold_stmt (gimple_stmt_iterator *gsi) override
-  {
-    return simplifier.simplify (gsi);
-  }
-
-  void post_fold_bb (basic_block bb) override
-  {
-    m_range_analyzer.leave (bb);
-  }
-
-  void post_new_stmt (gimple *stmt) override
-  {
-    m_range_analyzer.set_defs_to_varying (stmt);
-  }
-
-protected:
-  DISABLE_COPY_AND_ASSIGN (evrp_folder);
-  evrp_range_analyzer m_range_analyzer;
-  simplify_using_ranges simplifier;
-};
-
-// In a hybrid folder, start with an EVRP folder, and add the required
-// fold_stmt bits to either try the ranger first or second.
-//
-// The 3 value_* routines will always query both EVRP and the ranger for
-// a result, and ensure they return the same value.  If either returns a value
-// when the other doesn't, it is flagged in the listing, and the discoverd
-// value is returned.
-//
-// The simplifier is unable to process 2 different sources, thus we try to 
-// use one engine, and if it fails to simplify, try using the other engine.
-// It is reported when the first attempt fails and the second succeeds.
-
-class hybrid_folder : public evrp_folder
-{
-public:
-  hybrid_folder (bool evrp_first)
-  {
-    m_ranger = enable_ranger (cfun);
-
-    if (evrp_first)
-      {
-	first = &m_range_analyzer;
-	first_exec_flag = 0;
-	second = m_ranger;
-	second_exec_flag = m_ranger->non_executable_edge_flag;
-      }
-     else
-      {
-	first = m_ranger;
-	first_exec_flag = m_ranger->non_executable_edge_flag;
-	second = &m_range_analyzer;
-	second_exec_flag = 0;
-      }
-    m_pta = new pointer_equiv_analyzer (m_ranger);
-  }
-
-  ~hybrid_folder ()
-  {
-    if (dump_file && (dump_flags & TDF_DETAILS))
-      m_ranger->dump (dump_file);
-
-    m_ranger->export_global_ranges ();
-    disable_ranger (cfun);
-    delete m_pta;
-  }
-
-  bool fold_stmt (gimple_stmt_iterator *gsi) override
-    {
-      simplifier.set_range_query (first, first_exec_flag);
-      if (simplifier.simplify (gsi))
-	return true;
-
-      simplifier.set_range_query (second, second_exec_flag);
-      if (simplifier.simplify (gsi))
-	{
-	  if (dump_file)
-	    fprintf (dump_file, "EVRP:hybrid: Second query simplifed stmt\n");
-	  return true;
-	}
-      return false;
-    }
-
-  void pre_fold_stmt (gimple *stmt) override
-  {
-    evrp_folder::pre_fold_stmt (stmt);
-    m_pta->visit_stmt (stmt);
-  }
-
-  void pre_fold_bb (basic_block bb) override
-  {
-    evrp_folder::pre_fold_bb (bb);
-    m_pta->enter (bb);
-  }
-
-  void post_fold_bb (basic_block bb) override
-  {
-    evrp_folder::post_fold_bb (bb);
-    m_pta->leave (bb);
-  }
-
-  tree value_of_expr (tree name, gimple *) override;
-  tree value_on_edge (edge, tree name) override;
-  tree value_of_stmt (gimple *, tree name) override;
-
-private:
-  DISABLE_COPY_AND_ASSIGN (hybrid_folder);
-  gimple_ranger *m_ranger;
-  range_query *first;
-  int first_exec_flag;
-  range_query *second;
-  int second_exec_flag;
-  pointer_equiv_analyzer *m_pta;
-  tree choose_value (tree evrp_val, tree ranger_val);
-};
-
-
-tree
-hybrid_folder::value_of_expr (tree op, gimple *stmt)
-{
-  tree evrp_ret = evrp_folder::value_of_expr (op, stmt);
-  tree ranger_ret;
-  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
-    ranger_ret = NULL;
-  else
-    {
-      ranger_ret = m_ranger->value_of_expr (op, stmt);
-      if (!ranger_ret && supported_pointer_equiv_p (op))
-	ranger_ret = m_pta->get_equiv (op);
-    }
-  return choose_value (evrp_ret, ranger_ret);
-}
-
-tree
-hybrid_folder::value_on_edge (edge e, tree op)
-{
-  // Call evrp::value_of_expr directly.  Otherwise another dual call is made
-  // via hybrid_folder::value_of_expr, but without an edge.
-  tree evrp_ret = evrp_folder::value_of_expr (op, NULL);
-  tree ranger_ret;
-  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
-    ranger_ret = NULL;
-  else
-    {
-      ranger_ret = m_ranger->value_on_edge (e, op);
-      if (!ranger_ret && supported_pointer_equiv_p (op))
-	ranger_ret = m_pta->get_equiv (op);
-    }
-  return choose_value (evrp_ret, ranger_ret);
-}
-
-tree
-hybrid_folder::value_of_stmt (gimple *stmt, tree op) 
-{
-  // Call evrp::value_of_expr directly.  Otherwise another dual call is made
-  // via hybrid_folder::value_of_expr, but without a stmt.
-  tree evrp_ret;
-  if (op)
-    evrp_ret = evrp_folder::value_of_expr (op, NULL);
-  else
-    evrp_ret = NULL_TREE;
-
-  tree ranger_ret;
-  if (op && TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
-    ranger_ret = NULL;
-  else
-    ranger_ret = m_ranger->value_of_stmt (stmt, op);
-  return choose_value (evrp_ret, ranger_ret);
-}
-
-// Given trees returned by EVRP and Ranger, choose/report the value to use
-// by the folder.
-
-tree
-hybrid_folder::choose_value (tree evrp_val, tree ranger_val)
-{
-  // If both found the same value, just return it.
-  if (evrp_val && ranger_val && !compare_values (evrp_val, ranger_val))
-    return evrp_val;
-
-  // If neither returned a value, return NULL_TREE.
-  if (!ranger_val && !evrp_val)
-    return NULL_TREE;
-
-  // Otherwise there is a discrepancy to flag.
-  if (dump_file)
-    {
-      if (evrp_val && ranger_val)
-	fprintf (dump_file, "EVRP:hybrid: Disagreement\n");
-      if (evrp_val)
-	{
-	  fprintf (dump_file, "EVRP:hybrid: EVRP found singleton ");
-	  print_generic_expr (dump_file, evrp_val);
-	  fprintf (dump_file, "\n");
-	}
-      if (ranger_val)
-	{
-	  fprintf (dump_file, "EVRP:hybrid: RVRP found singleton ");
-	  print_generic_expr (dump_file, ranger_val);
-	  fprintf (dump_file, "\n");
-	}
-    }
-
-  // If one value was found, return it.
-  if (!evrp_val)
-    return ranger_val;
-  if (!ranger_val)
-    return evrp_val;
-
-  // If values are different, return the first calculated value.
-  if (param_evrp_mode == EVRP_MODE_RVRP_FIRST)
-    return ranger_val;
-  return evrp_val;
-}
-
-/* Main entry point for the early vrp pass which is a simplified non-iterative
-   version of vrp where basic blocks are visited in dominance order.  Value
-   ranges discovered in early vrp will also be used by ipa-vrp.  */
-
-static unsigned int
-execute_early_vrp ()
-{
-  if (param_evrp_mode == EVRP_MODE_RVRP_ONLY)
-    return execute_ranger_vrp (cfun, false);
-
-  /* Ideally this setup code would move into the ctor for the folder
-     However, this setup can change the number of blocks which
-     invalidates the internal arrays that are set up by the dominator
-     walker in substitute_and_fold_engine.  */
-  loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
-  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
-  scev_initialize ();
-  calculate_dominance_info (CDI_DOMINATORS);
-
-  // Only the last 2 bits matter for choosing the folder.
-  switch (param_evrp_mode)
-    {
-    case EVRP_MODE_EVRP_ONLY:
-      {
-	evrp_folder folder;
-	folder.substitute_and_fold ();
-	break;
-      }
-    case EVRP_MODE_EVRP_FIRST:
-      {
-	hybrid_folder folder (true);
-	folder.substitute_and_fold ();
-	break;
-      }
-    case EVRP_MODE_RVRP_FIRST:
-      {
-	hybrid_folder folder (false);
-	folder.substitute_and_fold ();
-	break;
-      }
-    default:
-      gcc_unreachable ();
-    }
-
-  scev_finalize ();
-  loop_optimizer_finalize ();
-  return 0;
-}
-
-namespace {
-
-const pass_data pass_data_early_vrp =
-{
-  GIMPLE_PASS, /* type */
-  "evrp", /* name */
-  OPTGROUP_NONE, /* optinfo_flags */
-  TV_TREE_EARLY_VRP, /* tv_id */
-  PROP_ssa, /* properties_required */
-  0, /* properties_provided */
-  0, /* properties_destroyed */
-  0, /* todo_flags_start */
-  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
-};
-
-class pass_early_vrp : public gimple_opt_pass
-{
-public:
-  pass_early_vrp (gcc::context *ctxt)
-    : gimple_opt_pass (pass_data_early_vrp, ctxt)
-    {}
-
-  /* opt_pass methods: */
-  opt_pass * clone () { return new pass_early_vrp (m_ctxt); }
-  virtual bool gate (function *)
-    {
-      return flag_tree_vrp != 0;
-    }
-  virtual unsigned int execute (function *)
-    { return execute_early_vrp (); }
-
-}; // class pass_vrp
-} // anon namespace
-
-gimple_opt_pass *
-make_pass_early_vrp (gcc::context *ctxt)
-{
-  return new pass_early_vrp (ctxt);
-}
diff --git a/gcc/params.opt b/gcc/params.opt
index bcf1423671a..2f9c9cf27dd 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -134,25 +134,6 @@  Maximum number of basic blocks before EVRP uses a sparse cache.
 Common Joined UInteger Var(param_evrp_switch_limit) Init(50) Optimization Param
 Maximum number of outgoing edges in a switch before EVRP will not process it.
 
--param=evrp-mode=
-Common Joined Var(param_evrp_mode) Enum(evrp_mode) Init(EVRP_MODE_RVRP_ONLY) Param Optimization
---param=evrp-mode=[legacy|ranger|legacy-first|ranger-first] Specifies the mode Early VRP should operate in.
-
-Enum
-Name(evrp_mode) Type(enum evrp_mode) UnknownError(unknown evrp mode %qs)
-
-EnumValue
-Enum(evrp_mode) String(legacy) Value(EVRP_MODE_EVRP_ONLY)
-
-EnumValue
-Enum(evrp_mode) String(ranger) Value(EVRP_MODE_RVRP_ONLY)
-
-EnumValue
-Enum(evrp_mode) String(legacy-first) Value(EVRP_MODE_EVRP_FIRST)
-
-EnumValue
-Enum(evrp_mode) String(ranger-first) Value(EVRP_MODE_RVRP_FIRST)
-
 -param=fsm-scale-path-blocks=
 Common Joined UInteger Var(param_fsm_scale_path_blocks) Init(3) IntegerRange(1, 10) Param Optimization
 Scale factor to apply to the number of blocks in a threading path when comparing to the number of (scaled) statements.
diff --git a/gcc/testsuite/g++.dg/pr100774.C b/gcc/testsuite/g++.dg/pr100774.C
index 345fcfa0d01..63320ef73fc 100644
--- a/gcc/testsuite/g++.dg/pr100774.C
+++ b/gcc/testsuite/g++.dg/pr100774.C
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-forwprop --param=evrp-mode=ranger -fcompare-debug  " } */
+/* { dg-options "-O2 -fno-tree-forwprop -fcompare-debug  " } */
 
 extern void __attribute__((noreturn)) error();
 
diff --git a/gcc/testsuite/gcc.dg/pr100781.c b/gcc/testsuite/gcc.dg/pr100781.c
index c0e008a3ba5..96f0a7a6012 100644
--- a/gcc/testsuite/gcc.dg/pr100781.c
+++ b/gcc/testsuite/gcc.dg/pr100781.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 --param=evrp-mode=ranger -fcompare-debug  " } */
+/* { dg-options "-O2 -fcompare-debug  " } */
 
 struct a {
   int b;
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 30022dac108..7b4e2917340 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -4388,17 +4388,30 @@  const pass_data pass_data_vrp =
   ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */
 };
 
+const pass_data pass_data_early_vrp =
+{
+  GIMPLE_PASS, /* type */
+  "evrp", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_TREE_EARLY_VRP, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  ( TODO_cleanup_cfg | TODO_update_ssa | TODO_verify_all ),
+};
+
 static int vrp_pass_num = 0;
 class pass_vrp : public gimple_opt_pass
 {
 public:
-  pass_vrp (gcc::context *ctxt)
-    : gimple_opt_pass (pass_data_vrp, ctxt), warn_array_bounds_p (false),
-      my_pass (++vrp_pass_num)
+  pass_vrp (gcc::context *ctxt, const pass_data &data_)
+    : gimple_opt_pass (data_, ctxt), data (data_), warn_array_bounds_p (false),
+      my_pass (vrp_pass_num++)
   {}
 
   /* opt_pass methods: */
-  opt_pass * clone () { return new pass_vrp (m_ctxt); }
+  opt_pass * clone () { return new pass_vrp (m_ctxt, data); }
   void set_pass_param (unsigned int n, bool param)
     {
       gcc_assert (n == 0);
@@ -4407,6 +4420,10 @@  public:
   virtual bool gate (function *) { return flag_tree_vrp != 0; }
   virtual unsigned int execute (function *fun)
     {
+      // Early VRP pass.
+      if (my_pass == 0)
+	return execute_ranger_vrp (fun, /*warn_array_bounds_p=*/false);
+
       if ((my_pass == 1 && param_vrp1_mode == VRP_MODE_RANGER)
 	  || (my_pass == 2 && param_vrp2_mode == VRP_MODE_RANGER))
 	return execute_ranger_vrp (fun, warn_array_bounds_p);
@@ -4414,6 +4431,7 @@  public:
     }
 
  private:
+  const pass_data &data;
   bool warn_array_bounds_p;
   int my_pass;
 }; // class pass_vrp
@@ -4423,5 +4441,11 @@  public:
 gimple_opt_pass *
 make_pass_vrp (gcc::context *ctxt)
 {
-  return new pass_vrp (ctxt);
+  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);
 }