public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-1327] Remove legacy EVRP code.
@ 2022-06-28 12:43 Aldy Hernandez
  0 siblings, 0 replies; only message in thread
From: Aldy Hernandez @ 2022-06-28 12:43 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:243b5396106c4b1eb813fd06c2bc6f0a3009bae8

commit r13-1327-g243b5396106c4b1eb813fd06c2bc6f0a3009bae8
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Mon Jun 27 18:40:23 2022 +0200

    Remove legacy EVRP code.
    
    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.
    
    Tested on x86-64 Linux.
    
    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/testsuite/ChangeLog:
    
            * g++.dg/pr100774.C: Remove --param=evrp-mode.
            * gcc.dg/pr100781.c: Same.

Diff:
---
 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(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 57edc47fc0c..a82909dafe5 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1417,8 +1417,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 793a3ea1f19..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 () final override { return new pass_early_vrp (m_ctxt); }
-  bool gate (function *) final override
-    {
-      return flag_tree_vrp != 0;
-    }
-  unsigned int execute (function *) final override
-    { 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 ef7978da234..2d15bb5a650 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 () final override { return new pass_vrp (m_ctxt); }
+  opt_pass * clone () final override { return new pass_vrp (m_ctxt, data); }
   void set_pass_param (unsigned int n, bool param) final override
     {
       gcc_assert (n == 0);
@@ -4407,6 +4420,10 @@ public:
   bool gate (function *) final override { return flag_tree_vrp != 0; }
   unsigned int execute (function *fun) final override
     {
+      // 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);
 }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-28 12:43 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-28 12:43 [gcc r13-1327] Remove legacy EVRP code Aldy Hernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).