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, 51 Franklin Street, Fifth Floor, 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"
36 #include "tree-flow.h"
37 #include "tree-chrec.h"
38 #include "tree-pass.h"
43 /* Extended folder for chrecs. */
45 /* Determines whether CST is not a constant evolution. */
48 is_not_constant_evolution (tree cst
)
50 return (TREE_CODE (cst
) == POLYNOMIAL_CHREC
);
53 /* Fold CODE for a polynomial function and a constant. */
56 chrec_fold_poly_cst (enum tree_code code
,
63 gcc_assert (TREE_CODE (poly
) == POLYNOMIAL_CHREC
);
64 gcc_assert (!is_not_constant_evolution (cst
));
69 return build_polynomial_chrec
70 (CHREC_VARIABLE (poly
),
71 chrec_fold_plus (type
, CHREC_LEFT (poly
), cst
),
75 return build_polynomial_chrec
76 (CHREC_VARIABLE (poly
),
77 chrec_fold_minus (type
, CHREC_LEFT (poly
), cst
),
81 return build_polynomial_chrec
82 (CHREC_VARIABLE (poly
),
83 chrec_fold_multiply (type
, CHREC_LEFT (poly
), cst
),
84 chrec_fold_multiply (type
, CHREC_RIGHT (poly
), cst
));
87 return chrec_dont_know
;
91 /* Fold the addition of two polynomial functions. */
94 chrec_fold_plus_poly_poly (enum tree_code code
,
103 gcc_assert (TREE_CODE (poly0
) == POLYNOMIAL_CHREC
);
104 gcc_assert (TREE_CODE (poly1
) == POLYNOMIAL_CHREC
);
107 {a, +, b}_1 + {c, +, d}_2 -> {{a, +, b}_1 + c, +, d}_2,
108 {a, +, b}_2 + {c, +, d}_1 -> {{c, +, d}_1 + a, +, b}_2,
109 {a, +, b}_x + {c, +, d}_x -> {a+c, +, b+d}_x. */
110 if (CHREC_VARIABLE (poly0
) < CHREC_VARIABLE (poly1
))
112 if (code
== PLUS_EXPR
)
113 return build_polynomial_chrec
114 (CHREC_VARIABLE (poly1
),
115 chrec_fold_plus (type
, poly0
, CHREC_LEFT (poly1
)),
116 CHREC_RIGHT (poly1
));
118 return build_polynomial_chrec
119 (CHREC_VARIABLE (poly1
),
120 chrec_fold_minus (type
, poly0
, CHREC_LEFT (poly1
)),
121 chrec_fold_multiply (type
, CHREC_RIGHT (poly1
),
122 build_int_cst_type (type
, -1)));
125 if (CHREC_VARIABLE (poly0
) > CHREC_VARIABLE (poly1
))
127 if (code
== PLUS_EXPR
)
128 return build_polynomial_chrec
129 (CHREC_VARIABLE (poly0
),
130 chrec_fold_plus (type
, CHREC_LEFT (poly0
), poly1
),
131 CHREC_RIGHT (poly0
));
133 return build_polynomial_chrec
134 (CHREC_VARIABLE (poly0
),
135 chrec_fold_minus (type
, CHREC_LEFT (poly0
), poly1
),
136 CHREC_RIGHT (poly0
));
139 if (code
== PLUS_EXPR
)
141 left
= chrec_fold_plus
142 (type
, CHREC_LEFT (poly0
), CHREC_LEFT (poly1
));
143 right
= chrec_fold_plus
144 (type
, CHREC_RIGHT (poly0
), CHREC_RIGHT (poly1
));
148 left
= chrec_fold_minus
149 (type
, CHREC_LEFT (poly0
), CHREC_LEFT (poly1
));
150 right
= chrec_fold_minus
151 (type
, CHREC_RIGHT (poly0
), CHREC_RIGHT (poly1
));
154 if (chrec_zerop (right
))
157 return build_polynomial_chrec
158 (CHREC_VARIABLE (poly0
), left
, right
);
163 /* Fold the multiplication of two polynomial functions. */
166 chrec_fold_multiply_poly_poly (tree type
,
172 gcc_assert (TREE_CODE (poly0
) == POLYNOMIAL_CHREC
);
173 gcc_assert (TREE_CODE (poly1
) == POLYNOMIAL_CHREC
);
175 /* {a, +, b}_1 * {c, +, d}_2 -> {c*{a, +, b}_1, +, d}_2,
176 {a, +, b}_2 * {c, +, d}_1 -> {a*{c, +, d}_1, +, b}_2,
177 {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
178 if (CHREC_VARIABLE (poly0
) < CHREC_VARIABLE (poly1
))
179 /* poly0 is a constant wrt. poly1. */
180 return build_polynomial_chrec
181 (CHREC_VARIABLE (poly1
),
182 chrec_fold_multiply (type
, CHREC_LEFT (poly1
), poly0
),
183 CHREC_RIGHT (poly1
));
185 if (CHREC_VARIABLE (poly1
) < CHREC_VARIABLE (poly0
))
186 /* poly1 is a constant wrt. poly0. */
187 return build_polynomial_chrec
188 (CHREC_VARIABLE (poly0
),
189 chrec_fold_multiply (type
, CHREC_LEFT (poly0
), poly1
),
190 CHREC_RIGHT (poly0
));
192 /* poly0 and poly1 are two polynomials in the same variable,
193 {a, +, b}_x * {c, +, d}_x -> {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x. */
195 build_polynomial_chrec
196 (CHREC_VARIABLE (poly0
),
197 build_polynomial_chrec
198 (CHREC_VARIABLE (poly0
),
201 chrec_fold_multiply (type
, CHREC_LEFT (poly0
), CHREC_LEFT (poly1
)),
203 /* "a*d + b*c + b*d". */
205 (type
, chrec_fold_multiply (type
, CHREC_LEFT (poly0
), CHREC_RIGHT (poly1
)),
209 chrec_fold_multiply (type
, CHREC_RIGHT (poly0
), CHREC_LEFT (poly1
)),
210 chrec_fold_multiply (type
, CHREC_RIGHT (poly0
), CHREC_RIGHT (poly1
))))),
214 (type
, build_int_cst (NULL_TREE
, 2),
215 chrec_fold_multiply (type
, CHREC_RIGHT (poly0
), CHREC_RIGHT (poly1
))));
218 /* When the operands are automatically_generated_chrec_p, the fold has
219 to respect the semantics of the operands. */
222 chrec_fold_automatically_generated_operands (tree op0
,
225 if (op0
== chrec_dont_know
226 || op1
== chrec_dont_know
)
227 return chrec_dont_know
;
229 if (op0
== chrec_known
230 || op1
== chrec_known
)
233 if (op0
== chrec_not_analyzed_yet
234 || op1
== chrec_not_analyzed_yet
)
235 return chrec_not_analyzed_yet
;
237 /* The default case produces a safe result. */
238 return chrec_dont_know
;
241 /* Fold the addition of two chrecs. */
244 chrec_fold_plus_1 (enum tree_code code
,
249 if (automatically_generated_chrec_p (op0
)
250 || automatically_generated_chrec_p (op1
))
251 return chrec_fold_automatically_generated_operands (op0
, op1
);
253 switch (TREE_CODE (op0
))
255 case POLYNOMIAL_CHREC
:
256 switch (TREE_CODE (op1
))
258 case POLYNOMIAL_CHREC
:
259 return chrec_fold_plus_poly_poly (code
, type
, op0
, op1
);
262 if (code
== PLUS_EXPR
)
263 return build_polynomial_chrec
264 (CHREC_VARIABLE (op0
),
265 chrec_fold_plus (type
, CHREC_LEFT (op0
), op1
),
268 return build_polynomial_chrec
269 (CHREC_VARIABLE (op0
),
270 chrec_fold_minus (type
, CHREC_LEFT (op0
), op1
),
275 switch (TREE_CODE (op1
))
277 case POLYNOMIAL_CHREC
:
278 if (code
== PLUS_EXPR
)
279 return build_polynomial_chrec
280 (CHREC_VARIABLE (op1
),
281 chrec_fold_plus (type
, op0
, CHREC_LEFT (op1
)),
284 return build_polynomial_chrec
285 (CHREC_VARIABLE (op1
),
286 chrec_fold_minus (type
, op0
, CHREC_LEFT (op1
)),
287 chrec_fold_multiply (type
, CHREC_RIGHT (op1
),
288 build_int_cst_type (type
, -1)));
293 if ((tree_contains_chrecs (op0
, &size
)
294 || tree_contains_chrecs (op1
, &size
))
295 && size
< PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE
))
296 return build2 (code
, type
, op0
, op1
);
297 else if (size
< PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE
))
298 return fold_build2 (code
, type
,
299 fold_convert (type
, op0
),
300 fold_convert (type
, op1
));
302 return chrec_dont_know
;
308 /* Fold the addition of two chrecs. */
311 chrec_fold_plus (tree type
,
315 if (integer_zerop (op0
))
317 if (integer_zerop (op1
))
320 return chrec_fold_plus_1 (PLUS_EXPR
, type
, op0
, op1
);
323 /* Fold the subtraction of two chrecs. */
326 chrec_fold_minus (tree type
,
330 if (integer_zerop (op1
))
333 return chrec_fold_plus_1 (MINUS_EXPR
, type
, op0
, op1
);
336 /* Fold the multiplication of two chrecs. */
339 chrec_fold_multiply (tree type
,
343 if (automatically_generated_chrec_p (op0
)
344 || automatically_generated_chrec_p (op1
))
345 return chrec_fold_automatically_generated_operands (op0
, op1
);
347 switch (TREE_CODE (op0
))
349 case POLYNOMIAL_CHREC
:
350 switch (TREE_CODE (op1
))
352 case POLYNOMIAL_CHREC
:
353 return chrec_fold_multiply_poly_poly (type
, op0
, op1
);
356 if (integer_onep (op1
))
358 if (integer_zerop (op1
))
359 return build_int_cst_type (type
, 0);
361 return build_polynomial_chrec
362 (CHREC_VARIABLE (op0
),
363 chrec_fold_multiply (type
, CHREC_LEFT (op0
), op1
),
364 chrec_fold_multiply (type
, CHREC_RIGHT (op0
), op1
));
368 if (integer_onep (op0
))
371 if (integer_zerop (op0
))
372 return build_int_cst_type (type
, 0);
374 switch (TREE_CODE (op1
))
376 case POLYNOMIAL_CHREC
:
377 return build_polynomial_chrec
378 (CHREC_VARIABLE (op1
),
379 chrec_fold_multiply (type
, CHREC_LEFT (op1
), op0
),
380 chrec_fold_multiply (type
, CHREC_RIGHT (op1
), op0
));
383 if (integer_onep (op1
))
385 if (integer_zerop (op1
))
386 return build_int_cst_type (type
, 0);
387 return fold_build2 (MULT_EXPR
, type
, op0
, op1
);
396 /* Evaluate the binomial coefficient. Return NULL_TREE if the intermediate
397 calculation overflows, otherwise return C(n,k) with type TYPE. */
400 tree_fold_binomial (tree type
, tree n
, unsigned int k
)
402 unsigned HOST_WIDE_INT lidx
, lnum
, ldenom
, lres
, ldum
;
403 HOST_WIDE_INT hidx
, hnum
, hdenom
, hres
, hdum
;
407 /* Handle the most frequent cases. */
409 return build_int_cst (type
, 1);
411 return fold_convert (type
, n
);
413 /* Check that k <= n. */
414 if (TREE_INT_CST_HIGH (n
) == 0
415 && TREE_INT_CST_LOW (n
) < k
)
419 lnum
= TREE_INT_CST_LOW (n
);
420 hnum
= TREE_INT_CST_HIGH (n
);
422 /* Denominator = 2. */
426 /* Index = Numerator-1. */
430 lidx
= ~ (unsigned HOST_WIDE_INT
) 0;
438 /* Numerator = Numerator*Index = n*(n-1). */
439 if (mul_double (lnum
, hnum
, lidx
, hidx
, &lnum
, &hnum
))
442 for (i
= 3; i
<= k
; i
++)
448 lidx
= ~ (unsigned HOST_WIDE_INT
) 0;
453 /* Numerator *= Index. */
454 if (mul_double (lnum
, hnum
, lidx
, hidx
, &lnum
, &hnum
))
457 /* Denominator *= i. */
458 mul_double (ldenom
, hdenom
, i
, 0, &ldenom
, &hdenom
);
461 /* Result = Numerator / Denominator. */
462 div_and_round_double (EXACT_DIV_EXPR
, 1, lnum
, hnum
, ldenom
, hdenom
,
463 &lres
, &hres
, &ldum
, &hdum
);
465 res
= build_int_cst_wide (type
, lres
, hres
);
466 return int_fits_type_p (res
, type
) ? res
: NULL_TREE
;
469 /* Helper function. Use the Newton's interpolating formula for
470 evaluating the value of the evolution function. */
473 chrec_evaluate (unsigned var
, tree chrec
, tree n
, unsigned int k
)
475 tree arg0
, arg1
, binomial_n_k
;
476 tree type
= TREE_TYPE (chrec
);
478 while (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
479 && CHREC_VARIABLE (chrec
) > var
)
480 chrec
= CHREC_LEFT (chrec
);
482 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
483 && CHREC_VARIABLE (chrec
) == var
)
485 arg0
= chrec_evaluate (var
, CHREC_RIGHT (chrec
), n
, k
+ 1);
486 if (arg0
== chrec_dont_know
)
487 return chrec_dont_know
;
488 binomial_n_k
= tree_fold_binomial (type
, n
, k
);
490 return chrec_dont_know
;
491 arg1
= fold_build2 (MULT_EXPR
, type
,
492 CHREC_LEFT (chrec
), binomial_n_k
);
493 return chrec_fold_plus (type
, arg0
, arg1
);
496 binomial_n_k
= tree_fold_binomial (type
, n
, k
);
498 return chrec_dont_know
;
500 return fold_build2 (MULT_EXPR
, type
, chrec
, binomial_n_k
);
503 /* Evaluates "CHREC (X)" when the varying variable is VAR.
504 Example: Given the following parameters,
510 The result is given by the Newton's interpolating formula:
511 3 * \binom{10}{0} + 4 * \binom{10}{1}.
515 chrec_apply (unsigned var
,
519 tree type
= chrec_type (chrec
);
520 tree res
= chrec_dont_know
;
522 if (automatically_generated_chrec_p (chrec
)
523 || automatically_generated_chrec_p (x
)
525 /* When the symbols are defined in an outer loop, it is possible
526 to symbolically compute the apply, since the symbols are
527 constants with respect to the varying loop. */
528 || chrec_contains_symbols_defined_in_loop (chrec
, var
)
529 || chrec_contains_symbols (x
))
530 return chrec_dont_know
;
532 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
533 fprintf (dump_file
, "(chrec_apply \n");
535 if (evolution_function_is_affine_p (chrec
))
537 /* "{a, +, b} (x)" -> "a + b*x". */
538 if (TREE_CODE (CHREC_LEFT (chrec
)) == INTEGER_CST
539 && integer_zerop (CHREC_LEFT (chrec
)))
540 res
= chrec_fold_multiply (type
, CHREC_RIGHT (chrec
), x
);
543 res
= chrec_fold_plus (type
, CHREC_LEFT (chrec
),
544 chrec_fold_multiply (type
,
545 CHREC_RIGHT (chrec
), x
));
548 else if (TREE_CODE (chrec
) != POLYNOMIAL_CHREC
)
551 else if (TREE_CODE (x
) == INTEGER_CST
552 && tree_int_cst_sgn (x
) == 1)
553 /* testsuite/.../ssa-chrec-38.c. */
554 res
= chrec_evaluate (var
, chrec
, x
, 0);
557 res
= chrec_dont_know
;
559 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
561 fprintf (dump_file
, " (varying_loop = %d\n", var
);
562 fprintf (dump_file
, ")\n (chrec = ");
563 print_generic_expr (dump_file
, chrec
, 0);
564 fprintf (dump_file
, ")\n (x = ");
565 print_generic_expr (dump_file
, x
, 0);
566 fprintf (dump_file
, ")\n (res = ");
567 print_generic_expr (dump_file
, res
, 0);
568 fprintf (dump_file
, "))\n");
574 /* Replaces the initial condition in CHREC with INIT_COND. */
577 chrec_replace_initial_condition (tree chrec
,
580 if (automatically_generated_chrec_p (chrec
))
583 switch (TREE_CODE (chrec
))
585 case POLYNOMIAL_CHREC
:
586 return build_polynomial_chrec
587 (CHREC_VARIABLE (chrec
),
588 chrec_replace_initial_condition (CHREC_LEFT (chrec
), init_cond
),
589 CHREC_RIGHT (chrec
));
596 /* Returns the initial condition of a given CHREC. */
599 initial_condition (tree chrec
)
601 if (automatically_generated_chrec_p (chrec
))
604 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
)
605 return initial_condition (CHREC_LEFT (chrec
));
610 /* Returns a univariate function that represents the evolution in
611 LOOP_NUM. Mask the evolution of any other loop. */
614 hide_evolution_in_other_loops_than_loop (tree chrec
,
617 if (automatically_generated_chrec_p (chrec
))
620 switch (TREE_CODE (chrec
))
622 case POLYNOMIAL_CHREC
:
623 if (CHREC_VARIABLE (chrec
) == loop_num
)
624 return build_polynomial_chrec
626 hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec
),
628 CHREC_RIGHT (chrec
));
630 else if (CHREC_VARIABLE (chrec
) < loop_num
)
631 /* There is no evolution in this loop. */
632 return initial_condition (chrec
);
635 return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec
),
643 /* Returns the evolution part of CHREC in LOOP_NUM when RIGHT is
644 true, otherwise returns the initial condition in LOOP_NUM. */
647 chrec_component_in_loop_num (tree chrec
,
653 if (automatically_generated_chrec_p (chrec
))
656 switch (TREE_CODE (chrec
))
658 case POLYNOMIAL_CHREC
:
659 if (CHREC_VARIABLE (chrec
) == loop_num
)
662 component
= CHREC_RIGHT (chrec
);
664 component
= CHREC_LEFT (chrec
);
666 if (TREE_CODE (CHREC_LEFT (chrec
)) != POLYNOMIAL_CHREC
667 || CHREC_VARIABLE (CHREC_LEFT (chrec
)) != CHREC_VARIABLE (chrec
))
671 return build_polynomial_chrec
673 chrec_component_in_loop_num (CHREC_LEFT (chrec
),
679 else if (CHREC_VARIABLE (chrec
) < loop_num
)
680 /* There is no evolution part in this loop. */
684 return chrec_component_in_loop_num (CHREC_LEFT (chrec
),
696 /* Returns the evolution part in LOOP_NUM. Example: the call
697 evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns
701 evolution_part_in_loop_num (tree chrec
,
704 return chrec_component_in_loop_num (chrec
, loop_num
, true);
707 /* Returns the initial condition in LOOP_NUM. Example: the call
708 initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns
712 initial_condition_in_loop_num (tree chrec
,
715 return chrec_component_in_loop_num (chrec
, loop_num
, false);
718 /* Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
719 This function is essentially used for setting the evolution to
720 chrec_dont_know, for example after having determined that it is
721 impossible to say how many times a loop will execute. */
724 reset_evolution_in_loop (unsigned loop_num
,
728 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
729 && CHREC_VARIABLE (chrec
) > loop_num
)
731 tree left
= reset_evolution_in_loop (loop_num
, CHREC_LEFT (chrec
),
733 tree right
= reset_evolution_in_loop (loop_num
, CHREC_RIGHT (chrec
),
735 return build3 (POLYNOMIAL_CHREC
, TREE_TYPE (left
),
736 build_int_cst (NULL_TREE
, CHREC_VARIABLE (chrec
)),
740 while (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
741 && CHREC_VARIABLE (chrec
) == loop_num
)
742 chrec
= CHREC_LEFT (chrec
);
744 return build_polynomial_chrec (loop_num
, chrec
, new_evol
);
747 /* Merges two evolution functions that were found by following two
748 alternate paths of a conditional expression. */
751 chrec_merge (tree chrec1
,
754 if (chrec1
== chrec_dont_know
755 || chrec2
== chrec_dont_know
)
756 return chrec_dont_know
;
758 if (chrec1
== chrec_known
759 || chrec2
== chrec_known
)
762 if (chrec1
== chrec_not_analyzed_yet
)
764 if (chrec2
== chrec_not_analyzed_yet
)
767 if (operand_equal_p (chrec1
, chrec2
, 0))
770 return chrec_dont_know
;
777 /* Helper function for is_multivariate_chrec. */
780 is_multivariate_chrec_rec (tree chrec
, unsigned int rec_var
)
782 if (chrec
== NULL_TREE
)
785 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
)
787 if (CHREC_VARIABLE (chrec
) != rec_var
)
790 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec
), rec_var
)
791 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec
), rec_var
));
797 /* Determine whether the given chrec is multivariate or not. */
800 is_multivariate_chrec (tree chrec
)
802 if (chrec
== NULL_TREE
)
805 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
)
806 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec
),
807 CHREC_VARIABLE (chrec
))
808 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec
),
809 CHREC_VARIABLE (chrec
)));
814 /* Determines whether the chrec contains symbolic names or not. */
817 chrec_contains_symbols (tree chrec
)
819 if (chrec
== NULL_TREE
)
822 if (TREE_CODE (chrec
) == SSA_NAME
823 || TREE_CODE (chrec
) == VAR_DECL
824 || TREE_CODE (chrec
) == PARM_DECL
825 || TREE_CODE (chrec
) == FUNCTION_DECL
826 || TREE_CODE (chrec
) == LABEL_DECL
827 || TREE_CODE (chrec
) == RESULT_DECL
828 || TREE_CODE (chrec
) == FIELD_DECL
)
831 switch (TREE_CODE_LENGTH (TREE_CODE (chrec
)))
834 if (chrec_contains_symbols (TREE_OPERAND (chrec
, 2)))
838 if (chrec_contains_symbols (TREE_OPERAND (chrec
, 1)))
842 if (chrec_contains_symbols (TREE_OPERAND (chrec
, 0)))
850 /* Determines whether the chrec contains undetermined coefficients. */
853 chrec_contains_undetermined (tree chrec
)
855 if (chrec
== chrec_dont_know
856 || chrec
== chrec_not_analyzed_yet
857 || chrec
== NULL_TREE
)
860 switch (TREE_CODE_LENGTH (TREE_CODE (chrec
)))
863 if (chrec_contains_undetermined (TREE_OPERAND (chrec
, 2)))
867 if (chrec_contains_undetermined (TREE_OPERAND (chrec
, 1)))
871 if (chrec_contains_undetermined (TREE_OPERAND (chrec
, 0)))
879 /* Determines whether the tree EXPR contains chrecs, and increment
880 SIZE if it is not a NULL pointer by an estimation of the depth of
884 tree_contains_chrecs (tree expr
, int *size
)
886 if (expr
== NULL_TREE
)
892 if (tree_is_chrec (expr
))
895 switch (TREE_CODE_LENGTH (TREE_CODE (expr
)))
898 if (tree_contains_chrecs (TREE_OPERAND (expr
, 2), size
))
902 if (tree_contains_chrecs (TREE_OPERAND (expr
, 1), size
))
906 if (tree_contains_chrecs (TREE_OPERAND (expr
, 0), size
))
914 /* Recursive helper function. */
917 evolution_function_is_invariant_rec_p (tree chrec
, int loopnum
)
919 if (evolution_function_is_constant_p (chrec
))
922 if (TREE_CODE (chrec
) == SSA_NAME
923 && expr_invariant_in_loop_p (current_loops
->parray
[loopnum
],
927 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
928 && CHREC_VARIABLE (chrec
) == (unsigned) loopnum
)
931 switch (TREE_CODE_LENGTH (TREE_CODE (chrec
)))
934 if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec
, 1),
939 if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec
, 0),
951 /* Return true if CHREC is invariant in loop LOOPNUM, false otherwise. */
954 evolution_function_is_invariant_p (tree chrec
, int loopnum
)
956 if (evolution_function_is_constant_p (chrec
))
959 if (current_loops
!= NULL
)
960 return evolution_function_is_invariant_rec_p (chrec
, loopnum
);
965 /* Determine whether the given tree is an affine multivariate
969 evolution_function_is_affine_multivariate_p (tree chrec
)
971 if (chrec
== NULL_TREE
)
974 switch (TREE_CODE (chrec
))
976 case POLYNOMIAL_CHREC
:
977 if (evolution_function_is_constant_p (CHREC_LEFT (chrec
)))
979 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec
)))
983 if (TREE_CODE (CHREC_RIGHT (chrec
)) == POLYNOMIAL_CHREC
984 && CHREC_VARIABLE (CHREC_RIGHT (chrec
))
985 != CHREC_VARIABLE (chrec
)
986 && evolution_function_is_affine_multivariate_p
987 (CHREC_RIGHT (chrec
)))
995 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec
))
996 && TREE_CODE (CHREC_LEFT (chrec
)) == POLYNOMIAL_CHREC
997 && CHREC_VARIABLE (CHREC_LEFT (chrec
)) != CHREC_VARIABLE (chrec
)
998 && evolution_function_is_affine_multivariate_p
999 (CHREC_LEFT (chrec
)))
1010 /* Determine whether the given tree is a function in zero or one
1014 evolution_function_is_univariate_p (tree chrec
)
1016 if (chrec
== NULL_TREE
)
1019 switch (TREE_CODE (chrec
))
1021 case POLYNOMIAL_CHREC
:
1022 switch (TREE_CODE (CHREC_LEFT (chrec
)))
1024 case POLYNOMIAL_CHREC
:
1025 if (CHREC_VARIABLE (chrec
) != CHREC_VARIABLE (CHREC_LEFT (chrec
)))
1027 if (!evolution_function_is_univariate_p (CHREC_LEFT (chrec
)))
1035 switch (TREE_CODE (CHREC_RIGHT (chrec
)))
1037 case POLYNOMIAL_CHREC
:
1038 if (CHREC_VARIABLE (chrec
) != CHREC_VARIABLE (CHREC_RIGHT (chrec
)))
1040 if (!evolution_function_is_univariate_p (CHREC_RIGHT (chrec
)))
1053 /* Returns the number of variables of CHREC. Example: the call
1054 nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2. */
1057 nb_vars_in_chrec (tree chrec
)
1059 if (chrec
== NULL_TREE
)
1062 switch (TREE_CODE (chrec
))
1064 case POLYNOMIAL_CHREC
:
1065 return 1 + nb_vars_in_chrec
1066 (initial_condition_in_loop_num (chrec
, CHREC_VARIABLE (chrec
)));
1075 /* Convert CHREC to TYPE. When the analyzer knows the context in
1076 which the CHREC is built, it sets AT_STMT to the statement that
1077 contains the definition of the analyzed variable, otherwise the
1078 conversion is less accurate: the information is used for
1079 determining a more accurate estimation of the number of iterations.
1080 By default AT_STMT could be safely set to NULL_TREE.
1082 The following rule is always true: TREE_TYPE (chrec) ==
1083 TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE (CHREC_RIGHT (chrec)).
1084 An example of what could happen when adding two chrecs and the type
1085 of the CHREC_RIGHT is different than CHREC_LEFT is:
1087 {(uint) 0, +, (uchar) 10} +
1088 {(uint) 0, +, (uchar) 250}
1090 that would produce a wrong result if CHREC_RIGHT is not (uint):
1092 {(uint) 0, +, (uchar) 4}
1096 {(uint) 0, +, (uint) 260}
1100 chrec_convert (tree type
, tree chrec
, tree at_stmt
)
1104 if (automatically_generated_chrec_p (chrec
))
1107 ct
= chrec_type (chrec
);
1111 if (evolution_function_is_affine_p (chrec
))
1113 tree step
= convert_step (current_loops
->parray
[CHREC_VARIABLE (chrec
)],
1114 type
, CHREC_LEFT (chrec
), CHREC_RIGHT (chrec
),
1117 return fold_convert (type
, chrec
);
1119 return build_polynomial_chrec (CHREC_VARIABLE (chrec
),
1120 chrec_convert (type
, CHREC_LEFT (chrec
),
1125 if (TREE_CODE (chrec
) == POLYNOMIAL_CHREC
)
1126 return chrec_dont_know
;
1128 res
= fold_convert (type
, chrec
);
1130 /* Don't propagate overflows. */
1131 if (CONSTANT_CLASS_P (res
))
1133 TREE_CONSTANT_OVERFLOW (res
) = 0;
1134 TREE_OVERFLOW (res
) = 0;
1137 /* But reject constants that don't fit in their type after conversion.
1138 This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the
1139 natural values associated with TYPE_PRECISION and TYPE_UNSIGNED,
1140 and can cause problems later when computing niters of loops. Note
1141 that we don't do the check before converting because we don't want
1142 to reject conversions of negative chrecs to unsigned types. */
1143 if (TREE_CODE (res
) == INTEGER_CST
1144 && TREE_CODE (type
) == INTEGER_TYPE
1145 && !int_fits_type_p (res
, type
))
1146 res
= chrec_dont_know
;
1151 /* Returns the type of the chrec. */
1154 chrec_type (tree chrec
)
1156 if (automatically_generated_chrec_p (chrec
))
1159 return TREE_TYPE (chrec
);