1 /* Chains of recurrences.
2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <s.pop@laposte.net>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 /* This file implements operations on chains of recurrences. Chains
23 of recurrences are used for modeling evolution functions of scalar
29 #include "coretypes.h"
33 #include "diagnostic.h"
35 #include "tree-chrec.h"
36 #include "tree-pass.h"
41 /* Extended folder for chrecs. */
43 /* Determines whether CST is not a constant evolution. */
46 is_not_constant_evolution (tree cst)
48 return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
51 /* Fold CODE for a polynomial function and a constant. */
54 chrec_fold_poly_cst (enum tree_code code,
61 gcc_assert (TREE_CODE (poly) == POLYNOMIAL_CHREC);
62 gcc_assert (!is_not_constant_evolution (cst));
67 return build_polynomial_chrec
68 (CHREC_VARIABLE (poly),
69 chrec_fold_plus (type, CHREC_LEFT (poly), cst),
73 return build_polynomial_chrec
74 (CHREC_VARIABLE (poly),
75 chrec_fold_minus (type, CHREC_LEFT (poly), cst),
79 return build_polynomial_chrec
80 (CHREC_VARIABLE (poly),
81 chrec_fold_multiply (type, CHREC_LEFT (poly), cst),
82 chrec_fold_multiply (type, CHREC_RIGHT (poly), cst));
85 return chrec_dont_know;
89 /* Fold the addition of two polynomial functions. */
92 chrec_fold_plus_poly_poly (enum tree_code code,
101 gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
102 gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
105 {a, +, b}_1 + {c, +, d}_2 -> {{a, +, b}_1 + c, +, d}_2,
106 {a, +, b}_2 + {c, +, d}_1 -> {{c, +, d}_1 + a, +, b}_2,
107 {a, +, b}_x + {c, +, d}_x -> {a+c, +, b+d}_x. */
108 if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
110 if (code == PLUS_EXPR)
111 return build_polynomial_chrec
112 (CHREC_VARIABLE (poly1),
113 chrec_fold_plus (type, poly0, CHREC_LEFT (poly1)),
114 CHREC_RIGHT (poly1));
116 return build_polynomial_chrec
117 (CHREC_VARIABLE (poly1),
118 chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
119 chrec_fold_multiply (type, CHREC_RIGHT (poly1),
120 build_int_cst_type (type, -1)));
123 if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
125 if (code == PLUS_EXPR)
126 return build_polynomial_chrec
127 (CHREC_VARIABLE (poly0),
128 chrec_fold_plus (type, CHREC_LEFT (poly0), poly1),
129 CHREC_RIGHT (poly0));
131 return build_polynomial_chrec
132 (CHREC_VARIABLE (poly0),
133 chrec_fold_minus (type, CHREC_LEFT (poly0), poly1),
134 CHREC_RIGHT (poly0));
137 if (code == PLUS_EXPR)
139 left = chrec_fold_plus
140 (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
141 right = chrec_fold_plus
142 (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
146 left = chrec_fold_minus
147 (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
148 right = chrec_fold_minus
149 (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
152 if (chrec_zerop (right))
155 return build_polynomial_chrec
156 (CHREC_VARIABLE (poly0), left, right);
161 /* Fold the multiplication of two polynomial functions. */
164 chrec_fold_multiply_poly_poly (tree type,
170 gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
171 gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
173 /* {a, +, b}_1 * {c, +, d}_2 -> {c*{a, +, b}_1, +, d}_2,
174 {a, +, b}_2 * {c, +, d}_1 -> {a*{c, +, d}_1, +, b}_2,
175 {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
176 if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
177 /* poly0 is a constant wrt. poly1. */
178 return build_polynomial_chrec
179 (CHREC_VARIABLE (poly1),
180 chrec_fold_multiply (type, CHREC_LEFT (poly1), poly0),
181 CHREC_RIGHT (poly1));
183 if (CHREC_VARIABLE (poly1) < CHREC_VARIABLE (poly0))
184 /* poly1 is a constant wrt. poly0. */
185 return build_polynomial_chrec
186 (CHREC_VARIABLE (poly0),
187 chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
188 CHREC_RIGHT (poly0));
190 /* poly0 and poly1 are two polynomials in the same variable,
191 {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
193 build_polynomial_chrec
194 (CHREC_VARIABLE (poly0),
195 build_polynomial_chrec
196 (CHREC_VARIABLE (poly0),
199 chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1)),
201 /* "a*d + b*c + b*d". */
203 (type, chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_RIGHT (poly1)),
207 chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_LEFT (poly1)),
208 chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1))))),
212 (type, build_int_cst (NULL_TREE, 2),
213 chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1))));
216 /* When the operands are automatically_generated_chrec_p, the fold has
217 to respect the semantics of the operands. */
220 chrec_fold_automatically_generated_operands (tree op0,
223 if (op0 == chrec_dont_know
224 || op1 == chrec_dont_know)
225 return chrec_dont_know;
227 if (op0 == chrec_known
228 || op1 == chrec_known)
231 if (op0 == chrec_not_analyzed_yet
232 || op1 == chrec_not_analyzed_yet)
233 return chrec_not_analyzed_yet;
235 /* The default case produces a safe result. */
236 return chrec_dont_know;
239 /* Fold the addition of two chrecs. */
242 chrec_fold_plus_1 (enum tree_code code,
247 if (automatically_generated_chrec_p (op0)
248 || automatically_generated_chrec_p (op1))
249 return chrec_fold_automatically_generated_operands (op0, op1);
251 switch (TREE_CODE (op0))
253 case POLYNOMIAL_CHREC:
254 switch (TREE_CODE (op1))
256 case POLYNOMIAL_CHREC:
257 return chrec_fold_plus_poly_poly (code, type, op0, op1);
260 if (code == PLUS_EXPR)
261 return build_polynomial_chrec
262 (CHREC_VARIABLE (op0),
263 chrec_fold_plus (type, CHREC_LEFT (op0), op1),
266 return build_polynomial_chrec
267 (CHREC_VARIABLE (op0),
268 chrec_fold_minus (type, CHREC_LEFT (op0), op1),
273 switch (TREE_CODE (op1))
275 case POLYNOMIAL_CHREC:
276 if (code == PLUS_EXPR)
277 return build_polynomial_chrec
278 (CHREC_VARIABLE (op1),
279 chrec_fold_plus (type, op0, CHREC_LEFT (op1)),
282 return build_polynomial_chrec
283 (CHREC_VARIABLE (op1),
284 chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
285 chrec_fold_multiply (type, CHREC_RIGHT (op1),
286 build_int_cst_type (type, -1)));
291 if ((tree_contains_chrecs (op0, &size)
292 || tree_contains_chrecs (op1, &size))
293 && size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
294 return build2 (code, type, op0, op1);
295 else if (size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
296 return fold_build2 (code, type,
297 fold_convert (type, op0),
298 fold_convert (type, op1));
300 return chrec_dont_know;
306 /* Fold the addition of two chrecs. */
309 chrec_fold_plus (tree type,
313 if (integer_zerop (op0))
315 if (integer_zerop (op1))
318 return chrec_fold_plus_1 (PLUS_EXPR, type, op0, op1);
321 /* Fold the subtraction of two chrecs. */
324 chrec_fold_minus (tree type,
328 if (integer_zerop (op1))
331 return chrec_fold_plus_1 (MINUS_EXPR, type, op0, op1);
334 /* Fold the multiplication of two chrecs. */
337 chrec_fold_multiply (tree type,
341 if (automatically_generated_chrec_p (op0)
342 || automatically_generated_chrec_p (op1))
343 return chrec_fold_automatically_generated_operands (op0, op1);
345 switch (TREE_CODE (op0))
347 case POLYNOMIAL_CHREC:
348 switch (TREE_CODE (op1))
350 case POLYNOMIAL_CHREC:
351 return chrec_fold_multiply_poly_poly (type, op0, op1);
354 if (integer_onep (op1))
356 if (integer_zerop (op1))
357 return build_int_cst_type (type, 0);
359 return build_polynomial_chrec
360 (CHREC_VARIABLE (op0),
361 chrec_fold_multiply (type, CHREC_LEFT (op0), op1),
362 chrec_fold_multiply (type, CHREC_RIGHT (op0), op1));
366 if (integer_onep (op0))
369 if (integer_zerop (op0))
370 return build_int_cst_type (type, 0);
372 switch (TREE_CODE (op1))
374 case POLYNOMIAL_CHREC:
375 return build_polynomial_chrec
376 (CHREC_VARIABLE (op1),
377 chrec_fold_multiply (type, CHREC_LEFT (op1), op0),
378 chrec_fold_multiply (type, CHREC_RIGHT (op1), op0));
381 if (integer_onep (op1))
383 if (integer_zerop (op1))
384 return build_int_cst_type (type, 0);
385 return fold_build2 (MULT_EXPR, type, op0, op1);
394 /* Evaluate the binomial coefficient. Return NULL_TREE if the intermediate
395 calculation overflows, otherwise return C(n,k) with type TYPE. */
398 tree_fold_binomial (tree type, tree n, unsigned int k)
400 unsigned HOST_WIDE_INT lidx, lnum, ldenom, lres, ldum;
401 HOST_WIDE_INT hidx, hnum, hdenom, hres, hdum;
405 /* Handle the most frequent cases. */
407 return build_int_cst (type, 1);
409 return fold_convert (type, n);
411 /* Check that k <= n. */
412 if (TREE_INT_CST_HIGH (n) == 0
413 && TREE_INT_CST_LOW (n) < k)
417 lnum = TREE_INT_CST_LOW (n);
418 hnum = TREE_INT_CST_HIGH (n);
420 /* Denominator = 2. */
424 /* Index = Numerator-1. */
428 lidx = ~ (unsigned HOST_WIDE_INT) 0;
436 /* Numerator = Numerator*Index = n*(n-1). */
437 if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
440 for (i = 3; i <= k; i++)
446 lidx = ~ (unsigned HOST_WIDE_INT) 0;
451 /* Numerator *= Index. */
452 if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
455 /* Denominator *= i. */
456 mul_double (ldenom, hdenom, i, 0, &ldenom, &hdenom);
459 /* Result = Numerator / Denominator. */
460 div_and_round_double (EXACT_DIV_EXPR, 1, lnum, hnum, ldenom, hdenom,
461 &lres, &hres, &ldum, &hdum);
463 res = build_int_cst_wide (type, lres, hres);
464 return int_fits_type_p (res, type) ? res : NULL_TREE;
467 /* Helper function. Use the Newton's interpolating formula for
468 evaluating the value of the evolution function. */
471 chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
473 tree arg0, arg1, binomial_n_k;
474 tree type = TREE_TYPE (chrec);
476 while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
477 && CHREC_VARIABLE (chrec) > var)
478 chrec = CHREC_LEFT (chrec);
480 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
481 && CHREC_VARIABLE (chrec) == var)
483 arg0 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1);
484 if (arg0 == chrec_dont_know)
485 return chrec_dont_know;
486 binomial_n_k = tree_fold_binomial (type, n, k);
488 return chrec_dont_know;
489 arg1 = fold_build2 (MULT_EXPR, type,
490 CHREC_LEFT (chrec), binomial_n_k);
491 return chrec_fold_plus (type, arg0, arg1);
494 binomial_n_k = tree_fold_binomial (type, n, k);
496 return chrec_dont_know;
498 return fold_build2 (MULT_EXPR, type, chrec, binomial_n_k);
501 /* Evaluates "CHREC (X)" when the varying variable is VAR.
502 Example: Given the following parameters,
508 The result is given by the Newton's interpolating formula:
509 3 * \binom{10}{0} + 4 * \binom{10}{1}.
513 chrec_apply (unsigned var,
517 tree type = chrec_type (chrec);
518 tree res = chrec_dont_know;
520 if (automatically_generated_chrec_p (chrec)
521 || automatically_generated_chrec_p (x)
523 /* When the symbols are defined in an outer loop, it is possible
524 to symbolically compute the apply, since the symbols are
525 constants with respect to the varying loop. */
526 || chrec_contains_symbols_defined_in_loop (chrec, var)
527 || chrec_contains_symbols (x))
528 return chrec_dont_know;
530 if (dump_file && (dump_flags & TDF_DETAILS))
531 fprintf (dump_file, "(chrec_apply \n");
533 if (evolution_function_is_affine_p (chrec))
535 /* "{a, +, b} (x)" -> "a + b*x". */
536 if (TREE_CODE (CHREC_LEFT (chrec)) == INTEGER_CST
537 && integer_zerop (CHREC_LEFT (chrec)))
538 res = chrec_fold_multiply (type, CHREC_RIGHT (chrec), x);
541 res = chrec_fold_plus (type, CHREC_LEFT (chrec),
542 chrec_fold_multiply (type,
543 CHREC_RIGHT (chrec), x));
546 else if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
549 else if (TREE_CODE (x) == INTEGER_CST
550 && tree_int_cst_sgn (x) == 1)
551 /* testsuite/.../ssa-chrec-38.c. */
552 res = chrec_evaluate (var, chrec, x, 0);
555 res = chrec_dont_know;
557 if (dump_file && (dump_flags & TDF_DETAILS))
559 fprintf (dump_file, " (varying_loop = %d\n", var);
560 fprintf (dump_file, ")\n (chrec = ");
561 print_generic_expr (dump_file, chrec, 0);
562 fprintf (dump_file, ")\n (x = ");
563 print_generic_expr (dump_file, x, 0);
564 fprintf (dump_file, ")\n (res = ");
565 print_generic_expr (dump_file, res, 0);
566 fprintf (dump_file, "))\n");
572 /* Replaces the initial condition in CHREC with INIT_COND. */
575 chrec_replace_initial_condition (tree chrec,
578 if (automatically_generated_chrec_p (chrec))
581 switch (TREE_CODE (chrec))
583 case POLYNOMIAL_CHREC:
584 return build_polynomial_chrec
585 (CHREC_VARIABLE (chrec),
586 chrec_replace_initial_condition (CHREC_LEFT (chrec), init_cond),
587 CHREC_RIGHT (chrec));
594 /* Returns the initial condition of a given CHREC. */
597 initial_condition (tree chrec)
599 if (automatically_generated_chrec_p (chrec))
602 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
603 return initial_condition (CHREC_LEFT (chrec));
608 /* Returns a univariate function that represents the evolution in
609 LOOP_NUM. Mask the evolution of any other loop. */
612 hide_evolution_in_other_loops_than_loop (tree chrec,
615 if (automatically_generated_chrec_p (chrec))
618 switch (TREE_CODE (chrec))
620 case POLYNOMIAL_CHREC:
621 if (CHREC_VARIABLE (chrec) == loop_num)
622 return build_polynomial_chrec
624 hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
626 CHREC_RIGHT (chrec));
628 else if (CHREC_VARIABLE (chrec) < loop_num)
629 /* There is no evolution in this loop. */
630 return initial_condition (chrec);
633 return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
641 /* Returns the evolution part of CHREC in LOOP_NUM when RIGHT is
642 true, otherwise returns the initial condition in LOOP_NUM. */
645 chrec_component_in_loop_num (tree chrec,
651 if (automatically_generated_chrec_p (chrec))
654 switch (TREE_CODE (chrec))
656 case POLYNOMIAL_CHREC:
657 if (CHREC_VARIABLE (chrec) == loop_num)
660 component = CHREC_RIGHT (chrec);
662 component = CHREC_LEFT (chrec);
664 if (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC
665 || CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec))
669 return build_polynomial_chrec
671 chrec_component_in_loop_num (CHREC_LEFT (chrec),
677 else if (CHREC_VARIABLE (chrec) < loop_num)
678 /* There is no evolution part in this loop. */
682 return chrec_component_in_loop_num (CHREC_LEFT (chrec),
694 /* Returns the evolution part in LOOP_NUM. Example: the call
695 evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns
699 evolution_part_in_loop_num (tree chrec,
702 return chrec_component_in_loop_num (chrec, loop_num, true);
705 /* Returns the initial condition in LOOP_NUM. Example: the call
706 initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns
710 initial_condition_in_loop_num (tree chrec,
713 return chrec_component_in_loop_num (chrec, loop_num, false);
716 /* Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
717 This function is essentially used for setting the evolution to
718 chrec_dont_know, for example after having determined that it is
719 impossible to say how many times a loop will execute. */
722 reset_evolution_in_loop (unsigned loop_num,
726 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
727 && CHREC_VARIABLE (chrec) > loop_num)
730 build_int_cst (NULL_TREE, CHREC_VARIABLE (chrec)),
731 reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec), new_evol),
732 reset_evolution_in_loop (loop_num, CHREC_RIGHT (chrec), new_evol));
734 while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
735 && CHREC_VARIABLE (chrec) == loop_num)
736 chrec = CHREC_LEFT (chrec);
738 return build_polynomial_chrec (loop_num, chrec, new_evol);
741 /* Merges two evolution functions that were found by following two
742 alternate paths of a conditional expression. */
745 chrec_merge (tree chrec1,
748 if (chrec1 == chrec_dont_know
749 || chrec2 == chrec_dont_know)
750 return chrec_dont_know;
752 if (chrec1 == chrec_known
753 || chrec2 == chrec_known)
756 if (chrec1 == chrec_not_analyzed_yet)
758 if (chrec2 == chrec_not_analyzed_yet)
761 if (operand_equal_p (chrec1, chrec2, 0))
764 return chrec_dont_know;
771 /* Helper function for is_multivariate_chrec. */
774 is_multivariate_chrec_rec (tree chrec, unsigned int rec_var)
776 if (chrec == NULL_TREE)
779 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
781 if (CHREC_VARIABLE (chrec) != rec_var)
784 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec), rec_var)
785 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec), rec_var));
791 /* Determine whether the given chrec is multivariate or not. */
794 is_multivariate_chrec (tree chrec)
796 if (chrec == NULL_TREE)
799 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
800 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec),
801 CHREC_VARIABLE (chrec))
802 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec),
803 CHREC_VARIABLE (chrec)));
808 /* Determines whether the chrec contains symbolic names or not. */
811 chrec_contains_symbols (tree chrec)
813 if (chrec == NULL_TREE)
816 if (TREE_CODE (chrec) == SSA_NAME
817 || TREE_CODE (chrec) == VAR_DECL
818 || TREE_CODE (chrec) == PARM_DECL
819 || TREE_CODE (chrec) == FUNCTION_DECL
820 || TREE_CODE (chrec) == LABEL_DECL
821 || TREE_CODE (chrec) == RESULT_DECL
822 || TREE_CODE (chrec) == FIELD_DECL)
825 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
828 if (chrec_contains_symbols (TREE_OPERAND (chrec, 2)))
832 if (chrec_contains_symbols (TREE_OPERAND (chrec, 1)))
836 if (chrec_contains_symbols (TREE_OPERAND (chrec, 0)))
844 /* Determines whether the chrec contains undetermined coefficients. */
847 chrec_contains_undetermined (tree chrec)
849 if (chrec == chrec_dont_know
850 || chrec == chrec_not_analyzed_yet
851 || chrec == NULL_TREE)
854 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
857 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 2)))
861 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 1)))
865 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 0)))
873 /* Determines whether the tree EXPR contains chrecs, and increment
874 SIZE if it is not a NULL pointer by an estimation of the depth of
878 tree_contains_chrecs (tree expr, int *size)
880 if (expr == NULL_TREE)
886 if (tree_is_chrec (expr))
889 switch (TREE_CODE_LENGTH (TREE_CODE (expr)))
892 if (tree_contains_chrecs (TREE_OPERAND (expr, 2), size))
896 if (tree_contains_chrecs (TREE_OPERAND (expr, 1), size))
900 if (tree_contains_chrecs (TREE_OPERAND (expr, 0), size))
908 /* Determine whether the given tree is an affine multivariate
912 evolution_function_is_affine_multivariate_p (tree chrec)
914 if (chrec == NULL_TREE)
917 switch (TREE_CODE (chrec))
919 case POLYNOMIAL_CHREC:
920 if (evolution_function_is_constant_p (CHREC_LEFT (chrec)))
922 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec)))
926 if (TREE_CODE (CHREC_RIGHT (chrec)) == POLYNOMIAL_CHREC
927 && CHREC_VARIABLE (CHREC_RIGHT (chrec))
928 != CHREC_VARIABLE (chrec)
929 && evolution_function_is_affine_multivariate_p
930 (CHREC_RIGHT (chrec)))
938 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec))
939 && TREE_CODE (CHREC_LEFT (chrec)) == POLYNOMIAL_CHREC
940 && CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec)
941 && evolution_function_is_affine_multivariate_p
942 (CHREC_LEFT (chrec)))
953 /* Determine whether the given tree is a function in zero or one
957 evolution_function_is_univariate_p (tree chrec)
959 if (chrec == NULL_TREE)
962 switch (TREE_CODE (chrec))
964 case POLYNOMIAL_CHREC:
965 switch (TREE_CODE (CHREC_LEFT (chrec)))
967 case POLYNOMIAL_CHREC:
968 if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_LEFT (chrec)))
970 if (!evolution_function_is_univariate_p (CHREC_LEFT (chrec)))
978 switch (TREE_CODE (CHREC_RIGHT (chrec)))
980 case POLYNOMIAL_CHREC:
981 if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_RIGHT (chrec)))
983 if (!evolution_function_is_univariate_p (CHREC_RIGHT (chrec)))
996 /* Returns the number of variables of CHREC. Example: the call
997 nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2. */
1000 nb_vars_in_chrec (tree chrec)
1002 if (chrec == NULL_TREE)
1005 switch (TREE_CODE (chrec))
1007 case POLYNOMIAL_CHREC:
1008 return 1 + nb_vars_in_chrec
1009 (initial_condition_in_loop_num (chrec, CHREC_VARIABLE (chrec)));
1018 /* Convert CHREC to TYPE. The following is rule is always true:
1019 TREE_TYPE (chrec) == TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE
1020 (CHREC_RIGHT (chrec)). An example of what could happen when adding
1021 two chrecs and the type of the CHREC_RIGHT is different than
1024 {(uint) 0, +, (uchar) 10} +
1025 {(uint) 0, +, (uchar) 250}
1027 that would produce a wrong result if CHREC_RIGHT is not (uint):
1029 {(uint) 0, +, (uchar) 4}
1033 {(uint) 0, +, (uint) 260}
1037 chrec_convert (tree type,
1042 if (automatically_generated_chrec_p (chrec))
1045 ct = chrec_type (chrec);
1049 if (TYPE_PRECISION (ct) < TYPE_PRECISION (type))
1050 return count_ev_in_wider_type (type, chrec);
1052 switch (TREE_CODE (chrec))
1054 case POLYNOMIAL_CHREC:
1055 return build_polynomial_chrec (CHREC_VARIABLE (chrec),
1056 chrec_convert (type,
1057 CHREC_LEFT (chrec)),
1058 chrec_convert (type,
1059 CHREC_RIGHT (chrec)));
1063 tree res = fold_convert (type, chrec);
1065 /* Don't propagate overflows. */
1066 if (CONSTANT_CLASS_P (res))
1068 TREE_CONSTANT_OVERFLOW (res) = 0;
1069 TREE_OVERFLOW (res) = 0;
1072 /* But reject constants that don't fit in their type after conversion.
1073 This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the
1074 natural values associated with TYPE_PRECISION and TYPE_UNSIGNED,
1075 and can cause problems later when computing niters of loops. Note
1076 that we don't do the check before converting because we don't want
1077 to reject conversions of negative chrecs to unsigned types. */
1078 if (TREE_CODE (res) == INTEGER_CST
1079 && TREE_CODE (type) == INTEGER_TYPE
1080 && !int_fits_type_p (res, type))
1081 res = chrec_dont_know;
1088 /* Returns the type of the chrec. */
1091 chrec_type (tree chrec)
1093 if (automatically_generated_chrec_p (chrec))
1096 return TREE_TYPE (chrec);