[PATCH] [frange] Rewrite union to merge sub-ranges.

Aldy Hernandez <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Replace the single-interval union_ with a sub-range aware one.

Like the intersect rewrite, do this ahead of raising MAX_PAIRS.  It is
still 1, so set_pairs collapses the result back to a single range.  No
functional change.

Tested on ppc64le: regstrap, LAPACK, no changes on a corpus of Fortran
files.

Pushed.

gcc/ChangeLog:

	* value-range.cc (frange::union_): Merge both operands' sub-ranges
	via set_pairs instead of widening to the hull.
---
 gcc/value-range.cc | 39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 472ff37a1df..18aa82733a4 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1324,29 +1324,26 @@ frange::union_ (const vrange &v)
   // Combine NAN info.
   if (known_isnan () || r.known_isnan ())
     return union_nans (r);
-  bool changed = false;
-  if (m_pos_nan != r.m_pos_nan || m_neg_nan != r.m_neg_nan)
-    {
-      m_pos_nan |= r.m_pos_nan;
-      m_neg_nan |= r.m_neg_nan;
-      changed = true;
-    }
 
-  // FIXME: Rewrite for sub-ranges.
-  // Combine endpoints.  This needs to be rewritten for sub-ranges.
-  if (frange_cmp (r.m_pairs[0].min, m_pairs[0].min) < 0)
-    {
-      m_pairs[0].min = r.m_pairs[0].min;
-      changed = true;
-    }
-  if (frange_cmp (m_pairs[0].max, r.m_pairs[0].max) < 0)
-    {
-      m_pairs[0].max = r.m_pairs[0].max;
-      changed = true;
-    }
+  frange save = *this;
+  m_pos_nan |= r.m_pos_nan;
+  m_neg_nan |= r.m_neg_nan;
 
-  changed |= normalize_kind ();
-  return changed;
+  // Throw both operands' sub-ranges into the pot as set_pairs will
+  // canonicalize things and hand us back at most MAX_PAIRS.
+  //
+  // NOTE: Both operands are already sorted and disjoint, so a merge could
+  // combine them in O(n) like irange::union_ rather than have set_pairs
+  // re-sort.  Not worth it while MAX_PAIRS is tiny; revisit if it grows.
+  frange_pair pairs[2 * MAX_PAIRS];
+  unsigned n = 0;
+  for (unsigned i = 0; i < save.m_num_ranges; ++i)
+    pairs[n++] = save.m_pairs[i];
+  for (unsigned i = 0; i < r.m_num_ranges; ++i)
+    pairs[n++] = r.m_pairs[i];
+
+  set_pairs (pairs, n);
+  return *this != save;
 }
 
 // Intersect two ranges when one is known to be a NAN.
-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.