comparison gcc/tree-chrec.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Chains of recurrences. 1 /* Chains of recurrences.
2 Copyright (C) 2003-2017 Free Software Foundation, Inc. 2 Copyright (C) 2003-2018 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <pop@cri.ensmp.fr> 3 Contributed by Sebastian Pop <pop@cri.ensmp.fr>
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
39 #include "params.h" 39 #include "params.h"
40 #include "tree-scalar-evolution.h" 40 #include "tree-scalar-evolution.h"
41 41
42 /* Extended folder for chrecs. */ 42 /* Extended folder for chrecs. */
43 43
44 /* Determines whether CST is not a constant evolution. */
45
46 static inline bool
47 is_not_constant_evolution (const_tree cst)
48 {
49 return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
50 }
51
52 /* Fold CODE for a polynomial function and a constant. */
53
54 static inline tree
55 chrec_fold_poly_cst (enum tree_code code,
56 tree type,
57 tree poly,
58 tree cst)
59 {
60 gcc_assert (poly);
61 gcc_assert (cst);
62 gcc_assert (TREE_CODE (poly) == POLYNOMIAL_CHREC);
63 gcc_checking_assert (!is_not_constant_evolution (cst));
64 gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly)));
65
66 switch (code)
67 {
68 case PLUS_EXPR:
69 return build_polynomial_chrec
70 (CHREC_VARIABLE (poly),
71 chrec_fold_plus (type, CHREC_LEFT (poly), cst),
72 CHREC_RIGHT (poly));
73
74 case MINUS_EXPR:
75 return build_polynomial_chrec
76 (CHREC_VARIABLE (poly),
77 chrec_fold_minus (type, CHREC_LEFT (poly), cst),
78 CHREC_RIGHT (poly));
79
80 case MULT_EXPR:
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));
85
86 default:
87 return chrec_dont_know;
88 }
89 }
90
91 /* Fold the addition of two polynomial functions. */ 44 /* Fold the addition of two polynomial functions. */
92 45
93 static inline tree 46 static inline tree
94 chrec_fold_plus_poly_poly (enum tree_code code, 47 chrec_fold_plus_poly_poly (enum tree_code code,
95 tree type, 48 tree type,
293 (!chrec_contains_symbols_defined_in_loop (op1, 246 (!chrec_contains_symbols_defined_in_loop (op1,
294 CHREC_VARIABLE (op1))); 247 CHREC_VARIABLE (op1)));
295 return chrec_fold_plus_poly_poly (code, type, op0, op1); 248 return chrec_fold_plus_poly_poly (code, type, op0, op1);
296 249
297 CASE_CONVERT: 250 CASE_CONVERT:
298 if (tree_contains_chrecs (op1, NULL)) 251 {
299 return chrec_dont_know; 252 /* We can strip sign-conversions to signed by performing the
253 operation in unsigned. */
254 tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
255 if (INTEGRAL_TYPE_P (type)
256 && INTEGRAL_TYPE_P (optype)
257 && tree_nop_conversion_p (type, optype)
258 && TYPE_UNSIGNED (optype))
259 return chrec_convert (type,
260 chrec_fold_plus_1 (code, optype,
261 chrec_convert (optype,
262 op0, NULL),
263 TREE_OPERAND (op1, 0)),
264 NULL);
265 if (tree_contains_chrecs (op1, NULL))
266 return chrec_dont_know;
267 }
300 /* FALLTHRU */ 268 /* FALLTHRU */
301 269
302 default: 270 default:
303 if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR) 271 if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
304 return build_polynomial_chrec 272 return build_polynomial_chrec
311 chrec_fold_minus (type, CHREC_LEFT (op0), op1), 279 chrec_fold_minus (type, CHREC_LEFT (op0), op1),
312 CHREC_RIGHT (op0)); 280 CHREC_RIGHT (op0));
313 } 281 }
314 282
315 CASE_CONVERT: 283 CASE_CONVERT:
316 if (tree_contains_chrecs (op0, NULL)) 284 {
317 return chrec_dont_know; 285 /* We can strip sign-conversions to signed by performing the
286 operation in unsigned. */
287 tree optype = TREE_TYPE (TREE_OPERAND (op0, 0));
288 if (INTEGRAL_TYPE_P (type)
289 && INTEGRAL_TYPE_P (optype)
290 && tree_nop_conversion_p (type, optype)
291 && TYPE_UNSIGNED (optype))
292 return chrec_convert (type,
293 chrec_fold_plus_1 (code, optype,
294 TREE_OPERAND (op0, 0),
295 chrec_convert (optype,
296 op1, NULL)),
297 NULL);
298 if (tree_contains_chrecs (op0, NULL))
299 return chrec_dont_know;
300 }
318 /* FALLTHRU */ 301 /* FALLTHRU */
319 302
320 default: 303 default:
321 switch (TREE_CODE (op1)) 304 switch (TREE_CODE (op1))
322 { 305 {
496 calculation overflows, otherwise return C(n,k) with type TYPE. */ 479 calculation overflows, otherwise return C(n,k) with type TYPE. */
497 480
498 static tree 481 static tree
499 tree_fold_binomial (tree type, tree n, unsigned int k) 482 tree_fold_binomial (tree type, tree n, unsigned int k)
500 { 483 {
501 bool overflow; 484 wi::overflow_type overflow;
502 unsigned int i; 485 unsigned int i;
503 486
504 /* Handle the most frequent cases. */ 487 /* Handle the most frequent cases. */
505 if (k == 0) 488 if (k == 0)
506 return build_int_cst (type, 1); 489 return build_int_cst (type, 1);
959 if (chrec == NULL_TREE) 942 if (chrec == NULL_TREE)
960 return false; 943 return false;
961 944
962 if (TREE_CODE (chrec) == SSA_NAME 945 if (TREE_CODE (chrec) == SSA_NAME
963 || VAR_P (chrec) 946 || VAR_P (chrec)
947 || TREE_CODE (chrec) == POLY_INT_CST
964 || TREE_CODE (chrec) == PARM_DECL 948 || TREE_CODE (chrec) == PARM_DECL
965 || TREE_CODE (chrec) == FUNCTION_DECL 949 || TREE_CODE (chrec) == FUNCTION_DECL
966 || TREE_CODE (chrec) == LABEL_DECL 950 || TREE_CODE (chrec) == LABEL_DECL
967 || TREE_CODE (chrec) == RESULT_DECL 951 || TREE_CODE (chrec) == RESULT_DECL
968 || TREE_CODE (chrec) == FIELD_DECL) 952 || TREE_CODE (chrec) == FIELD_DECL)
1159 default: 1143 default:
1160 if (tree_contains_chrecs (CHREC_RIGHT (chrec), NULL)) 1144 if (tree_contains_chrecs (CHREC_RIGHT (chrec), NULL))
1161 return false; 1145 return false;
1162 break; 1146 break;
1163 } 1147 }
1148 return true;
1164 1149
1165 default: 1150 default:
1166 return true; 1151 return true;
1167 } 1152 }
1168 } 1153 }