Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-affine.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* Operations with affine combinations of trees. | 1 /* Operations with affine combinations of trees. |
2 Copyright (C) 2005-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2005-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 6 GCC is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published by the | 7 under the terms of the GNU General Public License as published by the |
32 #include "dumpfile.h" | 32 #include "dumpfile.h" |
33 #include "cfgexpand.h" | 33 #include "cfgexpand.h" |
34 | 34 |
35 /* Extends CST as appropriate for the affine combinations COMB. */ | 35 /* Extends CST as appropriate for the affine combinations COMB. */ |
36 | 36 |
37 widest_int | 37 static widest_int |
38 wide_int_ext_for_comb (const widest_int &cst, tree type) | 38 wide_int_ext_for_comb (const widest_int &cst, tree type) |
39 { | |
40 return wi::sext (cst, TYPE_PRECISION (type)); | |
41 } | |
42 | |
43 /* Likewise for polynomial offsets. */ | |
44 | |
45 static poly_widest_int | |
46 wide_int_ext_for_comb (const poly_widest_int &cst, tree type) | |
39 { | 47 { |
40 return wi::sext (cst, TYPE_PRECISION (type)); | 48 return wi::sext (cst, TYPE_PRECISION (type)); |
41 } | 49 } |
42 | 50 |
43 /* Initializes affine combination COMB so that its value is zero in TYPE. */ | 51 /* Initializes affine combination COMB so that its value is zero in TYPE. */ |
55 } | 63 } |
56 | 64 |
57 /* Sets COMB to CST. */ | 65 /* Sets COMB to CST. */ |
58 | 66 |
59 void | 67 void |
60 aff_combination_const (aff_tree *comb, tree type, const widest_int &cst) | 68 aff_combination_const (aff_tree *comb, tree type, const poly_widest_int &cst) |
61 { | 69 { |
62 aff_combination_zero (comb, type); | 70 aff_combination_zero (comb, type); |
63 comb->offset = wide_int_ext_for_comb (cst, comb->type);; | 71 comb->offset = wide_int_ext_for_comb (cst, comb->type);; |
64 } | 72 } |
65 | 73 |
188 } | 196 } |
189 | 197 |
190 /* Adds CST to C. */ | 198 /* Adds CST to C. */ |
191 | 199 |
192 static void | 200 static void |
193 aff_combination_add_cst (aff_tree *c, const widest_int &cst) | 201 aff_combination_add_cst (aff_tree *c, const poly_widest_int &cst) |
194 { | 202 { |
195 c->offset = wide_int_ext_for_comb (c->offset + cst, c->type); | 203 c->offset = wide_int_ext_for_comb (c->offset + cst, c->type); |
196 } | 204 } |
197 | 205 |
198 /* Adds COMB2 to COMB1. */ | 206 /* Adds COMB2 to COMB1. */ |
257 tree_to_aff_combination (tree expr, tree type, aff_tree *comb) | 265 tree_to_aff_combination (tree expr, tree type, aff_tree *comb) |
258 { | 266 { |
259 aff_tree tmp; | 267 aff_tree tmp; |
260 enum tree_code code; | 268 enum tree_code code; |
261 tree cst, core, toffset; | 269 tree cst, core, toffset; |
262 HOST_WIDE_INT bitpos, bitsize; | 270 poly_int64 bitpos, bitsize, bytepos; |
263 machine_mode mode; | 271 machine_mode mode; |
264 int unsignedp, reversep, volatilep; | 272 int unsignedp, reversep, volatilep; |
265 | 273 |
266 STRIP_NOPS (expr); | 274 STRIP_NOPS (expr); |
267 | 275 |
268 code = TREE_CODE (expr); | 276 code = TREE_CODE (expr); |
269 switch (code) | 277 switch (code) |
270 { | 278 { |
271 case INTEGER_CST: | |
272 aff_combination_const (comb, type, wi::to_widest (expr)); | |
273 return; | |
274 | |
275 case POINTER_PLUS_EXPR: | 279 case POINTER_PLUS_EXPR: |
276 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb); | 280 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb); |
277 tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp); | 281 tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp); |
278 aff_combination_add (comb, &tmp); | 282 aff_combination_add (comb, &tmp); |
279 return; | 283 return; |
318 return; | 322 return; |
319 } | 323 } |
320 core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos, | 324 core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos, |
321 &toffset, &mode, &unsignedp, &reversep, | 325 &toffset, &mode, &unsignedp, &reversep, |
322 &volatilep); | 326 &volatilep); |
323 if (bitpos % BITS_PER_UNIT != 0) | 327 if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos)) |
324 break; | 328 break; |
325 aff_combination_const (comb, type, bitpos / BITS_PER_UNIT); | 329 aff_combination_const (comb, type, bytepos); |
326 if (TREE_CODE (core) == MEM_REF) | 330 if (TREE_CODE (core) == MEM_REF) |
327 { | 331 { |
328 aff_combination_add_cst (comb, wi::to_widest (TREE_OPERAND (core, 1))); | 332 tree mem_offset = TREE_OPERAND (core, 1); |
333 aff_combination_add_cst (comb, wi::to_poly_widest (mem_offset)); | |
329 core = TREE_OPERAND (core, 0); | 334 core = TREE_OPERAND (core, 0); |
330 } | 335 } |
331 else | 336 else |
332 core = build_fold_addr_expr (core); | 337 core = build_fold_addr_expr (core); |
333 | 338 |
421 } | 426 } |
422 } | 427 } |
423 break; | 428 break; |
424 | 429 |
425 default: | 430 default: |
426 break; | 431 { |
432 if (poly_int_tree_p (expr)) | |
433 { | |
434 aff_combination_const (comb, type, wi::to_poly_widest (expr)); | |
435 return; | |
436 } | |
437 break; | |
438 } | |
427 } | 439 } |
428 | 440 |
429 aff_combination_elt (comb, type, expr); | 441 aff_combination_elt (comb, type, expr); |
430 } | 442 } |
431 | 443 |
476 tree | 488 tree |
477 aff_combination_to_tree (aff_tree *comb) | 489 aff_combination_to_tree (aff_tree *comb) |
478 { | 490 { |
479 tree type = comb->type, base = NULL_TREE, expr = NULL_TREE; | 491 tree type = comb->type, base = NULL_TREE, expr = NULL_TREE; |
480 unsigned i; | 492 unsigned i; |
481 widest_int off, sgn; | 493 poly_widest_int off; |
494 int sgn; | |
482 | 495 |
483 gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE); | 496 gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE); |
484 | 497 |
485 i = 0; | 498 i = 0; |
486 if (POINTER_TYPE_P (type)) | 499 if (POINTER_TYPE_P (type)) |
500 if (comb->rest) | 513 if (comb->rest) |
501 expr = add_elt_to_tree (expr, type, comb->rest, 1); | 514 expr = add_elt_to_tree (expr, type, comb->rest, 1); |
502 | 515 |
503 /* Ensure that we get x - 1, not x + (-1) or x + 0xff..f if x is | 516 /* Ensure that we get x - 1, not x + (-1) or x + 0xff..f if x is |
504 unsigned. */ | 517 unsigned. */ |
505 if (wi::neg_p (comb->offset)) | 518 if (known_lt (comb->offset, 0)) |
506 { | 519 { |
507 off = -comb->offset; | 520 off = -comb->offset; |
508 sgn = -1; | 521 sgn = -1; |
509 } | 522 } |
510 else | 523 else |
586 | 599 |
587 aff_combination_add_elt (r, aval, coef); | 600 aff_combination_add_elt (r, aval, coef); |
588 } | 601 } |
589 | 602 |
590 if (val) | 603 if (val) |
591 aff_combination_add_elt (r, val, coef * c->offset); | 604 { |
605 if (c->offset.is_constant ()) | |
606 /* Access coeffs[0] directly, for efficiency. */ | |
607 aff_combination_add_elt (r, val, coef * c->offset.coeffs[0]); | |
608 else | |
609 { | |
610 /* c->offset is polynomial, so multiply VAL rather than COEF | |
611 by it. */ | |
612 tree offset = wide_int_to_tree (TREE_TYPE (val), c->offset); | |
613 val = fold_build2 (MULT_EXPR, TREE_TYPE (val), val, offset); | |
614 aff_combination_add_elt (r, val, coef); | |
615 } | |
616 } | |
592 else | 617 else |
593 aff_combination_add_cst (r, coef * c->offset); | 618 aff_combination_add_cst (r, coef * c->offset); |
594 } | 619 } |
595 | 620 |
596 /* Multiplies C1 by C2, storing the result to R */ | 621 /* Multiplies C1 by C2, storing the result to R */ |
605 | 630 |
606 for (i = 0; i < c2->n; i++) | 631 for (i = 0; i < c2->n; i++) |
607 aff_combination_add_product (c1, c2->elts[i].coef, c2->elts[i].val, r); | 632 aff_combination_add_product (c1, c2->elts[i].coef, c2->elts[i].val, r); |
608 if (c2->rest) | 633 if (c2->rest) |
609 aff_combination_add_product (c1, 1, c2->rest, r); | 634 aff_combination_add_product (c1, 1, c2->rest, r); |
610 aff_combination_add_product (c1, c2->offset, NULL, r); | 635 if (c2->offset.is_constant ()) |
636 /* Access coeffs[0] directly, for efficiency. */ | |
637 aff_combination_add_product (c1, c2->offset.coeffs[0], NULL, r); | |
638 else | |
639 { | |
640 /* c2->offset is polynomial, so do the multiplication in tree form. */ | |
641 tree offset = wide_int_to_tree (c2->type, c2->offset); | |
642 aff_combination_add_product (c1, 1, offset, r); | |
643 } | |
611 } | 644 } |
612 | 645 |
613 /* Returns the element of COMB whose value is VAL, or NULL if no such | 646 /* Returns the element of COMB whose value is VAL, or NULL if no such |
614 element exists. If IDX is not NULL, it is set to the index of VAL in | 647 element exists. If IDX is not NULL, it is set to the index of VAL in |
615 COMB. */ | 648 COMB. */ |
774 and if they are different, returns false. Finally, if neither of these | 807 and if they are different, returns false. Finally, if neither of these |
775 two cases occur, true is returned, and CST is stored to MULT and MULT_SET | 808 two cases occur, true is returned, and CST is stored to MULT and MULT_SET |
776 is set to true. */ | 809 is set to true. */ |
777 | 810 |
778 static bool | 811 static bool |
779 wide_int_constant_multiple_p (const widest_int &val, const widest_int &div, | 812 wide_int_constant_multiple_p (const poly_widest_int &val, |
780 bool *mult_set, widest_int *mult) | 813 const poly_widest_int &div, |
781 { | 814 bool *mult_set, poly_widest_int *mult) |
782 widest_int rem, cst; | 815 { |
783 | 816 poly_widest_int rem, cst; |
784 if (val == 0) | 817 |
785 { | 818 if (known_eq (val, 0)) |
786 if (*mult_set && *mult != 0) | 819 { |
820 if (*mult_set && maybe_ne (*mult, 0)) | |
787 return false; | 821 return false; |
788 *mult_set = true; | 822 *mult_set = true; |
789 *mult = 0; | 823 *mult = 0; |
790 return true; | 824 return true; |
791 } | 825 } |
792 | 826 |
793 if (div == 0) | 827 if (maybe_eq (div, 0)) |
794 return false; | 828 return false; |
795 | 829 |
796 if (!wi::multiple_of_p (val, div, SIGNED, &cst)) | 830 if (!multiple_p (val, div, &cst)) |
797 return false; | 831 return false; |
798 | 832 |
799 if (*mult_set && *mult != cst) | 833 if (*mult_set && maybe_ne (*mult, cst)) |
800 return false; | 834 return false; |
801 | 835 |
802 *mult_set = true; | 836 *mult_set = true; |
803 *mult = cst; | 837 *mult = cst; |
804 return true; | 838 return true; |
807 /* Returns true if VAL = X * DIV for some constant X. If this is the case, | 841 /* Returns true if VAL = X * DIV for some constant X. If this is the case, |
808 X is stored to MULT. */ | 842 X is stored to MULT. */ |
809 | 843 |
810 bool | 844 bool |
811 aff_combination_constant_multiple_p (aff_tree *val, aff_tree *div, | 845 aff_combination_constant_multiple_p (aff_tree *val, aff_tree *div, |
812 widest_int *mult) | 846 poly_widest_int *mult) |
813 { | 847 { |
814 bool mult_set = false; | 848 bool mult_set = false; |
815 unsigned i; | 849 unsigned i; |
816 | 850 |
817 if (val->n == 0 && val->offset == 0) | 851 if (val->n == 0 && known_eq (val->offset, 0)) |
818 { | 852 { |
819 *mult = 0; | 853 *mult = 0; |
820 return true; | 854 return true; |
821 } | 855 } |
822 if (val->n != div->n) | 856 if (val->n != div->n) |
892 /* Computes address of the reference REF in ADDR. The size of the accessed | 926 /* Computes address of the reference REF in ADDR. The size of the accessed |
893 location is stored to SIZE. Returns the ultimate containing object to | 927 location is stored to SIZE. Returns the ultimate containing object to |
894 which REF refers. */ | 928 which REF refers. */ |
895 | 929 |
896 tree | 930 tree |
897 get_inner_reference_aff (tree ref, aff_tree *addr, widest_int *size) | 931 get_inner_reference_aff (tree ref, aff_tree *addr, poly_widest_int *size) |
898 { | 932 { |
899 HOST_WIDE_INT bitsize, bitpos; | 933 poly_int64 bitsize, bitpos; |
900 tree toff; | 934 tree toff; |
901 machine_mode mode; | 935 machine_mode mode; |
902 int uns, rev, vol; | 936 int uns, rev, vol; |
903 aff_tree tmp; | 937 aff_tree tmp; |
904 tree base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode, | 938 tree base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode, |
913 { | 947 { |
914 tree_to_aff_combination (toff, sizetype, &tmp); | 948 tree_to_aff_combination (toff, sizetype, &tmp); |
915 aff_combination_add (addr, &tmp); | 949 aff_combination_add (addr, &tmp); |
916 } | 950 } |
917 | 951 |
918 aff_combination_const (&tmp, sizetype, bitpos / BITS_PER_UNIT); | 952 aff_combination_const (&tmp, sizetype, bits_to_bytes_round_down (bitpos)); |
919 aff_combination_add (addr, &tmp); | 953 aff_combination_add (addr, &tmp); |
920 | 954 |
921 *size = (bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT; | 955 *size = bits_to_bytes_round_up (bitsize); |
922 | 956 |
923 return base; | 957 return base; |
924 } | 958 } |
925 | 959 |
926 /* Returns true if a region of size SIZE1 at position 0 and a region of | 960 /* Returns true if a region of size SIZE1 at position 0 and a region of |
927 size SIZE2 at position DIFF cannot overlap. */ | 961 size SIZE2 at position DIFF cannot overlap. */ |
928 | 962 |
929 bool | 963 bool |
930 aff_comb_cannot_overlap_p (aff_tree *diff, const widest_int &size1, | 964 aff_comb_cannot_overlap_p (aff_tree *diff, const poly_widest_int &size1, |
931 const widest_int &size2) | 965 const poly_widest_int &size2) |
932 { | 966 { |
933 /* Unless the difference is a constant, we fail. */ | 967 /* Unless the difference is a constant, we fail. */ |
934 if (diff->n != 0) | 968 if (diff->n != 0) |
935 return false; | 969 return false; |
936 | 970 |
937 if (wi::neg_p (diff->offset)) | 971 if (!ordered_p (diff->offset, 0)) |
972 return false; | |
973 | |
974 if (maybe_lt (diff->offset, 0)) | |
938 { | 975 { |
939 /* The second object is before the first one, we succeed if the last | 976 /* The second object is before the first one, we succeed if the last |
940 element of the second object is before the start of the first one. */ | 977 element of the second object is before the start of the first one. */ |
941 return wi::neg_p (diff->offset + size2 - 1); | 978 return known_le (diff->offset + size2, 0); |
942 } | 979 } |
943 else | 980 else |
944 { | 981 { |
945 /* We succeed if the second object starts after the first one ends. */ | 982 /* We succeed if the second object starts after the first one ends. */ |
946 return size1 <= diff->offset; | 983 return known_le (size1, diff->offset); |
947 } | 984 } |
948 } | 985 } |
949 | 986 |