GCC with patches for OS216
Revision | 7ce6c8b321a7d6243a2bdecc4de7c64fca4f211a (tree) |
---|---|
Time | 2018-04-03 05:51:26 |
Author | Andrew Macleod <amacleod@gcc....> |
Commiter | Andrew Macleod |
Rewrite range union
From-SVN: r259017
@@ -563,135 +563,8 @@ irange::union_ (const wide_int &x, const wide_int &y) | ||
563 | 563 | gcc_assert (!CHECKING_P || valid_p ()); |
564 | 564 | return *this; |
565 | 565 | } |
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); | |
695 | 568 | } |
696 | 569 | |
697 | 570 | // THIS = THIS U R |
@@ -709,19 +582,102 @@ irange::union_ (const irange &r) | ||
709 | 582 | else if (r.empty_p ()) |
710 | 583 | return *this; |
711 | 584 | |
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; | |
716 | 603 | |
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 | + } | |
720 | 620 | |
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 | + } | |
723 | 673 | |
674 | + for (j = 0; j < i ; j++) | |
675 | + bounds[j] = res [j]; | |
676 | + nitems = i; | |
677 | + | |
724 | 678 | overflow |= r.overflow; |
679 | + | |
680 | + gcc_assert (!CHECKING_P || valid_p ()); | |
725 | 681 | return *this; |
726 | 682 | } |
727 | 683 |
@@ -1390,7 +1346,7 @@ irange_tests () | ||
1390 | 1346 | r1 = irange (integer_type_node, 25, 70); |
1391 | 1347 | r0.union_ (r1); |
1392 | 1348 | 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))); | |
1394 | 1350 | |
1395 | 1351 | if (irange::max_pairs > 2) |
1396 | 1352 | { |