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