• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GCC with patches for OS216


Commit MetaInfo

Revision7ce6c8b321a7d6243a2bdecc4de7c64fca4f211a (tree)
Time2018-04-03 05:51:26
AuthorAndrew Macleod <amacleod@gcc....>
CommiterAndrew Macleod

Log Message

Rewrite range union

From-SVN: r259017

Change Summary

Incremental Difference

--- a/gcc/range.c
+++ b/gcc/range.c
@@ -563,135 +563,8 @@ irange::union_ (const wide_int &x, const wide_int &y)
563563 gcc_assert (!CHECKING_P || valid_p ());
564564 return *this;
565565 }
566-
567- /* If [X,Y] comes before, put it at the front. */
568- if (wi::lt_p (y, bounds[0], TYPE_SIGN (type)))
569- {
570- prepend (x, y);
571- gcc_assert (!CHECKING_P || valid_p ());
572- return *this;
573- }
574- /* If [X,Y] comes after, put it at the end. */
575- if (wi::gt_p (x, bounds[nitems - 1], TYPE_SIGN (type)))
576- {
577- append (x, y);
578- gcc_assert (!CHECKING_P || valid_p ());
579- return *this;
580- }
581- /* Handle [X,Y] swalling up all of THIS. */
582- if (wi::le_p (x, bounds[0], TYPE_SIGN (type))
583- && wi::ge_p (y, bounds[nitems - 1], TYPE_SIGN (type)))
584- {
585- bounds[0] = x;
586- bounds[1] = y;
587- nitems = 2;
588- gcc_assert (!CHECKING_P || valid_p ());
589- return *this;
590- }
591- /* Handle X starting before, while Y is within.
592- Y
593- X[a,b][c,d][e,f][g,h][i,j]
594- ==> [X,Y][g,h][i,j]. */
595- if (wi::lt_p (x, bounds[0], TYPE_SIGN (type)))
596- {
597- bounds[0] = x;
598-
599- /* Y
600- X[a,b] => [X,b]. */
601- if (nitems == 2)
602- {
603- gcc_assert (!CHECKING_P || valid_p ());
604- return *this;
605- }
606-
607- for (unsigned i = 1; i < nitems; i += 2)
608- if (wi::le_p (y, bounds[i], TYPE_SIGN (type)))
609- {
610- if (y == bounds[i])
611- bounds[1] = y;
612- else
613- bounds[1] = bounds[i];
614- if (i >= 2)
615- remove (2, i);
616- gcc_assert (!CHECKING_P || valid_p ());
617- return *this;
618- }
619- gcc_unreachable ();
620- }
621- /* Handle Y being outside, while X is within.
622- X Y
623- [a,b][c,d][e,f][g,h][i,j]
624- ==> [a,b][c,d][e,Y]. */
625- if (wi::gt_p (y, bounds[nitems - 1], TYPE_SIGN (type)))
626- {
627- for (unsigned i = 0; i < nitems; i += 2)
628- if (wi::ge_p (bounds[i + 1], x, TYPE_SIGN (type)))
629- {
630- bounds[i + 1] = y;
631- nitems = i + 2;
632- return *this;
633- }
634- gcc_unreachable ();
635- }
636-
637- /* At this point, [X,Y] must be completely inside.
638- X Y
639- [a,b][c,d][e,f][g,h]. */
640- gcc_assert (wi::ge_p (x, bounds[0], TYPE_SIGN (type))
641- && wi::le_p (y, bounds[nitems - 1], TYPE_SIGN (type)));
642-
643- /* Find X. */
644- gcc_assert (nitems >= 2);
645- unsigned xpos = ~0U;
646- unsigned i = nitems;
647- do
648- {
649- i -= 2;
650- if (wi::ge_p (x, bounds[i], TYPE_SIGN (type)))
651- {
652- xpos = i;
653- break;
654- }
655- }
656- while (i);
657- gcc_assert (xpos != ~0U);
658-
659- /* Handle [X,Y] fitting between two sub-ranges:
660-
661- [a,b][X,Y][b,c]. */
662- if (nitems < max_pairs * 2
663- && wi::gt_p (x, bounds[xpos + 1], TYPE_SIGN (type))
664- && wi::lt_p (y, bounds[xpos + 2], TYPE_SIGN (type)))
665- {
666- insert (x, y, xpos + 2);
667- gcc_assert (!CHECKING_P || valid_p ());
668- return *this;
669- }
670-
671- /* Find Y. */
672- unsigned ypos = ~0U;
673- for (i = 1; i < nitems; i += 2)
674- if (wi::le_p (y, bounds[i], TYPE_SIGN (type)))
675- {
676- ypos = i;
677- break;
678- }
679- gcc_assert (ypos != ~0U);
680-
681- /* If [x,y] is inside of subrange [xpos,ypos], there's nothing to do. */
682- if (xpos + 1 == ypos)
683- {
684- gcc_assert (!CHECKING_P || valid_p ());
685- return *this;
686- }
687-
688- /* Squash the sub-ranges in between xpos and ypos. */
689- wide_int tmp = bounds[ypos];
690- remove (xpos + 2, ypos);
691- bounds[xpos + 1] = tmp;
692-
693- gcc_assert (!CHECKING_P || valid_p ());
694- return *this;
566+ irange tmp (type, x, y);
567+ return union_ (tmp);
695568 }
696569
697570 // THIS = THIS U R
@@ -709,19 +582,102 @@ irange::union_ (const irange &r)
709582 else if (r.empty_p ())
710583 return *this;
711584
712- /* FIXME: It would be nice to look at both THIS and R as a whole and
713- optimize the case where they don't overlap and be easily appended
714- or prepended. That is, do the calculation in this function
715- instead of doing it piecemeal below.
585+ // Build a union of 2 ranges here. Make sure we dont have to worry about
586+ // merging and such by reserving twice as many pairs as needed, and simply
587+ // sort the 2 ranges into this intermediate form.
588+ // THe intermediate result will have the property that the beginning of
589+ // each range is <= the beginning of the next range
590+ // There may be overlapping ranges at this point.
591+ // ie this would be valid
592+ // [ -20, 10], [-10, 0], [0, 20], [40, 90]
593+ // as it satidfies this contraint : -20 < -10 < 0 < 40
594+ // WHen the range is rebuilt into r, the merge is performed.
595+ //
596+ // [Xi,Yi]..[Xn,Yn] U [Xj,Yj]..[Xm,Ym] --> [Xk,Yk]..[Xp,Yp]
597+
598+ signop sign = TYPE_SIGN (type);
599+ wide_int res[max_pairs * 4];
600+ wide_int u1 ;
601+ bool ovf;
602+ unsigned i = 0, j = 0, k = 0;
716603
717- For example: [8,10][14,14] U [135,255]. */
718- for (unsigned i = 0; i < r.nitems; i += 2)
719- union_ (r.bounds[i], r.bounds[i + 1]);
604+ while (i < nitems && j < r.nitems)
605+ {
606+ // lower of Xi and Xj is the lowest point.
607+ if (wi::le_p (bounds[i], r.bounds[j], sign))
608+ {
609+ res[k++] = bounds[i];
610+ res[k++] = bounds[i + 1];
611+ i += 2;
612+ }
613+ else
614+ {
615+ res[k++] = r.bounds[j];
616+ res[k++] = r.bounds[j + 1];
617+ j += 2;
618+ }
619+ }
720620
721- /* There is no valid_p() check here because the calls to union_
722- above would have called valid_p(). */
621+ for ( ; i < nitems; i += 2)
622+ {
623+ res[k++] = bounds[i];
624+ res[k++] = bounds[i + 1];
625+ }
626+
627+ for ( ; j < r.nitems; j += 2)
628+ {
629+ res[k++] = r.bounds[j];
630+ res[k++] = r.bounds[j + 1];
631+ }
632+
633+ // Now normalize the vector removing any overlaps.
634+
635+ i = 2;
636+ for (j = 2; j < k ; j += 2)
637+ {
638+ u1 = wi::add (res[i - 1], 1, sign, &ovf);
639+ // Overflow indicates we are at MAX already
640+ if (ovf)
641+ break;
642+ // Current upper+1 is >= lower bound next pair, then we merge ranges.
643+ if (wi::ge_p (u1, res[j], sign))
644+ {
645+ // New upper bounds is greater of current or the next one.
646+ if (wi::gt_p (res[j + 1], res [i - 1], sign))
647+ res [i - 1] = res[j + 1];
648+ }
649+ else
650+ {
651+ // this is a new distinct range, but no point in copying it if its
652+ // in the right place.
653+ if (i != j)
654+ {
655+ res[i++] = res[j];
656+ res[i++] = res[j + 1];
657+ }
658+ else
659+ i += 2;
660+
661+ }
662+ }
663+
664+ // At This point, the vector should have i ranges, none overlapping. Now
665+ // it simply needs to be copied, and if there are too many ranges,
666+ // merge some. WE wont do any analysis as to what the "best" merges are,
667+ // simply combine the final ranges into one.
668+ if (i > max_pairs * 2)
669+ {
670+ res[max_pairs * 2 - 1] = res[i - 1];
671+ i = max_pairs * 2;
672+ }
723673
674+ for (j = 0; j < i ; j++)
675+ bounds[j] = res [j];
676+ nitems = i;
677+
724678 overflow |= r.overflow;
679+
680+ gcc_assert (!CHECKING_P || valid_p ());
725681 return *this;
726682 }
727683
@@ -1390,7 +1346,7 @@ irange_tests ()
13901346 r1 = irange (integer_type_node, 25, 70);
13911347 r0.union_ (r1);
13921348 ASSERT_TRUE (r0 == irange_union (irange (integer_type_node, 10, 20),
1393- irange (integer_type_node, 30, 70)));
1349+ irange (integer_type_node, 25, 70)));
13941350
13951351 if (irange::max_pairs > 2)
13961352 {