re PR tree-optimization/19903 (ACATS cxa4006 cxa4017 fail at runtime)
[gcc.git] / gcc / tree-chrec.c
1 /* Chains of recurrences.
2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <s.pop@laposte.net>
4
5 This file is part of GCC.
6
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
10 version.
11
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
15 for more details.
16
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
20 02111-1307, USA. */
21
22 /* This file implements operations on chains of recurrences. Chains
23 of recurrences are used for modeling evolution functions of scalar
24 variables.
25 */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "errors.h"
32 #include "ggc.h"
33 #include "tree.h"
34 #include "diagnostic.h"
35 #include "varray.h"
36 #include "tree-chrec.h"
37 #include "tree-pass.h"
38
39 \f
40
41 /* Extended folder for chrecs. */
42
43 /* Determines whether CST is not a constant evolution. */
44
45 static inline bool
46 is_not_constant_evolution (tree cst)
47 {
48 return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
49 }
50
51 /* Fold CODE for a polynomial function and a constant. */
52
53 static inline tree
54 chrec_fold_poly_cst (enum tree_code code,
55 tree type,
56 tree poly,
57 tree cst)
58 {
59 gcc_assert (poly);
60 gcc_assert (cst);
61 gcc_assert (TREE_CODE (poly) == POLYNOMIAL_CHREC);
62 gcc_assert (!is_not_constant_evolution (cst));
63
64 switch (code)
65 {
66 case PLUS_EXPR:
67 return build_polynomial_chrec
68 (CHREC_VARIABLE (poly),
69 chrec_fold_plus (type, CHREC_LEFT (poly), cst),
70 CHREC_RIGHT (poly));
71
72 case MINUS_EXPR:
73 return build_polynomial_chrec
74 (CHREC_VARIABLE (poly),
75 chrec_fold_minus (type, CHREC_LEFT (poly), cst),
76 CHREC_RIGHT (poly));
77
78 case MULT_EXPR:
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));
83
84 default:
85 return chrec_dont_know;
86 }
87 }
88
89 /* Fold the addition of two polynomial functions. */
90
91 static inline tree
92 chrec_fold_plus_poly_poly (enum tree_code code,
93 tree type,
94 tree poly0,
95 tree poly1)
96 {
97 tree left, right;
98
99 gcc_assert (poly0);
100 gcc_assert (poly1);
101 gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
102 gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
103
104 /*
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))
109 {
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));
115 else
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)));
121 }
122
123 if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
124 {
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));
130 else
131 return build_polynomial_chrec
132 (CHREC_VARIABLE (poly0),
133 chrec_fold_minus (type, CHREC_LEFT (poly0), poly1),
134 CHREC_RIGHT (poly0));
135 }
136
137 if (code == PLUS_EXPR)
138 {
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));
143 }
144 else
145 {
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));
150 }
151
152 if (chrec_zerop (right))
153 return left;
154 else
155 return build_polynomial_chrec
156 (CHREC_VARIABLE (poly0), left, right);
157 }
158
159 \f
160
161 /* Fold the multiplication of two polynomial functions. */
162
163 static inline tree
164 chrec_fold_multiply_poly_poly (tree type,
165 tree poly0,
166 tree poly1)
167 {
168 gcc_assert (poly0);
169 gcc_assert (poly1);
170 gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
171 gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
172
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));
182
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));
189
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. */
192 return
193 build_polynomial_chrec
194 (CHREC_VARIABLE (poly0),
195 build_polynomial_chrec
196 (CHREC_VARIABLE (poly0),
197
198 /* "a*c". */
199 chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1)),
200
201 /* "a*d + b*c + b*d". */
202 chrec_fold_plus
203 (type, chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_RIGHT (poly1)),
204
205 chrec_fold_plus
206 (type,
207 chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_LEFT (poly1)),
208 chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1))))),
209
210 /* "2*b*d". */
211 chrec_fold_multiply
212 (type, build_int_cst (NULL_TREE, 2),
213 chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1))));
214 }
215
216 /* When the operands are automatically_generated_chrec_p, the fold has
217 to respect the semantics of the operands. */
218
219 static inline tree
220 chrec_fold_automatically_generated_operands (tree op0,
221 tree op1)
222 {
223 if (op0 == chrec_dont_know
224 || op1 == chrec_dont_know)
225 return chrec_dont_know;
226
227 if (op0 == chrec_known
228 || op1 == chrec_known)
229 return chrec_known;
230
231 if (op0 == chrec_not_analyzed_yet
232 || op1 == chrec_not_analyzed_yet)
233 return chrec_not_analyzed_yet;
234
235 /* The default case produces a safe result. */
236 return chrec_dont_know;
237 }
238
239 /* Fold the addition of two chrecs. */
240
241 static tree
242 chrec_fold_plus_1 (enum tree_code code,
243 tree type,
244 tree op0,
245 tree op1)
246 {
247 if (automatically_generated_chrec_p (op0)
248 || automatically_generated_chrec_p (op1))
249 return chrec_fold_automatically_generated_operands (op0, op1);
250
251 switch (TREE_CODE (op0))
252 {
253 case POLYNOMIAL_CHREC:
254 switch (TREE_CODE (op1))
255 {
256 case POLYNOMIAL_CHREC:
257 return chrec_fold_plus_poly_poly (code, type, op0, op1);
258
259 default:
260 if (code == PLUS_EXPR)
261 return build_polynomial_chrec
262 (CHREC_VARIABLE (op0),
263 chrec_fold_plus (type, CHREC_LEFT (op0), op1),
264 CHREC_RIGHT (op0));
265 else
266 return build_polynomial_chrec
267 (CHREC_VARIABLE (op0),
268 chrec_fold_minus (type, CHREC_LEFT (op0), op1),
269 CHREC_RIGHT (op0));
270 }
271
272 default:
273 switch (TREE_CODE (op1))
274 {
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)),
280 CHREC_RIGHT (op1));
281 else
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)));
287
288 default:
289 if (tree_contains_chrecs (op0)
290 || tree_contains_chrecs (op1))
291 return build (code, type, op0, op1);
292 else
293 return fold (build (code, type, op0, op1));
294 }
295 }
296 }
297
298 /* Fold the addition of two chrecs. */
299
300 tree
301 chrec_fold_plus (tree type,
302 tree op0,
303 tree op1)
304 {
305 if (integer_zerop (op0))
306 return op1;
307 if (integer_zerop (op1))
308 return op0;
309
310 return chrec_fold_plus_1 (PLUS_EXPR, type, op0, op1);
311 }
312
313 /* Fold the subtraction of two chrecs. */
314
315 tree
316 chrec_fold_minus (tree type,
317 tree op0,
318 tree op1)
319 {
320 if (integer_zerop (op1))
321 return op0;
322
323 return chrec_fold_plus_1 (MINUS_EXPR, type, op0, op1);
324 }
325
326 /* Fold the multiplication of two chrecs. */
327
328 tree
329 chrec_fold_multiply (tree type,
330 tree op0,
331 tree op1)
332 {
333 if (automatically_generated_chrec_p (op0)
334 || automatically_generated_chrec_p (op1))
335 return chrec_fold_automatically_generated_operands (op0, op1);
336
337 switch (TREE_CODE (op0))
338 {
339 case POLYNOMIAL_CHREC:
340 switch (TREE_CODE (op1))
341 {
342 case POLYNOMIAL_CHREC:
343 return chrec_fold_multiply_poly_poly (type, op0, op1);
344
345 default:
346 if (integer_onep (op1))
347 return op0;
348 if (integer_zerop (op1))
349 return build_int_cst_type (type, 0);
350
351 return build_polynomial_chrec
352 (CHREC_VARIABLE (op0),
353 chrec_fold_multiply (type, CHREC_LEFT (op0), op1),
354 chrec_fold_multiply (type, CHREC_RIGHT (op0), op1));
355 }
356
357 default:
358 if (integer_onep (op0))
359 return op1;
360
361 if (integer_zerop (op0))
362 return build_int_cst_type (type, 0);
363
364 switch (TREE_CODE (op1))
365 {
366 case POLYNOMIAL_CHREC:
367 return build_polynomial_chrec
368 (CHREC_VARIABLE (op1),
369 chrec_fold_multiply (type, CHREC_LEFT (op1), op0),
370 chrec_fold_multiply (type, CHREC_RIGHT (op1), op0));
371
372 default:
373 if (integer_onep (op1))
374 return op0;
375 if (integer_zerop (op1))
376 return build_int_cst_type (type, 0);
377 return fold (build (MULT_EXPR, type, op0, op1));
378 }
379 }
380 }
381
382 \f
383
384 /* Operations. */
385
386 /* Evaluate the binomial coefficient. Return NULL_TREE if the intermediate
387 calculation overflows, otherwise return C(n,k) with type TYPE. */
388
389 static tree
390 tree_fold_binomial (tree type, tree n, unsigned int k)
391 {
392 unsigned HOST_WIDE_INT lidx, lnum, ldenom, lres, ldum;
393 HOST_WIDE_INT hidx, hnum, hdenom, hres, hdum;
394 unsigned int i;
395 tree res;
396
397 /* Handle the most frequent cases. */
398 if (k == 0)
399 return build_int_cst (type, 1);
400 if (k == 1)
401 return fold_convert (type, n);
402
403 /* Check that k <= n. */
404 if (TREE_INT_CST_HIGH (n) == 0
405 && TREE_INT_CST_LOW (n) < k)
406 return NULL_TREE;
407
408 /* Numerator = n. */
409 lnum = TREE_INT_CST_LOW (n);
410 hnum = TREE_INT_CST_HIGH (n);
411
412 /* Denominator = 2. */
413 ldenom = 2;
414 hdenom = 0;
415
416 /* Index = Numerator-1. */
417 if (lnum == 0)
418 {
419 hidx = hnum - 1;
420 lidx = ~ (unsigned HOST_WIDE_INT) 0;
421 }
422 else
423 {
424 hidx = hnum;
425 lidx = lnum - 1;
426 }
427
428 /* Numerator = Numerator*Index = n*(n-1). */
429 if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
430 return NULL_TREE;
431
432 for (i = 3; i <= k; i++)
433 {
434 /* Index--. */
435 if (lidx == 0)
436 {
437 hidx--;
438 lidx = ~ (unsigned HOST_WIDE_INT) 0;
439 }
440 else
441 lidx--;
442
443 /* Numerator *= Index. */
444 if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
445 return NULL_TREE;
446
447 /* Denominator *= i. */
448 mul_double (ldenom, hdenom, i, 0, &ldenom, &hdenom);
449 }
450
451 /* Result = Numerator / Denominator. */
452 div_and_round_double (EXACT_DIV_EXPR, 1, lnum, hnum, ldenom, hdenom,
453 &lres, &hres, &ldum, &hdum);
454
455 res = build_int_cst_wide (type, lres, hres);
456 return int_fits_type_p (res, type) ? res : NULL_TREE;
457 }
458
459 /* Helper function. Use the Newton's interpolating formula for
460 evaluating the value of the evolution function. */
461
462 static tree
463 chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
464 {
465 tree arg0, arg1, binomial_n_k;
466 tree type = TREE_TYPE (chrec);
467
468 while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
469 && CHREC_VARIABLE (chrec) > var)
470 chrec = CHREC_LEFT (chrec);
471
472 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
473 && CHREC_VARIABLE (chrec) == var)
474 {
475 arg0 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1);
476 if (arg0 == chrec_dont_know)
477 return chrec_dont_know;
478 binomial_n_k = tree_fold_binomial (type, n, k);
479 if (!binomial_n_k)
480 return chrec_dont_know;
481 arg1 = fold (build2 (MULT_EXPR, type,
482 CHREC_LEFT (chrec), binomial_n_k));
483 return chrec_fold_plus (type, arg0, arg1);
484 }
485
486 binomial_n_k = tree_fold_binomial (type, n, k);
487 if (!binomial_n_k)
488 return chrec_dont_know;
489
490 return fold (build2 (MULT_EXPR, type, chrec, binomial_n_k));
491 }
492
493 /* Evaluates "CHREC (X)" when the varying variable is VAR.
494 Example: Given the following parameters,
495
496 var = 1
497 chrec = {3, +, 4}_1
498 x = 10
499
500 The result is given by the Newton's interpolating formula:
501 3 * \binom{10}{0} + 4 * \binom{10}{1}.
502 */
503
504 tree
505 chrec_apply (unsigned var,
506 tree chrec,
507 tree x)
508 {
509 tree type = chrec_type (chrec);
510 tree res = chrec_dont_know;
511
512 if (automatically_generated_chrec_p (chrec)
513 || automatically_generated_chrec_p (x)
514
515 /* When the symbols are defined in an outer loop, it is possible
516 to symbolically compute the apply, since the symbols are
517 constants with respect to the varying loop. */
518 || chrec_contains_symbols_defined_in_loop (chrec, var)
519 || chrec_contains_symbols (x))
520 return chrec_dont_know;
521
522 if (dump_file && (dump_flags & TDF_DETAILS))
523 fprintf (dump_file, "(chrec_apply \n");
524
525 if (evolution_function_is_affine_p (chrec))
526 {
527 /* "{a, +, b} (x)" -> "a + b*x". */
528 if (TREE_CODE (CHREC_LEFT (chrec)) == INTEGER_CST
529 && integer_zerop (CHREC_LEFT (chrec)))
530 res = chrec_fold_multiply (type, CHREC_RIGHT (chrec), x);
531
532 else
533 res = chrec_fold_plus (type, CHREC_LEFT (chrec),
534 chrec_fold_multiply (type,
535 CHREC_RIGHT (chrec), x));
536 }
537
538 else if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
539 res = chrec;
540
541 else if (TREE_CODE (x) == INTEGER_CST
542 && tree_int_cst_sgn (x) == 1)
543 /* testsuite/.../ssa-chrec-38.c. */
544 res = chrec_evaluate (var, chrec, x, 0);
545
546 else
547 res = chrec_dont_know;
548
549 if (dump_file && (dump_flags & TDF_DETAILS))
550 {
551 fprintf (dump_file, " (varying_loop = %d\n", var);
552 fprintf (dump_file, ")\n (chrec = ");
553 print_generic_expr (dump_file, chrec, 0);
554 fprintf (dump_file, ")\n (x = ");
555 print_generic_expr (dump_file, x, 0);
556 fprintf (dump_file, ")\n (res = ");
557 print_generic_expr (dump_file, res, 0);
558 fprintf (dump_file, "))\n");
559 }
560
561 return res;
562 }
563
564 /* Replaces the initial condition in CHREC with INIT_COND. */
565
566 tree
567 chrec_replace_initial_condition (tree chrec,
568 tree init_cond)
569 {
570 if (automatically_generated_chrec_p (chrec))
571 return chrec;
572
573 switch (TREE_CODE (chrec))
574 {
575 case POLYNOMIAL_CHREC:
576 return build_polynomial_chrec
577 (CHREC_VARIABLE (chrec),
578 chrec_replace_initial_condition (CHREC_LEFT (chrec), init_cond),
579 CHREC_RIGHT (chrec));
580
581 default:
582 return init_cond;
583 }
584 }
585
586 /* Returns the initial condition of a given CHREC. */
587
588 tree
589 initial_condition (tree chrec)
590 {
591 if (automatically_generated_chrec_p (chrec))
592 return chrec;
593
594 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
595 return initial_condition (CHREC_LEFT (chrec));
596 else
597 return chrec;
598 }
599
600 /* Returns a univariate function that represents the evolution in
601 LOOP_NUM. Mask the evolution of any other loop. */
602
603 tree
604 hide_evolution_in_other_loops_than_loop (tree chrec,
605 unsigned loop_num)
606 {
607 if (automatically_generated_chrec_p (chrec))
608 return chrec;
609
610 switch (TREE_CODE (chrec))
611 {
612 case POLYNOMIAL_CHREC:
613 if (CHREC_VARIABLE (chrec) == loop_num)
614 return build_polynomial_chrec
615 (loop_num,
616 hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
617 loop_num),
618 CHREC_RIGHT (chrec));
619
620 else if (CHREC_VARIABLE (chrec) < loop_num)
621 /* There is no evolution in this loop. */
622 return initial_condition (chrec);
623
624 else
625 return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
626 loop_num);
627
628 default:
629 return chrec;
630 }
631 }
632
633 /* Returns the evolution part of CHREC in LOOP_NUM when RIGHT is
634 true, otherwise returns the initial condition in LOOP_NUM. */
635
636 static tree
637 chrec_component_in_loop_num (tree chrec,
638 unsigned loop_num,
639 bool right)
640 {
641 tree component;
642
643 if (automatically_generated_chrec_p (chrec))
644 return chrec;
645
646 switch (TREE_CODE (chrec))
647 {
648 case POLYNOMIAL_CHREC:
649 if (CHREC_VARIABLE (chrec) == loop_num)
650 {
651 if (right)
652 component = CHREC_RIGHT (chrec);
653 else
654 component = CHREC_LEFT (chrec);
655
656 if (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC
657 || CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec))
658 return component;
659
660 else
661 return build_polynomial_chrec
662 (loop_num,
663 chrec_component_in_loop_num (CHREC_LEFT (chrec),
664 loop_num,
665 right),
666 component);
667 }
668
669 else if (CHREC_VARIABLE (chrec) < loop_num)
670 /* There is no evolution part in this loop. */
671 return NULL_TREE;
672
673 else
674 return chrec_component_in_loop_num (CHREC_LEFT (chrec),
675 loop_num,
676 right);
677
678 default:
679 if (right)
680 return NULL_TREE;
681 else
682 return chrec;
683 }
684 }
685
686 /* Returns the evolution part in LOOP_NUM. Example: the call
687 evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns
688 {1, +, 2}_1 */
689
690 tree
691 evolution_part_in_loop_num (tree chrec,
692 unsigned loop_num)
693 {
694 return chrec_component_in_loop_num (chrec, loop_num, true);
695 }
696
697 /* Returns the initial condition in LOOP_NUM. Example: the call
698 initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns
699 {0, +, 1}_1 */
700
701 tree
702 initial_condition_in_loop_num (tree chrec,
703 unsigned loop_num)
704 {
705 return chrec_component_in_loop_num (chrec, loop_num, false);
706 }
707
708 /* Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
709 This function is essentially used for setting the evolution to
710 chrec_dont_know, for example after having determined that it is
711 impossible to say how many times a loop will execute. */
712
713 tree
714 reset_evolution_in_loop (unsigned loop_num,
715 tree chrec,
716 tree new_evol)
717 {
718 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
719 && CHREC_VARIABLE (chrec) > loop_num)
720 return build
721 (TREE_CODE (chrec),
722 build_int_cst (NULL_TREE, CHREC_VARIABLE (chrec)),
723 reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec), new_evol),
724 reset_evolution_in_loop (loop_num, CHREC_RIGHT (chrec), new_evol));
725
726 while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
727 && CHREC_VARIABLE (chrec) == loop_num)
728 chrec = CHREC_LEFT (chrec);
729
730 return build_polynomial_chrec (loop_num, chrec, new_evol);
731 }
732
733 /* Merges two evolution functions that were found by following two
734 alternate paths of a conditional expression. */
735
736 tree
737 chrec_merge (tree chrec1,
738 tree chrec2)
739 {
740 if (chrec1 == chrec_dont_know
741 || chrec2 == chrec_dont_know)
742 return chrec_dont_know;
743
744 if (chrec1 == chrec_known
745 || chrec2 == chrec_known)
746 return chrec_known;
747
748 if (chrec1 == chrec_not_analyzed_yet)
749 return chrec2;
750 if (chrec2 == chrec_not_analyzed_yet)
751 return chrec1;
752
753 if (operand_equal_p (chrec1, chrec2, 0))
754 return chrec1;
755
756 return chrec_dont_know;
757 }
758
759 \f
760
761 /* Observers. */
762
763 /* Helper function for is_multivariate_chrec. */
764
765 static bool
766 is_multivariate_chrec_rec (tree chrec, unsigned int rec_var)
767 {
768 if (chrec == NULL_TREE)
769 return false;
770
771 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
772 {
773 if (CHREC_VARIABLE (chrec) != rec_var)
774 return true;
775 else
776 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec), rec_var)
777 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec), rec_var));
778 }
779 else
780 return false;
781 }
782
783 /* Determine whether the given chrec is multivariate or not. */
784
785 bool
786 is_multivariate_chrec (tree chrec)
787 {
788 if (chrec == NULL_TREE)
789 return false;
790
791 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
792 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec),
793 CHREC_VARIABLE (chrec))
794 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec),
795 CHREC_VARIABLE (chrec)));
796 else
797 return false;
798 }
799
800 /* Determines whether the chrec contains symbolic names or not. */
801
802 bool
803 chrec_contains_symbols (tree chrec)
804 {
805 if (chrec == NULL_TREE)
806 return false;
807
808 if (TREE_CODE (chrec) == SSA_NAME
809 || TREE_CODE (chrec) == VAR_DECL
810 || TREE_CODE (chrec) == PARM_DECL
811 || TREE_CODE (chrec) == FUNCTION_DECL
812 || TREE_CODE (chrec) == LABEL_DECL
813 || TREE_CODE (chrec) == RESULT_DECL
814 || TREE_CODE (chrec) == FIELD_DECL)
815 return true;
816
817 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
818 {
819 case 3:
820 if (chrec_contains_symbols (TREE_OPERAND (chrec, 2)))
821 return true;
822
823 case 2:
824 if (chrec_contains_symbols (TREE_OPERAND (chrec, 1)))
825 return true;
826
827 case 1:
828 if (chrec_contains_symbols (TREE_OPERAND (chrec, 0)))
829 return true;
830
831 default:
832 return false;
833 }
834 }
835
836 /* Determines whether the chrec contains undetermined coefficients. */
837
838 bool
839 chrec_contains_undetermined (tree chrec)
840 {
841 if (chrec == chrec_dont_know
842 || chrec == chrec_not_analyzed_yet
843 || chrec == NULL_TREE)
844 return true;
845
846 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
847 {
848 case 3:
849 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 2)))
850 return true;
851
852 case 2:
853 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 1)))
854 return true;
855
856 case 1:
857 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 0)))
858 return true;
859
860 default:
861 return false;
862 }
863 }
864
865 /* Determines whether the tree EXPR contains chrecs. */
866
867 bool
868 tree_contains_chrecs (tree expr)
869 {
870 if (expr == NULL_TREE)
871 return false;
872
873 if (tree_is_chrec (expr))
874 return true;
875
876 switch (TREE_CODE_LENGTH (TREE_CODE (expr)))
877 {
878 case 3:
879 if (tree_contains_chrecs (TREE_OPERAND (expr, 2)))
880 return true;
881
882 case 2:
883 if (tree_contains_chrecs (TREE_OPERAND (expr, 1)))
884 return true;
885
886 case 1:
887 if (tree_contains_chrecs (TREE_OPERAND (expr, 0)))
888 return true;
889
890 default:
891 return false;
892 }
893 }
894
895 /* Determine whether the given tree is an affine multivariate
896 evolution. */
897
898 bool
899 evolution_function_is_affine_multivariate_p (tree chrec)
900 {
901 if (chrec == NULL_TREE)
902 return false;
903
904 switch (TREE_CODE (chrec))
905 {
906 case POLYNOMIAL_CHREC:
907 if (evolution_function_is_constant_p (CHREC_LEFT (chrec)))
908 {
909 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec)))
910 return true;
911 else
912 {
913 if (TREE_CODE (CHREC_RIGHT (chrec)) == POLYNOMIAL_CHREC
914 && CHREC_VARIABLE (CHREC_RIGHT (chrec))
915 != CHREC_VARIABLE (chrec)
916 && evolution_function_is_affine_multivariate_p
917 (CHREC_RIGHT (chrec)))
918 return true;
919 else
920 return false;
921 }
922 }
923 else
924 {
925 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec))
926 && TREE_CODE (CHREC_LEFT (chrec)) == POLYNOMIAL_CHREC
927 && CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec)
928 && evolution_function_is_affine_multivariate_p
929 (CHREC_LEFT (chrec)))
930 return true;
931 else
932 return false;
933 }
934
935 default:
936 return false;
937 }
938 }
939
940 /* Determine whether the given tree is a function in zero or one
941 variables. */
942
943 bool
944 evolution_function_is_univariate_p (tree chrec)
945 {
946 if (chrec == NULL_TREE)
947 return true;
948
949 switch (TREE_CODE (chrec))
950 {
951 case POLYNOMIAL_CHREC:
952 switch (TREE_CODE (CHREC_LEFT (chrec)))
953 {
954 case POLYNOMIAL_CHREC:
955 if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_LEFT (chrec)))
956 return false;
957 if (!evolution_function_is_univariate_p (CHREC_LEFT (chrec)))
958 return false;
959 break;
960
961 default:
962 break;
963 }
964
965 switch (TREE_CODE (CHREC_RIGHT (chrec)))
966 {
967 case POLYNOMIAL_CHREC:
968 if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_RIGHT (chrec)))
969 return false;
970 if (!evolution_function_is_univariate_p (CHREC_RIGHT (chrec)))
971 return false;
972 break;
973
974 default:
975 break;
976 }
977
978 default:
979 return true;
980 }
981 }
982
983 /* Returns the number of variables of CHREC. Example: the call
984 nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2. */
985
986 unsigned
987 nb_vars_in_chrec (tree chrec)
988 {
989 if (chrec == NULL_TREE)
990 return 0;
991
992 switch (TREE_CODE (chrec))
993 {
994 case POLYNOMIAL_CHREC:
995 return 1 + nb_vars_in_chrec
996 (initial_condition_in_loop_num (chrec, CHREC_VARIABLE (chrec)));
997
998 default:
999 return 0;
1000 }
1001 }
1002
1003 \f
1004
1005 /* Convert CHREC to TYPE. The following is rule is always true:
1006 TREE_TYPE (chrec) == TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE
1007 (CHREC_RIGHT (chrec)). An example of what could happen when adding
1008 two chrecs and the type of the CHREC_RIGHT is different than
1009 CHREC_LEFT is:
1010
1011 {(uint) 0, +, (uchar) 10} +
1012 {(uint) 0, +, (uchar) 250}
1013
1014 that would produce a wrong result if CHREC_RIGHT is not (uint):
1015
1016 {(uint) 0, +, (uchar) 4}
1017
1018 instead of
1019
1020 {(uint) 0, +, (uint) 260}
1021 */
1022
1023 tree
1024 chrec_convert (tree type,
1025 tree chrec)
1026 {
1027 tree ct;
1028
1029 if (automatically_generated_chrec_p (chrec))
1030 return chrec;
1031
1032 ct = chrec_type (chrec);
1033 if (ct == type)
1034 return chrec;
1035
1036 if (TYPE_PRECISION (ct) < TYPE_PRECISION (type))
1037 return count_ev_in_wider_type (type, chrec);
1038
1039 switch (TREE_CODE (chrec))
1040 {
1041 case POLYNOMIAL_CHREC:
1042 return build_polynomial_chrec (CHREC_VARIABLE (chrec),
1043 chrec_convert (type,
1044 CHREC_LEFT (chrec)),
1045 chrec_convert (type,
1046 CHREC_RIGHT (chrec)));
1047
1048 default:
1049 {
1050 tree res = fold_convert (type, chrec);
1051
1052 /* Don't propagate overflows. */
1053 TREE_OVERFLOW (res) = 0;
1054 if (CONSTANT_CLASS_P (res))
1055 TREE_CONSTANT_OVERFLOW (res) = 0;
1056
1057 /* But reject constants that don't fit in their type after conversion.
1058 This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the
1059 natural values associated with TYPE_PRECISION and TYPE_UNSIGNED,
1060 and can cause problems later when computing niters of loops. Note
1061 that we don't do the check before converting because we don't want
1062 to reject conversions of negative chrecs to unsigned types. */
1063 if (TREE_CODE (res) == INTEGER_CST
1064 && TREE_CODE (type) == INTEGER_TYPE
1065 && !int_fits_type_p (res, type))
1066 res = chrec_dont_know;
1067
1068 return res;
1069 }
1070 }
1071 }
1072
1073 /* Returns the type of the chrec. */
1074
1075 tree
1076 chrec_type (tree chrec)
1077 {
1078 if (automatically_generated_chrec_p (chrec))
1079 return NULL_TREE;
1080
1081 return TREE_TYPE (chrec);
1082 }