We already moved the value_range class into its own class in the last release. I think it's time to move the value_range_equiv stuff into its own class, as it's a distraction from the VRP code.

I've moved it to value-range-equiv.*, and gave it a semblance of order, by putting the constructors and setters at the beginning, the dumpers at the bottom, etc.

No functional changes.

OK for mainline?
Aldy
commit 10bcfd4659a32b1ef31eaa48f866311d53445de6
Author: Aldy Hernandez <al...@redhat.com>
Date:   Sun May 17 14:55:51 2020 +0200

    Move value_range_equiv code to its own file.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 9ba21f735f6..711d1fe308e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1641,6 +1641,7 @@ OBJS = \
 	unique-ptr-tests.o \
 	valtrack.o \
 	value-range.o \
+	value-range-equiv.o \
 	value-prof.o \
 	var-tracking.o \
 	varasm.o \
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 4b5df543c00..953ca508fa2 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -67,6 +67,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "vr-values.h"
 #include "builtins.h"
 #include "range-op.h"
+#include "value-range-equiv.h"
 
 /* Set of SSA names found live during the RPO traversal of the function
    for still active basic-blocks.  */
@@ -309,210 +310,6 @@ private:
 							const void *);
 };
 
-void
-value_range_equiv::set_equiv (bitmap equiv)
-{
-  if (undefined_p () || varying_p ())
-    equiv = NULL;
-  /* Since updating the equivalence set involves deep copying the
-     bitmaps, only do it if absolutely necessary.
-
-     All equivalence bitmaps are allocated from the same obstack.  So
-     we can use the obstack associated with EQUIV to allocate vr->equiv.  */
-  if (m_equiv == NULL
-      && equiv != NULL)
-    m_equiv = BITMAP_ALLOC (equiv->obstack);
-
-  if (equiv != m_equiv)
-    {
-      if (equiv && !bitmap_empty_p (equiv))
-	bitmap_copy (m_equiv, equiv);
-      else
-	bitmap_clear (m_equiv);
-    }
-}
-
-/* Initialize value_range.  */
-
-void
-value_range_equiv::set (tree min, tree max, bitmap equiv,
-			value_range_kind kind)
-{
-  value_range::set (min, max, kind);
-  set_equiv (equiv);
-  if (flag_checking)
-    check ();
-}
-
-value_range_equiv::value_range_equiv (tree min, tree max, bitmap equiv,
-				      value_range_kind kind)
-{
-  m_equiv = NULL;
-  set (min, max, equiv, kind);
-}
-
-value_range_equiv::value_range_equiv (const value_range &other)
-{
-  m_equiv = NULL;
-  set (other.min(), other.max (), NULL, other.kind ());
-}
-
-/* Like set, but keep the equivalences in place.  */
-
-void
-value_range_equiv::update (tree min, tree max, value_range_kind kind)
-{
-  set (min, max,
-       (kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL, kind);
-}
-
-/* Copy value_range in FROM into THIS while avoiding bitmap sharing.
-
-   Note: The code that avoids the bitmap sharing looks at the existing
-   this->m_equiv, so this function cannot be used to initalize an
-   object.  Use the constructors for initialization.  */
-
-void
-value_range_equiv::deep_copy (const value_range_equiv *from)
-{
-  set (from->min (), from->max (), from->m_equiv, from->m_kind);
-}
-
-void
-value_range_equiv::move (value_range_equiv *from)
-{
-  set (from->min (), from->max (), NULL, from->m_kind);
-  m_equiv = from->m_equiv;
-  from->m_equiv = NULL;
-}
-
-void
-value_range_equiv::check ()
-{
-  value_range::check ();
-  switch (m_kind)
-    {
-    case VR_UNDEFINED:
-    case VR_VARYING:
-      gcc_assert (!m_equiv || bitmap_empty_p (m_equiv));
-    default:;
-    }
-}
-
-/* Return true if the bitmaps B1 and B2 are equal.  */
-
-static bool
-vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
-{
-  return (b1 == b2
-	  || ((!b1 || bitmap_empty_p (b1))
-	      && (!b2 || bitmap_empty_p (b2)))
-	  || (b1 && b2
-	      && bitmap_equal_p (b1, b2)));
-}
-
-/* Returns TRUE if THIS == OTHER.  Ignores the equivalence bitmap if
-   IGNORE_EQUIVS is TRUE.  */
-
-bool
-value_range_equiv::equal_p (const value_range_equiv &other,
-			    bool ignore_equivs) const
-{
-  return (value_range::equal_p (other)
-	  && (ignore_equivs
-	      || vrp_bitmap_equal_p (m_equiv, other.m_equiv)));
-}
-
-void
-value_range_equiv::set_undefined ()
-{
-  set (NULL, NULL, NULL, VR_UNDEFINED);
-}
-
-void
-value_range_equiv::set_varying (tree type)
-{
-  value_range::set_varying (type);
-  equiv_clear ();
-}
-
-void
-value_range_equiv::equiv_clear ()
-{
-  if (m_equiv)
-    bitmap_clear (m_equiv);
-}
-
-/* Add VAR and VAR's equivalence set (VAR_VR) to the equivalence
-   bitmap.  If no equivalence table has been created, OBSTACK is the
-   obstack to use (NULL for the default obstack).
-
-   This is the central point where equivalence processing can be
-   turned on/off.  */
-
-void
-value_range_equiv::equiv_add (const_tree var,
-			      const value_range_equiv *var_vr,
-			      bitmap_obstack *obstack)
-{
-  if (!m_equiv)
-    m_equiv = BITMAP_ALLOC (obstack);
-  unsigned ver = SSA_NAME_VERSION (var);
-  bitmap_set_bit (m_equiv, ver);
-  if (var_vr && var_vr->m_equiv)
-    bitmap_ior_into (m_equiv, var_vr->m_equiv);
-}
-
-void
-value_range_equiv::dump (FILE *file) const
-{
-  value_range::dump (file);
-  if ((m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
-      && m_equiv)
-    {
-      bitmap_iterator bi;
-      unsigned i, c = 0;
-
-      fprintf (file, "  EQUIVALENCES: { ");
-
-      EXECUTE_IF_SET_IN_BITMAP (m_equiv, 0, i, bi)
-	{
-	  print_generic_expr (file, ssa_name (i));
-	  fprintf (file, " ");
-	  c++;
-	}
-
-      fprintf (file, "} (%u elements)", c);
-    }
-}
-
-void
-value_range_equiv::dump () const
-{
-  dump (stderr);
-}
-
-void
-dump_value_range (FILE *file, const value_range_equiv *vr)
-{
-  if (!vr)
-    fprintf (file, "[]");
-  else
-    vr->dump (file);
-}
-
-DEBUG_FUNCTION void
-debug (const value_range_equiv *vr)
-{
-  dump_value_range (stderr, vr);
-}
-
-DEBUG_FUNCTION void
-debug (const value_range_equiv &vr)
-{
-  dump_value_range (stderr, &vr);
-}
-
 /* Return true if the SSA name NAME is live on the edge E.  */
 
 bool
@@ -594,15 +391,6 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type,
   return vr_type;
 }
 
-void
-value_range_equiv::set (tree val)
-{
-  gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
-  if (TREE_OVERFLOW_P (val))
-    val = drop_tree_overflow (val);
-  set (val, val);
-}
-
 /* Return true if max and min of VR are INTEGER_CST.  It's not necessary
    a singleton.  */
 
@@ -4811,92 +4599,6 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
   return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
 }
 
