1 /* Operations with affine combinations of trees.
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
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
8 Free Software Foundation; either version 2, or (at your option) any
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "coretypes.h"
28 #include "hard-reg-set.h"
30 #include "diagnostic.h"
31 #include "tree-dump.h"
32 #include "pointer-set.h"
33 #include "tree-affine.h"
34 #include "tree-gimple.h"
36 /* Extends CST as appropriate for the affine combinations COMB. */
39 double_int_ext_for_comb (double_int cst, aff_tree *comb)
41 return double_int_sext (cst, TYPE_PRECISION (comb->type));
44 /* Initializes affine combination COMB so that its value is zero in TYPE. */
47 aff_combination_zero (aff_tree *comb, tree type)
50 comb->offset = double_int_zero;
52 comb->rest = NULL_TREE;
55 /* Sets COMB to CST. */
58 aff_combination_const (aff_tree *comb, tree type, double_int cst)
60 aff_combination_zero (comb, type);
61 comb->offset = double_int_ext_for_comb (cst, comb);
64 /* Sets COMB to single element ELT. */
67 aff_combination_elt (aff_tree *comb, tree type, tree elt)
69 aff_combination_zero (comb, type);
72 comb->elts[0].val = elt;
73 comb->elts[0].coef = double_int_one;
76 /* Scales COMB by SCALE. */
79 aff_combination_scale (aff_tree *comb, double_int scale)
83 scale = double_int_ext_for_comb (scale, comb);
84 if (double_int_one_p (scale))
87 if (double_int_zero_p (scale))
89 aff_combination_zero (comb, comb->type);
94 = double_int_ext_for_comb (double_int_mul (scale, comb->offset), comb);
95 for (i = 0, j = 0; i < comb->n; i++)
100 = double_int_ext_for_comb (double_int_mul (scale, comb->elts[i].coef),
102 /* A coefficient may become zero due to overflow. Remove the zero
104 if (double_int_zero_p (new_coef))
106 comb->elts[j].coef = new_coef;
107 comb->elts[j].val = comb->elts[i].val;
114 if (comb->n < MAX_AFF_ELTS)
116 comb->elts[comb->n].coef = scale;
117 comb->elts[comb->n].val = comb->rest;
118 comb->rest = NULL_TREE;
122 comb->rest = fold_build2 (MULT_EXPR, comb->type, comb->rest,
123 double_int_to_tree (comb->type, scale));
127 /* Adds ELT * SCALE to COMB. */
130 aff_combination_add_elt (aff_tree *comb, tree elt, double_int scale)
135 scale = double_int_ext_for_comb (scale, comb);
136 if (double_int_zero_p (scale))
139 for (i = 0; i < comb->n; i++)
140 if (operand_equal_p (comb->elts[i].val, elt, 0))
144 new_coef = double_int_add (comb->elts[i].coef, scale);
145 new_coef = double_int_ext_for_comb (new_coef, comb);
146 if (!double_int_zero_p (new_coef))
148 comb->elts[i].coef = new_coef;
153 comb->elts[i] = comb->elts[comb->n];
157 gcc_assert (comb->n == MAX_AFF_ELTS - 1);
158 comb->elts[comb->n].coef = double_int_one;
159 comb->elts[comb->n].val = comb->rest;
160 comb->rest = NULL_TREE;
165 if (comb->n < MAX_AFF_ELTS)
167 comb->elts[comb->n].coef = scale;
168 comb->elts[comb->n].val = elt;
174 if (POINTER_TYPE_P (type))
177 if (double_int_one_p (scale))
178 elt = fold_convert (type, elt);
180 elt = fold_build2 (MULT_EXPR, type,
181 fold_convert (type, elt),
182 double_int_to_tree (type, scale));
186 if (POINTER_TYPE_P (comb->type))
187 comb->rest = fold_build2 (POINTER_PLUS_EXPR, comb->type,
190 comb->rest = fold_build2 (PLUS_EXPR, comb->type, comb->rest,
200 aff_combination_add_cst (aff_tree *c, double_int cst)
202 c->offset = double_int_ext_for_comb (double_int_add (c->offset, cst), c);
205 /* Adds COMB2 to COMB1. */
208 aff_combination_add (aff_tree *comb1, aff_tree *comb2)
212 aff_combination_add_cst (comb1, comb2->offset);
213 for (i = 0; i < comb2->n; i++)
214 aff_combination_add_elt (comb1, comb2->elts[i].val, comb2->elts[i].coef);
216 aff_combination_add_elt (comb1, comb2->rest, double_int_one);
219 /* Converts affine combination COMB to TYPE. */
222 aff_combination_convert (aff_tree *comb, tree type)
225 tree comb_type = comb->type;
227 if (TYPE_PRECISION (type) > TYPE_PRECISION (comb_type))
229 tree val = fold_convert (type, aff_combination_to_tree (comb));
230 tree_to_aff_combination (val, type, comb);
236 comb->rest = fold_convert (type, comb->rest);
238 if (TYPE_PRECISION (type) == TYPE_PRECISION (comb_type))
241 comb->offset = double_int_ext_for_comb (comb->offset, comb);
242 for (i = j = 0; i < comb->n; i++)
244 double_int new_coef = double_int_ext_for_comb (comb->elts[i].coef, comb);
245 if (double_int_zero_p (new_coef))
247 comb->elts[j].coef = new_coef;
248 comb->elts[j].val = fold_convert (type, comb->elts[i].val);
253 if (comb->n < MAX_AFF_ELTS && comb->rest)
255 comb->elts[comb->n].coef = double_int_one;
256 comb->elts[comb->n].val = comb->rest;
257 comb->rest = NULL_TREE;
262 /* Splits EXPR into an affine combination of parts. */
265 tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
269 tree cst, core, toffset;
270 HOST_WIDE_INT bitpos, bitsize;
271 enum machine_mode mode;
272 int unsignedp, volatilep;
276 code = TREE_CODE (expr);
280 aff_combination_const (comb, type, tree_to_double_int (expr));
283 case POINTER_PLUS_EXPR:
284 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
285 tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
286 aff_combination_convert (&tmp, type);
287 aff_combination_add (comb, &tmp);
292 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
293 tree_to_aff_combination (TREE_OPERAND (expr, 1), type, &tmp);
294 if (code == MINUS_EXPR)
295 aff_combination_scale (&tmp, double_int_minus_one);
296 aff_combination_add (comb, &tmp);
300 cst = TREE_OPERAND (expr, 1);
301 if (TREE_CODE (cst) != INTEGER_CST)
303 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
304 aff_combination_scale (comb, tree_to_double_int (cst));
308 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
309 aff_combination_scale (comb, double_int_minus_one);
314 tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
315 aff_combination_scale (comb, double_int_minus_one);
316 aff_combination_add_cst (comb, double_int_minus_one);
320 core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
321 &toffset, &mode, &unsignedp, &volatilep,
323 if (bitpos % BITS_PER_UNIT != 0)
325 aff_combination_const (comb, type,
326 uhwi_to_double_int (bitpos / BITS_PER_UNIT));
327 core = build_fold_addr_expr (core);
328 if (TREE_CODE (core) == ADDR_EXPR)
329 aff_combination_add_elt (comb, core, double_int_one);
332 tree_to_aff_combination (core, type, &tmp);
333 aff_combination_add (comb, &tmp);
337 tree_to_aff_combination (toffset, type, &tmp);
338 aff_combination_add (comb, &tmp);
346 aff_combination_elt (comb, type, expr);
349 /* Creates EXPR + ELT * SCALE in TYPE. EXPR is taken from affine
353 add_elt_to_tree (tree expr, tree type, tree elt, double_int scale,
358 scale = double_int_ext_for_comb (scale, comb);
359 elt = fold_convert (type, elt);
361 if (double_int_one_p (scale))
366 return fold_build2 (PLUS_EXPR, type, expr, elt);
369 if (double_int_minus_one_p (scale))
372 return fold_build1 (NEGATE_EXPR, type, elt);
374 return fold_build2 (MINUS_EXPR, type, expr, elt);
378 return fold_build2 (MULT_EXPR, type, elt,
379 double_int_to_tree (type, scale));
381 if (double_int_negative_p (scale))
384 scale = double_int_neg (scale);
389 elt = fold_build2 (MULT_EXPR, type, elt,
390 double_int_to_tree (type, scale));
391 return fold_build2 (code, type, expr, elt);
394 /* Makes tree from the affine combination COMB. */
397 aff_combination_to_tree (aff_tree *comb)
399 tree type = comb->type;
400 tree expr = comb->rest;
404 gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE);
406 for (i = 0; i < comb->n; i++)
407 expr = add_elt_to_tree (expr, type, comb->elts[i].val, comb->elts[i].coef,
410 /* Ensure that we get x - 1, not x + (-1) or x + 0xff..f if x is
412 if (double_int_negative_p (comb->offset))
414 off = double_int_neg (comb->offset);
415 sgn = double_int_minus_one;
420 sgn = double_int_one;
422 return add_elt_to_tree (expr, type, double_int_to_tree (type, off), sgn,
426 /* Copies the tree elements of COMB to ensure that they are not shared. */
429 unshare_aff_combination (aff_tree *comb)
433 for (i = 0; i < comb->n; i++)
434 comb->elts[i].val = unshare_expr (comb->elts[i].val);
436 comb->rest = unshare_expr (comb->rest);
439 /* Remove M-th element from COMB. */
442 aff_combination_remove_elt (aff_tree *comb, unsigned m)
446 comb->elts[m] = comb->elts[comb->n];
449 comb->elts[comb->n].coef = double_int_one;
450 comb->elts[comb->n].val = comb->rest;
451 comb->rest = NULL_TREE;
456 /* Adds C * COEF * VAL to R. VAL may be NULL, in that case only
457 C * COEF is added to R. */
461 aff_combination_add_product (aff_tree *c, double_int coef, tree val,
467 for (i = 0; i < c->n; i++)
469 aval = c->elts[i].val;
472 type = TREE_TYPE (aval);
473 aval = fold_build2 (MULT_EXPR, type, aval,
474 fold_convert (type, val));
477 aff_combination_add_elt (r, aval,
478 double_int_mul (coef, c->elts[i].coef));
486 type = TREE_TYPE (aval);
487 aval = fold_build2 (MULT_EXPR, type, aval,
488 fold_convert (type, val));
491 aff_combination_add_elt (r, aval, coef);
495 aff_combination_add_elt (r, val,
496 double_int_mul (coef, c->offset));
498 aff_combination_add_cst (r, double_int_mul (coef, c->offset));
501 /* Multiplies C1 by C2, storing the result to R */
504 aff_combination_mult (aff_tree *c1, aff_tree *c2, aff_tree *r)
507 gcc_assert (TYPE_PRECISION (c1->type) == TYPE_PRECISION (c2->type));
509 aff_combination_zero (r, c1->type);
511 for (i = 0; i < c2->n; i++)
512 aff_combination_add_product (c1, c2->elts[i].coef, c2->elts[i].val, r);
514 aff_combination_add_product (c1, double_int_one, c2->rest, r);
515 aff_combination_add_product (c1, c2->offset, NULL, r);
518 /* Returns the element of COMB whose value is VAL, or NULL if no such
519 element exists. If IDX is not NULL, it is set to the index of VAL in
522 static struct aff_comb_elt *
523 aff_combination_find_elt (aff_tree *comb, tree val, unsigned *idx)
527 for (i = 0; i < comb->n; i++)
528 if (operand_equal_p (comb->elts[i].val, val, 0))
533 return &comb->elts[i];
539 /* Element of the cache that maps ssa name NAME to its expanded form
540 as an affine expression EXPANSION. */
542 struct name_expansion
546 /* True if the expansion for the name is just being generated. */
547 unsigned in_progress : 1;
550 /* Similar to tree_to_aff_combination, but follows SSA name definitions
551 and expands them recursively. CACHE is used to cache the expansions
552 of the ssa names, to avoid exponential time complexity for cases
561 tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
562 struct pointer_map_t **cache)
565 aff_tree to_add, current, curre;
569 struct name_expansion *exp;
571 tree_to_aff_combination (expr, type, comb);
572 aff_combination_zero (&to_add, type);
573 for (i = 0; i < comb->n; i++)
575 e = comb->elts[i].val;
576 if (TREE_CODE (e) != SSA_NAME)
578 def = SSA_NAME_DEF_STMT (e);
579 if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
580 || GIMPLE_STMT_OPERAND (def, 0) != e)
583 rhs = GIMPLE_STMT_OPERAND (def, 1);
584 if (TREE_CODE (rhs) != SSA_NAME
586 && !is_gimple_min_invariant (rhs))
589 /* We do not know whether the reference retains its value at the
590 place where the expansion is used. */
591 if (REFERENCE_CLASS_P (rhs))
595 *cache = pointer_map_create ();
596 slot = pointer_map_insert (*cache, e);
601 exp = XNEW (struct name_expansion);
602 exp->in_progress = 1;
604 tree_to_aff_combination_expand (rhs, type, ¤t, cache);
605 exp->expansion = current;
606 exp->in_progress = 0;
610 /* Since we follow the definitions in the SSA form, we should not
611 enter a cycle unless we pass through a phi node. */
612 gcc_assert (!exp->in_progress);
613 current = exp->expansion;
616 /* Accumulate the new terms to TO_ADD, so that we do not modify
617 COMB while traversing it; include the term -coef * E, to remove
619 scale = comb->elts[i].coef;
620 aff_combination_zero (&curre, type);
621 aff_combination_add_elt (&curre, e, double_int_neg (scale));
622 aff_combination_scale (¤t, scale);
623 aff_combination_add (&to_add, ¤t);
624 aff_combination_add (&to_add, &curre);
626 aff_combination_add (comb, &to_add);
629 /* Frees memory occupied by struct name_expansion in *VALUE. Callback for
630 pointer_map_traverse. */
633 free_name_expansion (void *key ATTRIBUTE_UNUSED, void **value,
634 void *data ATTRIBUTE_UNUSED)
636 struct name_expansion *exp = *value;
642 /* Frees memory allocated for the CACHE used by
643 tree_to_aff_combination_expand. */
646 free_affine_expand_cache (struct pointer_map_t **cache)
651 pointer_map_traverse (*cache, free_name_expansion, NULL);
652 pointer_map_destroy (*cache);
656 /* If VAL != CST * DIV for any constant CST, returns false.
657 Otherwise, if VAL != 0 (and hence CST != 0), and *MULT_SET is true,
658 additionally compares CST and MULT, and if they are different,
659 returns false. Finally, if neither of these two cases occur,
660 true is returned, and if CST != 0, CST is stored to MULT and
661 MULT_SET is set to true. */
664 double_int_constant_multiple_p (double_int val, double_int div,
665 bool *mult_set, double_int *mult)
669 if (double_int_zero_p (val))
672 if (double_int_zero_p (div))
675 cst = double_int_sdivmod (val, div, FLOOR_DIV_EXPR, &rem);
676 if (!double_int_zero_p (rem))
679 if (*mult_set && !double_int_equal_p (*mult, cst))
687 /* Returns true if VAL = X * DIV for some constant X. If this is the case,
688 X is stored to MULT. */
691 aff_combination_constant_multiple_p (aff_tree *val, aff_tree *div,
694 bool mult_set = false;
697 if (val->n == 0 && double_int_zero_p (val->offset))
699 *mult = double_int_zero;
702 if (val->n != div->n)
705 if (val->rest || div->rest)
708 if (!double_int_constant_multiple_p (val->offset, div->offset,
712 for (i = 0; i < div->n; i++)
714 struct aff_comb_elt *elt
715 = aff_combination_find_elt (val, div->elts[i].val, NULL);
718 if (!double_int_constant_multiple_p (elt->coef, div->elts[i].coef,
723 gcc_assert (mult_set);