-void
-value_range_equiv::intersect (const value_range_equiv *other)
-{
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "Intersecting\n  ");
-      dump_value_range (dump_file, this);
-      fprintf (dump_file, "\nand\n  ");
-      dump_value_range (dump_file, other);
-      fprintf (dump_file, "\n");
-    }
-
-  /* If THIS is varying we want to pick up equivalences from OTHER.
-     Just special-case this here rather than trying to fixup after the
-     fact.  */
-  if (this->varying_p ())
-    this->deep_copy (other);
-  else
-    {
-      value_range tem = intersect_helper (this, other);
-      this->update (tem.min (), tem.max (), tem.kind ());
-
-      /* If the result is VR_UNDEFINED there is no need to mess with
-	 equivalencies.  */
-      if (!undefined_p ())
-	{
-	  /* The resulting set of equivalences for range intersection
-	     is the union of the two sets.  */
-	  if (m_equiv && other->m_equiv && m_equiv != other->m_equiv)
-	    bitmap_ior_into (m_equiv, other->m_equiv);
-	  else if (other->m_equiv && !m_equiv)
-	    {
-	      /* All equivalence bitmaps are allocated from the same
-		 obstack.  So we can use the obstack associated with
-		 VR to allocate this->m_equiv.  */
-	      m_equiv = BITMAP_ALLOC (other->m_equiv->obstack);
-	      bitmap_copy (m_equiv, other->m_equiv);
-	    }
-	}
-    }
-
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "to\n  ");
-      dump_value_range (dump_file, this);
-      fprintf (dump_file, "\n");
-    }
-}
-
-void
-value_range_equiv::union_ (const value_range_equiv *other)
-{
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "Meeting\n  ");
-      dump_value_range (dump_file, this);
-      fprintf (dump_file, "\nand\n  ");
-      dump_value_range (dump_file, other);
-      fprintf (dump_file, "\n");
-    }
-
-  /* If THIS is undefined we want to pick up equivalences from OTHER.
-     Just special-case this here rather than trying to fixup after the fact.  */
-  if (this->undefined_p ())
-    this->deep_copy (other);
-  else
-    {
-      value_range tem = union_helper (this, other);
-      this->update (tem.min (), tem.max (), tem.kind ());
-
-      /* The resulting set of equivalences is always the intersection of
-	 the two sets.  */
-      if (this->m_equiv && other->m_equiv && this->m_equiv != other->m_equiv)
-	bitmap_and_into (this->m_equiv, other->m_equiv);
-      else if (this->m_equiv && !other->m_equiv)
-	bitmap_clear (this->m_equiv);
-    }
-
-  if (dump_file && (dump_flags & TDF_DETAILS))
-    {
-      fprintf (dump_file, "to\n  ");
-      dump_value_range (dump_file, this);
-      fprintf (dump_file, "\n");
-    }
-}
-
 /* Visit all arguments for PHI node PHI that flow through executable
    edges.  If a valid value range can be derived from all the incoming
    value ranges, set a new range for the LHS of PHI.  */
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index aa8201f7359..b3d187ffdf1 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -22,76 +22,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "value-range.h"
 
-/* Note value_range_equiv cannot currently be used with GC memory,
-   only value_range is fully set up for this.  */
-class GTY((user)) value_range_equiv : public value_range
-{
- public:
-  value_range_equiv ();
-  value_range_equiv (const value_range &);
-  /* Deep-copies equiv bitmap argument.  */
-  value_range_equiv (tree, tree, bitmap = NULL, value_range_kind = VR_RANGE);
-
-  /* Shallow-copies equiv bitmap.  */
-  value_range_equiv (const value_range_equiv &) /* = delete */;
-  /* Shallow-copies equiv bitmap.  */
-  value_range_equiv& operator=(const value_range_equiv &) /* = delete */;
-
-  /* Move equiv bitmap from source range.  */
-  void move (value_range_equiv *);
-
-  /* Leaves equiv bitmap alone.  */
-  void update (tree, tree, value_range_kind = VR_RANGE);
-  /* Deep-copies equiv bitmap argument.  */
-  void set (tree, tree, bitmap = NULL, value_range_kind = VR_RANGE);
-  void set (tree);
-
-  bool operator== (const value_range_equiv &) const /* = delete */;
-  bool operator!= (const value_range_equiv &) const /* = delete */;
-  void intersect (const value_range_equiv *);
-  void union_ (const value_range_equiv *);
-  bool equal_p (const value_range_equiv &, bool ignore_equivs) const;
-
-  /* Types of value ranges.  */
-  void set_undefined ();
-  void set_varying (tree);
-
-  /* Equivalence bitmap methods.  */
-  bitmap equiv () const;
-  void equiv_clear ();
-  void equiv_add (const_tree, const value_range_equiv *,
-		  bitmap_obstack * = NULL);
-
-  /* Misc methods.  */
-  void deep_copy (const value_range_equiv *);
-  void dump (FILE *) const;
-  void dump () const;
-
- private:
-  /* Deep-copies bitmap argument.  */
-  void set_equiv (bitmap);
-  void check ();
-
-  /* Set of SSA names whose value ranges are equivalent to this one.
-     This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
-  bitmap m_equiv;
-};
-
-inline
-value_range_equiv::value_range_equiv ()
-  : value_range ()
-{
-  m_equiv = NULL;
-}
-
-inline bitmap
-value_range_equiv::equiv () const
-{
-  return m_equiv;
-}
-
-extern void dump_value_range (FILE *, const value_range_equiv *);
-
 struct assert_info
 {
   /* Predicate code for the ASSERT_EXPR.  Must be COMPARISON_CLASS_P.  */
diff --git a/gcc/value-range-equiv.cc b/gcc/value-range-equiv.cc
new file mode 100644
index 00000000000..24132e3546e
--- /dev/null
+++ b/gcc/value-range-equiv.cc
@@ -0,0 +1,322 @@
+/* Support routines for value ranges with equivalences.
+   Copyright (C) 2020 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 "ssa.h"
+#include "tree-pretty-print.h"
+#include "value-range-equiv.h"
+
+value_range_equiv::value_range_equiv (tree min, tree max, bitmap equiv,
+				      value_range_kind kind)
+{
+  m_equiv = NULL;
+  set (min, max, equiv, kind);
+}
+
+value_range_equiv::value_range_equiv (const value_range &other)
+{
+  m_equiv = NULL;
+  set (other.min(), other.max (), NULL, other.kind ());
+}
+
+void
+value_range_equiv::set (tree min, tree max, bitmap equiv,
+			value_range_kind kind)
+{
+  value_range::set (min, max, kind);
+  set_equiv (equiv);
+  if (flag_checking)
+    check ();
+}
+
+void
+value_range_equiv::set (tree val)
+{
+  gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
+  if (TREE_OVERFLOW_P (val))
+    val = drop_tree_overflow (val);
+  set (val, val);
+}
+
+void
+value_range_equiv::set_undefined ()
+{
+  set (NULL, NULL, NULL, VR_UNDEFINED);
+}
+
+void
+value_range_equiv::set_varying (tree type)
+{
+  value_range::set_varying (type);
+  equiv_clear ();
+}
+
+/* Like set, but keep the equivalences in place.  */
+
+void
+value_range_equiv::update (tree min, tree max, value_range_kind kind)
+{
+  set (min, max,
+       (kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL, kind);
+}
+
+/* Copy value_range in FROM into THIS while avoiding bitmap sharing.
+
+   Note: The code that avoids the bitmap sharing looks at the existing
+   this->m_equiv, so this function cannot be used to initalize an
+   object.  Use the constructors for initialization.  */
+
+void
+value_range_equiv::deep_copy (const value_range_equiv *from)
+{
+  set (from->min (), from->max (), from->m_equiv, from->m_kind);
+}
+
+void
+value_range_equiv::move (value_range_equiv *from)
+{
+  set (from->min (), from->max (), NULL, from->m_kind);
+  m_equiv = from->m_equiv;
+  from->m_equiv = NULL;
+}
+
+void
+value_range_equiv::set_equiv (bitmap equiv)
+{
+  if (undefined_p () || varying_p ())
+    equiv = NULL;
+  /* Since updating the equivalence set involves deep copying the
+     bitmaps, only do it if absolutely necessary.
+
+     All equivalence bitmaps are allocated from the same obstack.  So
+     we can use the obstack associated with EQUIV to allocate vr->equiv.  */
+  if (m_equiv == NULL
+      && equiv != NULL)
+    m_equiv = BITMAP_ALLOC (equiv->obstack);
+
+  if (equiv != m_equiv)
+    {
+      if (equiv && !bitmap_empty_p (equiv))
+	bitmap_copy (m_equiv, equiv);
+      else
+	bitmap_clear (m_equiv);
+    }
+}
+
+void
+value_range_equiv::check ()
+{
+  value_range::check ();
+  switch (m_kind)
+    {
+    case VR_UNDEFINED:
+    case VR_VARYING:
+      gcc_assert (!m_equiv || bitmap_empty_p (m_equiv));
+    default:;
+    }
+}
+
+/* Return true if the bitmaps B1 and B2 are equal.  */
+
+static bool
+vr_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
+{
+  return (b1 == b2
+	  || ((!b1 || bitmap_empty_p (b1))
+	      && (!b2 || bitmap_empty_p (b2)))
+	  || (b1 && b2
+	      && bitmap_equal_p (b1, b2)));
+}
+
+/* Returns TRUE if THIS == OTHER.  Ignores the equivalence bitmap if
+   IGNORE_EQUIVS is TRUE.  */
+
+bool
+value_range_equiv::equal_p (const value_range_equiv &other,
+			    bool ignore_equivs) const
+{
+  return (value_range::equal_p (other)
+	  && (ignore_equivs || vr_bitmap_equal_p (m_equiv, other.m_equiv)));
+}
+
+void
+value_range_equiv::equiv_clear ()
+{
+  if (m_equiv)
+    bitmap_clear (m_equiv);
+}
+
+/* Add VAR and VAR's equivalence set (VAR_VR) to the equivalence
+   bitmap.  If no equivalence table has been created, OBSTACK is the
+   obstack to use (NULL for the default obstack).
+
+   This is the central point where equivalence processing can be
+   turned on/off.  */
+
+void
+value_range_equiv::equiv_add (const_tree var,
+			      const value_range_equiv *var_vr,
+			      bitmap_obstack *obstack)
+{
+  if (!m_equiv)
+    m_equiv = BITMAP_ALLOC (obstack);
+  unsigned ver = SSA_NAME_VERSION (var);
+  bitmap_set_bit (m_equiv, ver);
+  if (var_vr && var_vr->m_equiv)
+    bitmap_ior_into (m_equiv, var_vr->m_equiv);
+}
+
+void
+value_range_equiv::intersect (const value_range_equiv *other)
+{
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Intersecting\n  ");
+      dump_value_range (dump_file, this);
+      fprintf (dump_file, "\nand\n  ");
+      dump_value_range (dump_file, other);
+      fprintf (dump_file, "\n");
+    }
+
+  /* If THIS is varying we want to pick up equivalences from OTHER.
+     Just special-case this here rather than trying to fixup after the
+     fact.  */
+  if (this->varying_p ())
+    this->deep_copy (other);
+  else
+    {
+      value_range tem = intersect_helper (this, other);
+      this->update (tem.min (), tem.max (), tem.kind ());
+
+      /* If the result is VR_UNDEFINED there is no need to mess with
+	 equivalencies.  */
+      if (!undefined_p ())
+	{
+	  /* The resulting set of equivalences for range intersection
+	     is the union of the two sets.  */
+	  if (m_equiv && other->m_equiv && m_equiv != other->m_equiv)
+	    bitmap_ior_into (m_equiv, other->m_equiv);
+	  else if (other->m_equiv && !m_equiv)
+	    {
+	      /* All equivalence bitmaps are allocated from the same
+		 obstack.  So we can use the obstack associated with
+		 VR to allocate this->m_equiv.  */
+	      m_equiv = BITMAP_ALLOC (other->m_equiv->obstack);
+	      bitmap_copy (m_equiv, other->m_equiv);
+	    }
+	}
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "to\n  ");
+      dump_value_range (dump_file, this);
+      fprintf (dump_file, "\n");
+    }
+}
+
+void
+value_range_equiv::union_ (const value_range_equiv *other)
+{
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Meeting\n  ");
+      dump_value_range (dump_file, this);
+      fprintf (dump_file, "\nand\n  ");
+      dump_value_range (dump_file, other);
+      fprintf (dump_file, "\n");
+    }
+
+  /* If THIS is undefined we want to pick up equivalences from OTHER.
+     Just special-case this here rather than trying to fixup after the fact.  */
+  if (this->undefined_p ())
+    this->deep_copy (other);
+  else
+    {
+      value_range tem = union_helper (this, other);
+      this->update (tem.min (), tem.max (), tem.kind ());
+
+      /* The resulting set of equivalences is always the intersection of
+	 the two sets.  */
+      if (this->m_equiv && other->m_equiv && this->m_equiv != other->m_equiv)
+	bitmap_and_into (this->m_equiv, other->m_equiv);
+      else if (this->m_equiv && !other->m_equiv)
+	bitmap_clear (this->m_equiv);
+    }
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "to\n  ");
+      dump_value_range (dump_file, this);
+      fprintf (dump_file, "\n");
+    }
+}
+
+void
+value_range_equiv::dump (FILE *file) const
+{
+  value_range::dump (file);
+  if ((m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
+      && m_equiv)
+    {
+      bitmap_iterator bi;
+      unsigned i, c = 0;
+
+      fprintf (file, "  EQUIVALENCES: { ");
+      EXECUTE_IF_SET_IN_BITMAP (m_equiv, 0, i, bi)
+	{
+	  print_generic_expr (file, ssa_name (i));
+	  fprintf (file, " ");
+	  c++;
+	}
+      fprintf (file, "} (%u elements)", c);
+    }
+}
+
+void
+value_range_equiv::dump () const
+{
+  dump (stderr);
+}
+
+void
+dump_value_range (FILE *file, const value_range_equiv *vr)
+{
+  if (!vr)
+    fprintf (file, "[]");
+  else
+    vr->dump (file);
+}
+
+DEBUG_FUNCTION void
+debug (const value_range_equiv *vr)
+{
+  dump_value_range (stderr, vr);
+}
+
+DEBUG_FUNCTION void
+debug (const value_range_equiv &vr)
+{
+  dump_value_range (stderr, &vr);
+}
diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h
new file mode 100644
index 00000000000..274221226e6
--- /dev/null
+++ b/gcc/value-range-equiv.h
@@ -0,0 +1,82 @@
+/* Support routines for value ranges with equivalences.
+   Copyright (C) 2020 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_VALUE_RANGE_EQUIV_H
+#define GCC_VALUE_RANGE_EQUIV_H
+
+#include "value-range.h"
+
+/* Note value_range_equiv cannot currently be used with GC memory,
+   only value_range is fully set up for this.  */
+class GTY((user)) value_range_equiv : public value_range
+{
+ public:
+  value_range_equiv () : value_range () { m_equiv = NULL; }
+  value_range_equiv (const value_range &);
+  /* Deep-copies equiv bitmap argument.  */
+  value_range_equiv (tree, tree, bitmap = NULL, value_range_kind = VR_RANGE);
+
+  /* Shallow-copies equiv bitmap.  */
+  value_range_equiv (const value_range_equiv &) /* = delete */;
+  /* Shallow-copies equiv bitmap.  */
+  value_range_equiv& operator=(const value_range_equiv &) /* = delete */;
+
+  /* Move equiv bitmap from source range.  */
+  void move (value_range_equiv *);
+
+  /* Leaves equiv bitmap alone.  */
+  void update (tree, tree, value_range_kind = VR_RANGE);
+  /* Deep-copies equiv bitmap argument.  */
+  void set (tree, tree, bitmap = NULL, value_range_kind = VR_RANGE);
+  void set (tree);
+
+  bool operator== (const value_range_equiv &) const /* = delete */;
+  bool operator!= (const value_range_equiv &) const /* = delete */;
+  void intersect (const value_range_equiv *);
+  void union_ (const value_range_equiv *);
+  bool equal_p (const value_range_equiv &, bool ignore_equivs) const;
+
+  /* Types of value ranges.  */
+  void set_undefined ();
+  void set_varying (tree);
+
+  /* Equivalence bitmap methods.  */
+  bitmap equiv () const { return m_equiv; }
+  void equiv_clear ();
+  void equiv_add (const_tree, const value_range_equiv *,
+		  bitmap_obstack * = NULL);
+
+  /* Misc methods.  */
+  void deep_copy (const value_range_equiv *);
+  void dump (FILE *) const;
+  void dump () const;
+
+ private:
+  /* Deep-copies bitmap argument.  */
+  void set_equiv (bitmap);
+  void check ();
+
+  /* Set of SSA names whose value ranges are equivalent to this one.
+     This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
+  bitmap m_equiv;
+};
+
+extern void dump_value_range (FILE *, const value_range_equiv *);
+
+#endif // GCC_VALUE_RANGE_EQUIV_H
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index b4ab4e6f5b8..cfe4f64809e 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_VR_VALUES_H
 #define GCC_VR_VALUES_H
 
+#include "value-range-equiv.h"
+
 /* The VR_VALUES class holds the current view of range information
    for all the SSA_NAMEs in the IL.
 

Reply via email to