Mercurial > hg > CbC > CbC_gcc
comparison gcc/fortran/simplify.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
comparison
equal
deleted
inserted
replaced
131:84e7813d76e9 | 145:1830386684a0 |
---|---|
1 /* Simplify intrinsic functions at compile-time. | 1 /* Simplify intrinsic functions at compile-time. |
2 Copyright (C) 2000-2018 Free Software Foundation, Inc. | 2 Copyright (C) 2000-2020 Free Software Foundation, Inc. |
3 Contributed by Andy Vaught & Katherine Holcomb | 3 Contributed by Andy Vaught & Katherine Holcomb |
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 |
167 | 167 |
168 mpz_clear (mask); | 168 mpz_clear (mask); |
169 } | 169 } |
170 else | 170 else |
171 { | 171 { |
172 /* Confirm that no bits above the signed range are set. */ | 172 /* Confirm that no bits above the signed range are set if we |
173 gcc_assert (mpz_scan1 (x, bitsize-1) == ULONG_MAX); | 173 are doing range checking. */ |
174 if (flag_range_check != 0) | |
175 gcc_assert (mpz_scan1 (x, bitsize-1) == ULONG_MAX); | |
174 } | 176 } |
175 } | 177 } |
176 | 178 |
177 | 179 |
178 /* Converts an mpz_t unsigned variable into a signed one, assuming | 180 /* Converts an mpz_t unsigned variable into a signed one, assuming |
206 | 208 |
207 mpz_neg (x, x); | 209 mpz_neg (x, x); |
208 | 210 |
209 mpz_clear (mask); | 211 mpz_clear (mask); |
210 } | 212 } |
211 } | |
212 | |
213 | |
214 /* In-place convert BOZ to REAL of the specified kind. */ | |
215 | |
216 static gfc_expr * | |
217 convert_boz (gfc_expr *x, int kind) | |
218 { | |
219 if (x && x->ts.type == BT_INTEGER && x->is_boz) | |
220 { | |
221 gfc_typespec ts; | |
222 gfc_clear_ts (&ts); | |
223 ts.type = BT_REAL; | |
224 ts.kind = kind; | |
225 | |
226 if (!gfc_convert_boz (x, &ts)) | |
227 return &gfc_bad_expr; | |
228 } | |
229 | |
230 return x; | |
231 } | 213 } |
232 | 214 |
233 | 215 |
234 /* Test that the expression is a constant array, simplifying if | 216 /* Test that the expression is a constant array, simplifying if |
235 we are dealing with a parameter array. */ | 217 we are dealing with a parameter array. */ |
634 { | 616 { |
635 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n) | 617 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n) |
636 if (*src) | 618 if (*src) |
637 *dest = op (*dest, gfc_copy_expr (*src)); | 619 *dest = op (*dest, gfc_copy_expr (*src)); |
638 | 620 |
621 if (post_op) | |
622 *dest = post_op (*dest, *dest); | |
623 | |
639 count[0]++; | 624 count[0]++; |
640 base += sstride[0]; | 625 base += sstride[0]; |
641 dest += dstride[0]; | 626 dest += dstride[0]; |
642 | 627 |
643 n = 0; | 628 n = 0; |
669 | 654 |
670 /* Place updated expression in result constructor. */ | 655 /* Place updated expression in result constructor. */ |
671 result_ctor = gfc_constructor_first (result->value.constructor); | 656 result_ctor = gfc_constructor_first (result->value.constructor); |
672 for (i = 0; i < resultsize; ++i) | 657 for (i = 0; i < resultsize; ++i) |
673 { | 658 { |
674 if (post_op) | 659 result_ctor->expr = resultvec[i]; |
675 result_ctor->expr = post_op (result_ctor->expr, resultvec[i]); | |
676 else | |
677 result_ctor->expr = resultvec[i]; | |
678 result_ctor = gfc_constructor_next (result_ctor); | 660 result_ctor = gfc_constructor_next (result_ctor); |
679 } | 661 } |
680 | 662 |
681 free (arrayvec); | 663 free (arrayvec); |
682 free (resultvec); | 664 free (resultvec); |
1657 | 1639 |
1658 static gfc_expr * | 1640 static gfc_expr * |
1659 simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind) | 1641 simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind) |
1660 { | 1642 { |
1661 gfc_expr *result; | 1643 gfc_expr *result; |
1662 | |
1663 if (convert_boz (x, kind) == &gfc_bad_expr) | |
1664 return &gfc_bad_expr; | |
1665 | |
1666 if (convert_boz (y, kind) == &gfc_bad_expr) | |
1667 return &gfc_bad_expr; | |
1668 | 1644 |
1669 if (x->expr_type != EXPR_CONSTANT | 1645 if (x->expr_type != EXPR_CONSTANT |
1670 || (y != NULL && y->expr_type != EXPR_CONSTANT)) | 1646 || (y != NULL && y->expr_type != EXPR_CONSTANT)) |
1671 return NULL; | 1647 return NULL; |
1672 | 1648 |
1792 } | 1768 } |
1793 | 1769 |
1794 /* Convert a floating-point number from radians to degrees. */ | 1770 /* Convert a floating-point number from radians to degrees. */ |
1795 | 1771 |
1796 static void | 1772 static void |
1797 degrees_f (mpfr_t x, mp_rnd_t rnd_mode) | 1773 degrees_f (mpfr_t x, mpfr_rnd_t rnd_mode) |
1798 { | 1774 { |
1799 mpfr_t tmp; | 1775 mpfr_t tmp; |
1800 mpfr_init (tmp); | 1776 mpfr_init (tmp); |
1801 | 1777 |
1802 /* Set x = x % 2pi to avoid offsets with large angles. */ | 1778 /* Set x = x % 2pi to avoid offsets with large angles. */ |
1815 } | 1791 } |
1816 | 1792 |
1817 /* Convert a floating-point number from degrees to radians. */ | 1793 /* Convert a floating-point number from degrees to radians. */ |
1818 | 1794 |
1819 static void | 1795 static void |
1820 radians_f (mpfr_t x, mp_rnd_t rnd_mode) | 1796 radians_f (mpfr_t x, mpfr_rnd_t rnd_mode) |
1821 { | 1797 { |
1822 mpfr_t tmp; | 1798 mpfr_t tmp; |
1823 mpfr_init (tmp); | 1799 mpfr_init (tmp); |
1824 | 1800 |
1825 /* Set x = x % 360 to avoid offsets with large angles. */ | 1801 /* Set x = x % 360 to avoid offsets with large angles. */ |
2213 | 2189 |
2214 gfc_expr * | 2190 gfc_expr * |
2215 gfc_simplify_dble (gfc_expr *e) | 2191 gfc_simplify_dble (gfc_expr *e) |
2216 { | 2192 { |
2217 gfc_expr *result = NULL; | 2193 gfc_expr *result = NULL; |
2194 int tmp1, tmp2; | |
2218 | 2195 |
2219 if (e->expr_type != EXPR_CONSTANT) | 2196 if (e->expr_type != EXPR_CONSTANT) |
2220 return NULL; | 2197 return NULL; |
2221 | 2198 |
2222 if (convert_boz (e, gfc_default_double_kind) == &gfc_bad_expr) | 2199 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra |
2223 return &gfc_bad_expr; | 2200 warnings. */ |
2201 tmp1 = warn_conversion; | |
2202 tmp2 = warn_conversion_extra; | |
2203 warn_conversion = warn_conversion_extra = 0; | |
2224 | 2204 |
2225 result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind); | 2205 result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind); |
2206 | |
2207 warn_conversion = tmp1; | |
2208 warn_conversion_extra = tmp2; | |
2209 | |
2226 if (result == &gfc_bad_expr) | 2210 if (result == &gfc_bad_expr) |
2227 return &gfc_bad_expr; | 2211 return &gfc_bad_expr; |
2228 | 2212 |
2229 return range_check (result, "DBLE"); | 2213 return range_check (result, "DBLE"); |
2230 } | 2214 } |
2697 using a large precision for intermediate results. This is used for all | 2681 using a large precision for intermediate results. This is used for all |
2698 but large values of the argument. */ | 2682 but large values of the argument. */ |
2699 static void | 2683 static void |
2700 fullprec_erfc_scaled (mpfr_t res, mpfr_t arg) | 2684 fullprec_erfc_scaled (mpfr_t res, mpfr_t arg) |
2701 { | 2685 { |
2702 mp_prec_t prec; | 2686 mpfr_prec_t prec; |
2703 mpfr_t a, b; | 2687 mpfr_t a, b; |
2704 | 2688 |
2705 prec = mpfr_get_default_prec (); | 2689 prec = mpfr_get_default_prec (); |
2706 mpfr_set_default_prec (10 * prec); | 2690 mpfr_set_default_prec (10 * prec); |
2707 | 2691 |
2734 static void | 2718 static void |
2735 asympt_erfc_scaled (mpfr_t res, mpfr_t arg) | 2719 asympt_erfc_scaled (mpfr_t res, mpfr_t arg) |
2736 { | 2720 { |
2737 mpfr_t sum, x, u, v, w, oldsum, sumtrunc; | 2721 mpfr_t sum, x, u, v, w, oldsum, sumtrunc; |
2738 mpz_t num; | 2722 mpz_t num; |
2739 mp_prec_t prec; | 2723 mpfr_prec_t prec; |
2740 unsigned i; | 2724 unsigned i; |
2741 | 2725 |
2742 prec = mpfr_get_default_prec (); | 2726 prec = mpfr_get_default_prec (); |
2743 mpfr_set_default_prec (2 * prec); | 2727 mpfr_set_default_prec (2 * prec); |
2744 | 2728 |
2963 gfc_expr *result; | 2947 gfc_expr *result; |
2964 | 2948 |
2965 if (a->expr_type != EXPR_CONSTANT) | 2949 if (a->expr_type != EXPR_CONSTANT) |
2966 return NULL; | 2950 return NULL; |
2967 | 2951 |
2968 if (a->is_boz) | 2952 result = gfc_int2real (a, gfc_default_real_kind); |
2969 { | |
2970 if (convert_boz (a, gfc_default_real_kind) == &gfc_bad_expr) | |
2971 return &gfc_bad_expr; | |
2972 | |
2973 result = gfc_copy_expr (a); | |
2974 } | |
2975 else | |
2976 result = gfc_int2real (a, gfc_default_real_kind); | |
2977 | 2953 |
2978 return range_check (result, "FLOAT"); | 2954 return range_check (result, "FLOAT"); |
2979 } | 2955 } |
2980 | 2956 |
2981 | 2957 |
3100 | 3076 |
3101 gfc_expr * | 3077 gfc_expr * |
3102 gfc_simplify_fraction (gfc_expr *x) | 3078 gfc_simplify_fraction (gfc_expr *x) |
3103 { | 3079 { |
3104 gfc_expr *result; | 3080 gfc_expr *result; |
3105 | |
3106 #if MPFR_VERSION < MPFR_VERSION_NUM(3,1,0) | |
3107 mpfr_t absv, exp, pow2; | |
3108 #else | |
3109 mpfr_exp_t e; | 3081 mpfr_exp_t e; |
3110 #endif | |
3111 | 3082 |
3112 if (x->expr_type != EXPR_CONSTANT) | 3083 if (x->expr_type != EXPR_CONSTANT) |
3113 return NULL; | 3084 return NULL; |
3114 | 3085 |
3115 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where); | 3086 result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where); |
3119 { | 3090 { |
3120 mpfr_set_nan (result->value.real); | 3091 mpfr_set_nan (result->value.real); |
3121 return result; | 3092 return result; |
3122 } | 3093 } |
3123 | 3094 |
3124 #if MPFR_VERSION < MPFR_VERSION_NUM(3,1,0) | |
3125 | |
3126 /* MPFR versions before 3.1.0 do not include mpfr_frexp. | |
3127 TODO: remove the kludge when MPFR 3.1.0 or newer will be required */ | |
3128 | |
3129 if (mpfr_sgn (x->value.real) == 0) | |
3130 { | |
3131 mpfr_set (result->value.real, x->value.real, GFC_RND_MODE); | |
3132 return result; | |
3133 } | |
3134 | |
3135 gfc_set_model_kind (x->ts.kind); | |
3136 mpfr_init (exp); | |
3137 mpfr_init (absv); | |
3138 mpfr_init (pow2); | |
3139 | |
3140 mpfr_abs (absv, x->value.real, GFC_RND_MODE); | |
3141 mpfr_log2 (exp, absv, GFC_RND_MODE); | |
3142 | |
3143 mpfr_trunc (exp, exp); | |
3144 mpfr_add_ui (exp, exp, 1, GFC_RND_MODE); | |
3145 | |
3146 mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE); | |
3147 | |
3148 mpfr_div (result->value.real, x->value.real, pow2, GFC_RND_MODE); | |
3149 | |
3150 mpfr_clears (exp, absv, pow2, NULL); | |
3151 | |
3152 #else | |
3153 | |
3154 /* mpfr_frexp() correctly handles zeros and NaNs. */ | 3095 /* mpfr_frexp() correctly handles zeros and NaNs. */ |
3155 mpfr_frexp (&e, result->value.real, x->value.real, GFC_RND_MODE); | 3096 mpfr_frexp (&e, result->value.real, x->value.real, GFC_RND_MODE); |
3156 | |
3157 #endif | |
3158 | 3097 |
3159 return range_check (result, "FRACTION"); | 3098 return range_check (result, "FRACTION"); |
3160 } | 3099 } |
3161 | 3100 |
3162 | 3101 |
3607 | 3546 |
3608 static gfc_expr * | 3547 static gfc_expr * |
3609 simplify_intconv (gfc_expr *e, int kind, const char *name) | 3548 simplify_intconv (gfc_expr *e, int kind, const char *name) |
3610 { | 3549 { |
3611 gfc_expr *result = NULL; | 3550 gfc_expr *result = NULL; |
3551 int tmp1, tmp2; | |
3552 | |
3553 /* Convert BOZ to integer, and return without range checking. */ | |
3554 if (e->ts.type == BT_BOZ) | |
3555 { | |
3556 if (!gfc_boz2int (e, kind)) | |
3557 return NULL; | |
3558 result = gfc_copy_expr (e); | |
3559 return result; | |
3560 } | |
3612 | 3561 |
3613 if (e->expr_type != EXPR_CONSTANT) | 3562 if (e->expr_type != EXPR_CONSTANT) |
3614 return NULL; | 3563 return NULL; |
3615 | 3564 |
3565 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra | |
3566 warnings. */ | |
3567 tmp1 = warn_conversion; | |
3568 tmp2 = warn_conversion_extra; | |
3569 warn_conversion = warn_conversion_extra = 0; | |
3570 | |
3616 result = gfc_convert_constant (e, BT_INTEGER, kind); | 3571 result = gfc_convert_constant (e, BT_INTEGER, kind); |
3572 | |
3573 warn_conversion = tmp1; | |
3574 warn_conversion_extra = tmp2; | |
3575 | |
3617 if (result == &gfc_bad_expr) | 3576 if (result == &gfc_bad_expr) |
3618 return &gfc_bad_expr; | 3577 return &gfc_bad_expr; |
3619 | 3578 |
3620 return range_check (result, name); | 3579 return range_check (result, name); |
3621 } | 3580 } |
4180 case REF_COMPONENT: | 4139 case REF_COMPONENT: |
4181 as = ref->u.c.component->as; | 4140 as = ref->u.c.component->as; |
4182 continue; | 4141 continue; |
4183 | 4142 |
4184 case REF_SUBSTRING: | 4143 case REF_SUBSTRING: |
4144 case REF_INQUIRY: | |
4185 continue; | 4145 continue; |
4186 } | 4146 } |
4187 } | 4147 } |
4188 | 4148 |
4189 gcc_unreachable (); | 4149 gcc_unreachable (); |
4322 case REF_COMPONENT: | 4282 case REF_COMPONENT: |
4323 as = ref->u.c.component->as; | 4283 as = ref->u.c.component->as; |
4324 continue; | 4284 continue; |
4325 | 4285 |
4326 case REF_SUBSTRING: | 4286 case REF_SUBSTRING: |
4287 case REF_INQUIRY: | |
4327 continue; | 4288 continue; |
4328 } | 4289 } |
4329 } | 4290 } |
4330 | 4291 |
4331 if (!as) | 4292 if (!as) |
4470 && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym)) | 4431 && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym)) |
4471 | 4432 |
4472 /* The expression in assoc->target points to a ref to the _data component | 4433 /* The expression in assoc->target points to a ref to the _data component |
4473 of the unlimited polymorphic entity. To get the _len component the last | 4434 of the unlimited polymorphic entity. To get the _len component the last |
4474 _data ref needs to be stripped and a ref to the _len component added. */ | 4435 _data ref needs to be stripped and a ref to the _len component added. */ |
4475 return gfc_get_len_component (e->symtree->n.sym->assoc->target); | 4436 return gfc_get_len_component (e->symtree->n.sym->assoc->target, k); |
4476 else | 4437 else |
4477 return NULL; | 4438 return NULL; |
4478 } | 4439 } |
4479 | 4440 |
4480 | 4441 |
4710 mpz_init_set_si (result->shape[1], result_columns); | 4671 mpz_init_set_si (result->shape[1], result_columns); |
4711 } | 4672 } |
4712 else | 4673 else |
4713 gcc_unreachable(); | 4674 gcc_unreachable(); |
4714 | 4675 |
4715 offset_a = offset_b = 0; | 4676 offset_b = 0; |
4716 for (col = 0; col < result_columns; ++col) | 4677 for (col = 0; col < result_columns; ++col) |
4717 { | 4678 { |
4718 offset_a = 0; | 4679 offset_a = 0; |
4719 | 4680 |
4720 for (row = 0; row < result_rows; ++row) | 4681 for (row = 0; row < result_rows; ++row) |
4804 { | 4765 { |
4805 gfc_expr * result; | 4766 gfc_expr * result; |
4806 gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor; | 4767 gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor; |
4807 | 4768 |
4808 if (mask->expr_type == EXPR_CONSTANT) | 4769 if (mask->expr_type == EXPR_CONSTANT) |
4809 return gfc_get_parentheses (gfc_copy_expr (mask->value.logical | 4770 { |
4810 ? tsource : fsource)); | 4771 result = gfc_copy_expr (mask->value.logical ? tsource : fsource); |
4772 /* Parenthesis is needed to get lower bounds of 1. */ | |
4773 result = gfc_get_parentheses (result); | |
4774 gfc_simplify_expr (result, 1); | |
4775 return result; | |
4776 } | |
4811 | 4777 |
4812 if (!mask->rank || !is_constant_array_expr (mask) | 4778 if (!mask->rank || !is_constant_array_expr (mask) |
4813 || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource)) | 4779 || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource)) |
4814 return NULL; | 4780 return NULL; |
4815 | 4781 |
4959 | 4925 |
4960 static gfc_expr * | 4926 static gfc_expr * |
4961 simplify_min_max (gfc_expr *expr, int sign) | 4927 simplify_min_max (gfc_expr *expr, int sign) |
4962 { | 4928 { |
4963 gfc_actual_arglist *arg, *last, *extremum; | 4929 gfc_actual_arglist *arg, *last, *extremum; |
4964 gfc_intrinsic_sym * specific; | 4930 gfc_expr *tmp, *ret; |
4931 const char *fname; | |
4965 | 4932 |
4966 last = NULL; | 4933 last = NULL; |
4967 extremum = NULL; | 4934 extremum = NULL; |
4968 specific = expr->value.function.isym; | |
4969 | 4935 |
4970 arg = expr->value.function.actual; | 4936 arg = expr->value.function.actual; |
4971 | 4937 |
4972 for (; arg; last = arg, arg = arg->next) | 4938 for (; arg; last = arg, arg = arg->next) |
4973 { | 4939 { |
4993 /* If there is one value left, replace the function call with the | 4959 /* If there is one value left, replace the function call with the |
4994 expression. */ | 4960 expression. */ |
4995 if (expr->value.function.actual->next != NULL) | 4961 if (expr->value.function.actual->next != NULL) |
4996 return NULL; | 4962 return NULL; |
4997 | 4963 |
4998 /* Convert to the correct type and kind. */ | 4964 /* Handle special cases of specific functions (min|max)1 and |
4999 if (expr->ts.type != BT_UNKNOWN) | 4965 a(min|max)0. */ |
5000 return gfc_convert_constant (expr->value.function.actual->expr, | 4966 |
5001 expr->ts.type, expr->ts.kind); | 4967 tmp = expr->value.function.actual->expr; |
5002 | 4968 fname = expr->value.function.isym->name; |
5003 if (specific->ts.type != BT_UNKNOWN) | 4969 |
5004 return gfc_convert_constant (expr->value.function.actual->expr, | 4970 if ((tmp->ts.type != BT_INTEGER || tmp->ts.kind != gfc_integer_4_kind) |
5005 specific->ts.type, specific->ts.kind); | 4971 && (strcmp (fname, "min1") == 0 || strcmp (fname, "max1") == 0)) |
5006 | 4972 { |
5007 return gfc_copy_expr (expr->value.function.actual->expr); | 4973 ret = gfc_convert_constant (tmp, BT_INTEGER, gfc_integer_4_kind); |
4974 } | |
4975 else if ((tmp->ts.type != BT_REAL || tmp->ts.kind != gfc_real_4_kind) | |
4976 && (strcmp (fname, "amin0") == 0 || strcmp (fname, "amax0") == 0)) | |
4977 { | |
4978 ret = gfc_convert_constant (tmp, BT_REAL, gfc_real_4_kind); | |
4979 } | |
4980 else | |
4981 ret = gfc_copy_expr (tmp); | |
4982 | |
4983 return ret; | |
4984 | |
5008 } | 4985 } |
5009 | 4986 |
5010 | 4987 |
5011 gfc_expr * | 4988 gfc_expr * |
5012 gfc_simplify_min (gfc_expr *e) | 4989 gfc_simplify_min (gfc_expr *e) |
5370 return result; | 5347 return result; |
5371 } | 5348 } |
5372 | 5349 |
5373 /* Simplify minloc and maxloc for constant arrays. */ | 5350 /* Simplify minloc and maxloc for constant arrays. */ |
5374 | 5351 |
5375 gfc_expr * | 5352 static gfc_expr * |
5376 gfc_simplify_minmaxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, | 5353 gfc_simplify_minmaxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, |
5377 gfc_expr *kind, gfc_expr *back, int sign) | 5354 gfc_expr *kind, gfc_expr *back, int sign) |
5378 { | 5355 { |
5379 gfc_expr *result; | 5356 gfc_expr *result; |
5380 gfc_expr *extremum; | 5357 gfc_expr *extremum; |
5404 if (back->expr_type != EXPR_CONSTANT) | 5381 if (back->expr_type != EXPR_CONSTANT) |
5405 return NULL; | 5382 return NULL; |
5406 | 5383 |
5407 back_val = back->value.logical; | 5384 back_val = back->value.logical; |
5408 } | 5385 } |
5409 | 5386 |
5410 if (sign < 0) | 5387 if (sign < 0) |
5411 init_val = INT_MAX; | 5388 init_val = INT_MAX; |
5412 else if (sign > 0) | 5389 else if (sign > 0) |
5413 init_val = INT_MIN; | 5390 init_val = INT_MIN; |
5414 else | 5391 else |
5448 gfc_expr * | 5425 gfc_expr * |
5449 gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind, | 5426 gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind, |
5450 gfc_expr *back) | 5427 gfc_expr *back) |
5451 { | 5428 { |
5452 return gfc_simplify_minmaxloc (array, dim, mask, kind, back, 1); | 5429 return gfc_simplify_minmaxloc (array, dim, mask, kind, back, 1); |
5430 } | |
5431 | |
5432 /* Simplify findloc to scalar. Similar to | |
5433 simplify_minmaxloc_to_scalar. */ | |
5434 | |
5435 static gfc_expr * | |
5436 simplify_findloc_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *value, | |
5437 gfc_expr *mask, int back_val) | |
5438 { | |
5439 gfc_expr *a, *m; | |
5440 gfc_constructor *array_ctor, *mask_ctor; | |
5441 mpz_t count; | |
5442 | |
5443 mpz_set_si (result->value.integer, 0); | |
5444 | |
5445 /* Shortcut for constant .FALSE. MASK. */ | |
5446 if (mask | |
5447 && mask->expr_type == EXPR_CONSTANT | |
5448 && !mask->value.logical) | |
5449 return result; | |
5450 | |
5451 array_ctor = gfc_constructor_first (array->value.constructor); | |
5452 if (mask && mask->expr_type == EXPR_ARRAY) | |
5453 mask_ctor = gfc_constructor_first (mask->value.constructor); | |
5454 else | |
5455 mask_ctor = NULL; | |
5456 | |
5457 mpz_init_set_si (count, 0); | |
5458 while (array_ctor) | |
5459 { | |
5460 mpz_add_ui (count, count, 1); | |
5461 a = array_ctor->expr; | |
5462 array_ctor = gfc_constructor_next (array_ctor); | |
5463 /* A constant MASK equals .TRUE. here and can be ignored. */ | |
5464 if (mask_ctor) | |
5465 { | |
5466 m = mask_ctor->expr; | |
5467 mask_ctor = gfc_constructor_next (mask_ctor); | |
5468 if (!m->value.logical) | |
5469 continue; | |
5470 } | |
5471 if (gfc_compare_expr (a, value, INTRINSIC_EQ) == 0) | |
5472 { | |
5473 /* We have a match. If BACK is true, continue so we find | |
5474 the last one. */ | |
5475 mpz_set (result->value.integer, count); | |
5476 if (!back_val) | |
5477 break; | |
5478 } | |
5479 } | |
5480 mpz_clear (count); | |
5481 return result; | |
5482 } | |
5483 | |
5484 /* Simplify findloc in the absence of a dim argument. Similar to | |
5485 simplify_minmaxloc_nodim. */ | |
5486 | |
5487 static gfc_expr * | |
5488 simplify_findloc_nodim (gfc_expr *result, gfc_expr *value, gfc_expr *array, | |
5489 gfc_expr *mask, bool back_val) | |
5490 { | |
5491 ssize_t res[GFC_MAX_DIMENSIONS]; | |
5492 int i, n; | |
5493 gfc_constructor *result_ctor, *array_ctor, *mask_ctor; | |
5494 ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS], | |
5495 sstride[GFC_MAX_DIMENSIONS]; | |
5496 gfc_expr *a, *m; | |
5497 bool continue_loop; | |
5498 bool ma; | |
5499 | |
5500 for (i = 0; i<array->rank; i++) | |
5501 res[i] = -1; | |
5502 | |
5503 /* Shortcut for constant .FALSE. MASK. */ | |
5504 if (mask | |
5505 && mask->expr_type == EXPR_CONSTANT | |
5506 && !mask->value.logical) | |
5507 goto finish; | |
5508 | |
5509 for (i = 0; i < array->rank; i++) | |
5510 { | |
5511 count[i] = 0; | |
5512 sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]); | |
5513 extent[i] = mpz_get_si (array->shape[i]); | |
5514 if (extent[i] <= 0) | |
5515 goto finish; | |
5516 } | |
5517 | |
5518 continue_loop = true; | |
5519 array_ctor = gfc_constructor_first (array->value.constructor); | |
5520 if (mask && mask->rank > 0) | |
5521 mask_ctor = gfc_constructor_first (mask->value.constructor); | |
5522 else | |
5523 mask_ctor = NULL; | |
5524 | |
5525 /* Loop over the array elements (and mask), keeping track of | |
5526 the indices to return. */ | |
5527 while (continue_loop) | |
5528 { | |
5529 do | |
5530 { | |
5531 a = array_ctor->expr; | |
5532 if (mask_ctor) | |
5533 { | |
5534 m = mask_ctor->expr; | |
5535 ma = m->value.logical; | |
5536 mask_ctor = gfc_constructor_next (mask_ctor); | |
5537 } | |
5538 else | |
5539 ma = true; | |
5540 | |
5541 if (ma && gfc_compare_expr (a, value, INTRINSIC_EQ) == 0) | |
5542 { | |
5543 for (i = 0; i<array->rank; i++) | |
5544 res[i] = count[i]; | |
5545 if (!back_val) | |
5546 goto finish; | |
5547 } | |
5548 array_ctor = gfc_constructor_next (array_ctor); | |
5549 count[0] ++; | |
5550 } while (count[0] != extent[0]); | |
5551 n = 0; | |
5552 do | |
5553 { | |
5554 /* When we get to the end of a dimension, reset it and increment | |
5555 the next dimension. */ | |
5556 count[n] = 0; | |
5557 n++; | |
5558 if (n >= array->rank) | |
5559 { | |
5560 continue_loop = false; | |
5561 break; | |
5562 } | |
5563 else | |
5564 count[n] ++; | |
5565 } while (count[n] == extent[n]); | |
5566 } | |
5567 | |
5568 finish: | |
5569 result_ctor = gfc_constructor_first (result->value.constructor); | |
5570 for (i = 0; i<array->rank; i++) | |
5571 { | |
5572 gfc_expr *r_expr; | |
5573 r_expr = result_ctor->expr; | |
5574 mpz_set_si (r_expr->value.integer, res[i] + 1); | |
5575 result_ctor = gfc_constructor_next (result_ctor); | |
5576 } | |
5577 return result; | |
5578 } | |
5579 | |
5580 | |
5581 /* Simplify findloc to an array. Similar to | |
5582 simplify_minmaxloc_to_array. */ | |
5583 | |
5584 static gfc_expr * | |
5585 simplify_findloc_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *value, | |
5586 gfc_expr *dim, gfc_expr *mask, bool back_val) | |
5587 { | |
5588 mpz_t size; | |
5589 int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride; | |
5590 gfc_expr **arrayvec, **resultvec, **base, **src, **dest; | |
5591 gfc_constructor *array_ctor, *mask_ctor, *result_ctor; | |
5592 | |
5593 int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS], | |
5594 sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS], | |
5595 tmpstride[GFC_MAX_DIMENSIONS]; | |
5596 | |
5597 /* Shortcut for constant .FALSE. MASK. */ | |
5598 if (mask | |
5599 && mask->expr_type == EXPR_CONSTANT | |
5600 && !mask->value.logical) | |
5601 return result; | |
5602 | |
5603 /* Build an indexed table for array element expressions to minimize | |
5604 linked-list traversal. Masked elements are set to NULL. */ | |
5605 gfc_array_size (array, &size); | |
5606 arraysize = mpz_get_ui (size); | |
5607 mpz_clear (size); | |
5608 | |
5609 arrayvec = XCNEWVEC (gfc_expr*, arraysize); | |
5610 | |
5611 array_ctor = gfc_constructor_first (array->value.constructor); | |
5612 mask_ctor = NULL; | |
5613 if (mask && mask->expr_type == EXPR_ARRAY) | |
5614 mask_ctor = gfc_constructor_first (mask->value.constructor); | |
5615 | |
5616 for (i = 0; i < arraysize; ++i) | |
5617 { | |
5618 arrayvec[i] = array_ctor->expr; | |
5619 array_ctor = gfc_constructor_next (array_ctor); | |
5620 | |
5621 if (mask_ctor) | |
5622 { | |
5623 if (!mask_ctor->expr->value.logical) | |
5624 arrayvec[i] = NULL; | |
5625 | |
5626 mask_ctor = gfc_constructor_next (mask_ctor); | |
5627 } | |
5628 } | |
5629 | |
5630 /* Same for the result expression. */ | |
5631 gfc_array_size (result, &size); | |
5632 resultsize = mpz_get_ui (size); | |
5633 mpz_clear (size); | |
5634 | |
5635 resultvec = XCNEWVEC (gfc_expr*, resultsize); | |
5636 result_ctor = gfc_constructor_first (result->value.constructor); | |
5637 for (i = 0; i < resultsize; ++i) | |
5638 { | |
5639 resultvec[i] = result_ctor->expr; | |
5640 result_ctor = gfc_constructor_next (result_ctor); | |
5641 } | |
5642 | |
5643 gfc_extract_int (dim, &dim_index); | |
5644 | |
5645 dim_index -= 1; /* Zero-base index. */ | |
5646 dim_extent = 0; | |
5647 dim_stride = 0; | |
5648 | |
5649 for (i = 0, n = 0; i < array->rank; ++i) | |
5650 { | |
5651 count[i] = 0; | |
5652 tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]); | |
5653 if (i == dim_index) | |
5654 { | |
5655 dim_extent = mpz_get_si (array->shape[i]); | |
5656 dim_stride = tmpstride[i]; | |
5657 continue; | |
5658 } | |
5659 | |
5660 extent[n] = mpz_get_si (array->shape[i]); | |
5661 sstride[n] = tmpstride[i]; | |
5662 dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1]; | |
5663 n += 1; | |
5664 } | |
5665 | |
5666 done = resultsize <= 0; | |
5667 base = arrayvec; | |
5668 dest = resultvec; | |
5669 while (!done) | |
5670 { | |
5671 for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n) | |
5672 { | |
5673 if (*src && gfc_compare_expr (*src, value, INTRINSIC_EQ) == 0) | |
5674 { | |
5675 mpz_set_si ((*dest)->value.integer, n + 1); | |
5676 if (!back_val) | |
5677 break; | |
5678 } | |
5679 } | |
5680 | |
5681 count[0]++; | |
5682 base += sstride[0]; | |
5683 dest += dstride[0]; | |
5684 | |
5685 n = 0; | |
5686 while (!done && count[n] == extent[n]) | |
5687 { | |
5688 count[n] = 0; | |
5689 base -= sstride[n] * extent[n]; | |
5690 dest -= dstride[n] * extent[n]; | |
5691 | |
5692 n++; | |
5693 if (n < result->rank) | |
5694 { | |
5695 /* If the nested loop is unrolled GFC_MAX_DIMENSIONS | |
5696 times, we'd warn for the last iteration, because the | |
5697 array index will have already been incremented to the | |
5698 array sizes, and we can't tell that this must make | |
5699 the test against result->rank false, because ranks | |
5700 must not exceed GFC_MAX_DIMENSIONS. */ | |
5701 GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds) | |
5702 count[n]++; | |
5703 base += sstride[n]; | |
5704 dest += dstride[n]; | |
5705 GCC_DIAGNOSTIC_POP | |
5706 } | |
5707 else | |
5708 done = true; | |
5709 } | |
5710 } | |
5711 | |
5712 /* Place updated expression in result constructor. */ | |
5713 result_ctor = gfc_constructor_first (result->value.constructor); | |
5714 for (i = 0; i < resultsize; ++i) | |
5715 { | |
5716 result_ctor->expr = resultvec[i]; | |
5717 result_ctor = gfc_constructor_next (result_ctor); | |
5718 } | |
5719 | |
5720 free (arrayvec); | |
5721 free (resultvec); | |
5722 return result; | |
5723 } | |
5724 | |
5725 /* Simplify findloc. */ | |
5726 | |
5727 gfc_expr * | |
5728 gfc_simplify_findloc (gfc_expr *array, gfc_expr *value, gfc_expr *dim, | |
5729 gfc_expr *mask, gfc_expr *kind, gfc_expr *back) | |
5730 { | |
5731 gfc_expr *result; | |
5732 int ikind; | |
5733 bool back_val = false; | |
5734 | |
5735 if (!is_constant_array_expr (array) | |
5736 || !gfc_is_constant_expr (dim)) | |
5737 return NULL; | |
5738 | |
5739 if (! gfc_is_constant_expr (value)) | |
5740 return 0; | |
5741 | |
5742 if (mask | |
5743 && !is_constant_array_expr (mask) | |
5744 && mask->expr_type != EXPR_CONSTANT) | |
5745 return NULL; | |
5746 | |
5747 if (kind) | |
5748 { | |
5749 if (gfc_extract_int (kind, &ikind, -1)) | |
5750 return NULL; | |
5751 } | |
5752 else | |
5753 ikind = gfc_default_integer_kind; | |
5754 | |
5755 if (back) | |
5756 { | |
5757 if (back->expr_type != EXPR_CONSTANT) | |
5758 return NULL; | |
5759 | |
5760 back_val = back->value.logical; | |
5761 } | |
5762 | |
5763 if (dim) | |
5764 { | |
5765 result = transformational_result (array, dim, BT_INTEGER, | |
5766 ikind, &array->where); | |
5767 init_result_expr (result, 0, array); | |
5768 | |
5769 if (array->rank == 1) | |
5770 return simplify_findloc_to_scalar (result, array, value, mask, | |
5771 back_val); | |
5772 else | |
5773 return simplify_findloc_to_array (result, array, value, dim, mask, | |
5774 back_val); | |
5775 } | |
5776 else | |
5777 { | |
5778 result = new_array (BT_INTEGER, ikind, array->rank, &array->where); | |
5779 return simplify_findloc_nodim (result, value, array, mask, back_val); | |
5780 } | |
5781 return NULL; | |
5453 } | 5782 } |
5454 | 5783 |
5455 gfc_expr * | 5784 gfc_expr * |
5456 gfc_simplify_maxexponent (gfc_expr *x) | 5785 gfc_simplify_maxexponent (gfc_expr *x) |
5457 { | 5786 { |
5585 | 5914 |
5586 gfc_expr * | 5915 gfc_expr * |
5587 gfc_simplify_nearest (gfc_expr *x, gfc_expr *s) | 5916 gfc_simplify_nearest (gfc_expr *x, gfc_expr *s) |
5588 { | 5917 { |
5589 gfc_expr *result; | 5918 gfc_expr *result; |
5590 mp_exp_t emin, emax; | 5919 mpfr_exp_t emin, emax; |
5591 int kind; | 5920 int kind; |
5592 | 5921 |
5593 if (x->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT) | 5922 if (x->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT) |
5594 return NULL; | 5923 return NULL; |
5595 | 5924 |
5599 emin = mpfr_get_emin (); | 5928 emin = mpfr_get_emin (); |
5600 emax = mpfr_get_emax (); | 5929 emax = mpfr_get_emax (); |
5601 | 5930 |
5602 /* Set emin and emax for the current model number. */ | 5931 /* Set emin and emax for the current model number. */ |
5603 kind = gfc_validate_kind (BT_REAL, x->ts.kind, 0); | 5932 kind = gfc_validate_kind (BT_REAL, x->ts.kind, 0); |
5604 mpfr_set_emin ((mp_exp_t) gfc_real_kinds[kind].min_exponent - | 5933 mpfr_set_emin ((mpfr_exp_t) gfc_real_kinds[kind].min_exponent - |
5605 mpfr_get_prec(result->value.real) + 1); | 5934 mpfr_get_prec(result->value.real) + 1); |
5606 mpfr_set_emax ((mp_exp_t) gfc_real_kinds[kind].max_exponent - 1); | 5935 mpfr_set_emax ((mpfr_exp_t) gfc_real_kinds[kind].max_exponent - 1); |
5607 mpfr_check_range (result->value.real, 0, GMP_RNDU); | 5936 mpfr_check_range (result->value.real, 0, MPFR_RNDU); |
5608 | 5937 |
5609 if (mpfr_sgn (s->value.real) > 0) | 5938 if (mpfr_sgn (s->value.real) > 0) |
5610 { | 5939 { |
5611 mpfr_nextabove (result->value.real); | 5940 mpfr_nextabove (result->value.real); |
5612 mpfr_subnormalize (result->value.real, 0, GMP_RNDU); | 5941 mpfr_subnormalize (result->value.real, 0, MPFR_RNDU); |
5613 } | 5942 } |
5614 else | 5943 else |
5615 { | 5944 { |
5616 mpfr_nextbelow (result->value.real); | 5945 mpfr_nextbelow (result->value.real); |
5617 mpfr_subnormalize (result->value.real, 0, GMP_RNDD); | 5946 mpfr_subnormalize (result->value.real, 0, MPFR_RNDD); |
5618 } | 5947 } |
5619 | 5948 |
5620 mpfr_set_emin (emin); | 5949 mpfr_set_emin (emin); |
5621 mpfr_set_emax (emax); | 5950 mpfr_set_emax (emax); |
5622 | 5951 |
5681 gfc_simplify_idnint (gfc_expr *e) | 6010 gfc_simplify_idnint (gfc_expr *e) |
5682 { | 6011 { |
5683 return simplify_nint ("IDNINT", e, NULL); | 6012 return simplify_nint ("IDNINT", e, NULL); |
5684 } | 6013 } |
5685 | 6014 |
6015 static int norm2_scale; | |
5686 | 6016 |
5687 static gfc_expr * | 6017 static gfc_expr * |
5688 add_squared (gfc_expr *result, gfc_expr *e) | 6018 norm2_add_squared (gfc_expr *result, gfc_expr *e) |
5689 { | 6019 { |
5690 mpfr_t tmp; | 6020 mpfr_t tmp; |
5691 | 6021 |
5692 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT); | 6022 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT); |
5693 gcc_assert (result->ts.type == BT_REAL | 6023 gcc_assert (result->ts.type == BT_REAL |
5694 && result->expr_type == EXPR_CONSTANT); | 6024 && result->expr_type == EXPR_CONSTANT); |
5695 | 6025 |
5696 gfc_set_model_kind (result->ts.kind); | 6026 gfc_set_model_kind (result->ts.kind); |
6027 int index = gfc_validate_kind (BT_REAL, result->ts.kind, false); | |
6028 mpfr_exp_t exp; | |
6029 if (mpfr_regular_p (result->value.real)) | |
6030 { | |
6031 exp = mpfr_get_exp (result->value.real); | |
6032 /* If result is getting close to overflowing, scale down. */ | |
6033 if (exp >= gfc_real_kinds[index].max_exponent - 4 | |
6034 && norm2_scale <= gfc_real_kinds[index].max_exponent - 2) | |
6035 { | |
6036 norm2_scale += 2; | |
6037 mpfr_div_ui (result->value.real, result->value.real, 16, | |
6038 GFC_RND_MODE); | |
6039 } | |
6040 } | |
6041 | |
5697 mpfr_init (tmp); | 6042 mpfr_init (tmp); |
5698 mpfr_pow_ui (tmp, e->value.real, 2, GFC_RND_MODE); | 6043 if (mpfr_regular_p (e->value.real)) |
6044 { | |
6045 exp = mpfr_get_exp (e->value.real); | |
6046 /* If e**2 would overflow or close to overflowing, scale down. */ | |
6047 if (exp - norm2_scale >= gfc_real_kinds[index].max_exponent / 2 - 2) | |
6048 { | |
6049 int new_scale = gfc_real_kinds[index].max_exponent / 2 + 4; | |
6050 mpfr_set_ui (tmp, 1, GFC_RND_MODE); | |
6051 mpfr_set_exp (tmp, new_scale - norm2_scale); | |
6052 mpfr_div (result->value.real, result->value.real, tmp, GFC_RND_MODE); | |
6053 mpfr_div (result->value.real, result->value.real, tmp, GFC_RND_MODE); | |
6054 norm2_scale = new_scale; | |
6055 } | |
6056 } | |
6057 if (norm2_scale) | |
6058 { | |
6059 mpfr_set_ui (tmp, 1, GFC_RND_MODE); | |
6060 mpfr_set_exp (tmp, norm2_scale); | |
6061 mpfr_div (tmp, e->value.real, tmp, GFC_RND_MODE); | |
6062 } | |
6063 else | |
6064 mpfr_set (tmp, e->value.real, GFC_RND_MODE); | |
6065 mpfr_pow_ui (tmp, tmp, 2, GFC_RND_MODE); | |
5699 mpfr_add (result->value.real, result->value.real, tmp, | 6066 mpfr_add (result->value.real, result->value.real, tmp, |
5700 GFC_RND_MODE); | 6067 GFC_RND_MODE); |
5701 mpfr_clear (tmp); | 6068 mpfr_clear (tmp); |
5702 | 6069 |
5703 return result; | 6070 return result; |
5704 } | 6071 } |
5705 | 6072 |
5706 | 6073 |
5707 static gfc_expr * | 6074 static gfc_expr * |
5708 do_sqrt (gfc_expr *result, gfc_expr *e) | 6075 norm2_do_sqrt (gfc_expr *result, gfc_expr *e) |
5709 { | 6076 { |
5710 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT); | 6077 gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT); |
5711 gcc_assert (result->ts.type == BT_REAL | 6078 gcc_assert (result->ts.type == BT_REAL |
5712 && result->expr_type == EXPR_CONSTANT); | 6079 && result->expr_type == EXPR_CONSTANT); |
5713 | 6080 |
5714 mpfr_set (result->value.real, e->value.real, GFC_RND_MODE); | 6081 if (result != e) |
6082 mpfr_set (result->value.real, e->value.real, GFC_RND_MODE); | |
5715 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE); | 6083 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE); |
6084 if (norm2_scale && mpfr_regular_p (result->value.real)) | |
6085 { | |
6086 mpfr_t tmp; | |
6087 mpfr_init (tmp); | |
6088 mpfr_set_ui (tmp, 1, GFC_RND_MODE); | |
6089 mpfr_set_exp (tmp, norm2_scale); | |
6090 mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE); | |
6091 mpfr_clear (tmp); | |
6092 } | |
6093 norm2_scale = 0; | |
6094 | |
5716 return result; | 6095 return result; |
5717 } | 6096 } |
5718 | 6097 |
5719 | 6098 |
5720 gfc_expr * | 6099 gfc_expr * |
5733 init_result_expr (result, 0, NULL); | 6112 init_result_expr (result, 0, NULL); |
5734 | 6113 |
5735 if (size_zero) | 6114 if (size_zero) |
5736 return result; | 6115 return result; |
5737 | 6116 |
6117 norm2_scale = 0; | |
5738 if (!dim || e->rank == 1) | 6118 if (!dim || e->rank == 1) |
5739 { | 6119 { |
5740 result = simplify_transformation_to_scalar (result, e, NULL, | 6120 result = simplify_transformation_to_scalar (result, e, NULL, |
5741 add_squared); | 6121 norm2_add_squared); |
5742 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE); | 6122 mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE); |
6123 if (norm2_scale && mpfr_regular_p (result->value.real)) | |
6124 { | |
6125 mpfr_t tmp; | |
6126 mpfr_init (tmp); | |
6127 mpfr_set_ui (tmp, 1, GFC_RND_MODE); | |
6128 mpfr_set_exp (tmp, norm2_scale); | |
6129 mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE); | |
6130 mpfr_clear (tmp); | |
6131 } | |
6132 norm2_scale = 0; | |
5743 } | 6133 } |
5744 else | 6134 else |
5745 result = simplify_transformation_to_array (result, e, dim, NULL, | 6135 result = simplify_transformation_to_array (result, e, dim, NULL, |
5746 add_squared, &do_sqrt); | 6136 norm2_add_squared, |
6137 norm2_do_sqrt); | |
5747 | 6138 |
5748 return result; | 6139 return result; |
5749 } | 6140 } |
5750 | 6141 |
5751 | 6142 |
5922 result->value.logical = result->value.logical != e->value.logical; | 6313 result->value.logical = result->value.logical != e->value.logical; |
5923 return result; | 6314 return result; |
5924 } | 6315 } |
5925 | 6316 |
5926 | 6317 |
6318 gfc_expr * | |
6319 gfc_simplify_is_contiguous (gfc_expr *array) | |
6320 { | |
6321 if (gfc_is_simply_contiguous (array, false, true)) | |
6322 return gfc_get_logical_expr (gfc_default_logical_kind, &array->where, 1); | |
6323 | |
6324 if (gfc_is_not_contiguous (array)) | |
6325 return gfc_get_logical_expr (gfc_default_logical_kind, &array->where, 0); | |
6326 | |
6327 return NULL; | |
6328 } | |
6329 | |
5927 | 6330 |
5928 gfc_expr * | 6331 gfc_expr * |
5929 gfc_simplify_parity (gfc_expr *e, gfc_expr *dim) | 6332 gfc_simplify_parity (gfc_expr *e, gfc_expr *dim) |
5930 { | 6333 { |
5931 return simplify_transformation (e, dim, NULL, 0, do_xor); | 6334 return simplify_transformation (e, dim, NULL, 0, do_xor); |
6050 | 6453 |
6051 gfc_expr * | 6454 gfc_expr * |
6052 gfc_simplify_real (gfc_expr *e, gfc_expr *k) | 6455 gfc_simplify_real (gfc_expr *e, gfc_expr *k) |
6053 { | 6456 { |
6054 gfc_expr *result = NULL; | 6457 gfc_expr *result = NULL; |
6055 int kind; | 6458 int kind, tmp1, tmp2; |
6459 | |
6460 /* Convert BOZ to real, and return without range checking. */ | |
6461 if (e->ts.type == BT_BOZ) | |
6462 { | |
6463 /* Determine kind for conversion of the BOZ. */ | |
6464 if (k) | |
6465 gfc_extract_int (k, &kind); | |
6466 else | |
6467 kind = gfc_default_real_kind; | |
6468 | |
6469 if (!gfc_boz2real (e, kind)) | |
6470 return NULL; | |
6471 result = gfc_copy_expr (e); | |
6472 return result; | |
6473 } | |
6056 | 6474 |
6057 if (e->ts.type == BT_COMPLEX) | 6475 if (e->ts.type == BT_COMPLEX) |
6058 kind = get_kind (BT_REAL, k, "REAL", e->ts.kind); | 6476 kind = get_kind (BT_REAL, k, "REAL", e->ts.kind); |
6059 else | 6477 else |
6060 kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind); | 6478 kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind); |
6063 return &gfc_bad_expr; | 6481 return &gfc_bad_expr; |
6064 | 6482 |
6065 if (e->expr_type != EXPR_CONSTANT) | 6483 if (e->expr_type != EXPR_CONSTANT) |
6066 return NULL; | 6484 return NULL; |
6067 | 6485 |
6068 if (convert_boz (e, kind) == &gfc_bad_expr) | 6486 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra |
6069 return &gfc_bad_expr; | 6487 warnings. */ |
6488 tmp1 = warn_conversion; | |
6489 tmp2 = warn_conversion_extra; | |
6490 warn_conversion = warn_conversion_extra = 0; | |
6070 | 6491 |
6071 result = gfc_convert_constant (e, BT_REAL, kind); | 6492 result = gfc_convert_constant (e, BT_REAL, kind); |
6493 | |
6494 warn_conversion = tmp1; | |
6495 warn_conversion_extra = tmp2; | |
6496 | |
6072 if (result == &gfc_bad_expr) | 6497 if (result == &gfc_bad_expr) |
6073 return &gfc_bad_expr; | 6498 return &gfc_bad_expr; |
6074 | 6499 |
6075 return range_check (result, "REAL"); | 6500 return range_check (result, "REAL"); |
6076 } | 6501 } |
6239 /* Proceed with simplification, unpacking the array. */ | 6664 /* Proceed with simplification, unpacking the array. */ |
6240 | 6665 |
6241 mpz_init (index); | 6666 mpz_init (index); |
6242 rank = 0; | 6667 rank = 0; |
6243 | 6668 |
6669 for (i = 0; i < GFC_MAX_DIMENSIONS; i++) | |
6670 x[i] = 0; | |
6671 | |
6244 for (;;) | 6672 for (;;) |
6245 { | 6673 { |
6246 e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank); | 6674 e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank); |
6247 if (e == NULL) | 6675 if (e == NULL) |
6248 break; | 6676 break; |
6263 for (i = 0; i < rank; i++) | 6691 for (i = 0; i < rank; i++) |
6264 order[i] = i; | 6692 order[i] = i; |
6265 } | 6693 } |
6266 else | 6694 else |
6267 { | 6695 { |
6268 for (i = 0; i < rank; i++) | 6696 mpz_t size; |
6269 x[i] = 0; | 6697 int order_size, shape_size; |
6698 | |
6699 if (order_exp->rank != shape_exp->rank) | |
6700 { | |
6701 gfc_error ("Shapes of ORDER at %L and SHAPE at %L are different", | |
6702 &order_exp->where, &shape_exp->where); | |
6703 return &gfc_bad_expr; | |
6704 } | |
6705 | |
6706 gfc_array_size (shape_exp, &size); | |
6707 shape_size = mpz_get_ui (size); | |
6708 mpz_clear (size); | |
6709 gfc_array_size (order_exp, &size); | |
6710 order_size = mpz_get_ui (size); | |
6711 mpz_clear (size); | |
6712 if (order_size != shape_size) | |
6713 { | |
6714 gfc_error ("Sizes of ORDER at %L and SHAPE at %L are different", | |
6715 &order_exp->where, &shape_exp->where); | |
6716 return &gfc_bad_expr; | |
6717 } | |
6270 | 6718 |
6271 for (i = 0; i < rank; i++) | 6719 for (i = 0; i < rank; i++) |
6272 { | 6720 { |
6273 e = gfc_constructor_lookup_expr (order_exp->value.constructor, i); | 6721 e = gfc_constructor_lookup_expr (order_exp->value.constructor, i); |
6274 gcc_assert (e); | 6722 gcc_assert (e); |
6275 | 6723 |
6276 gfc_extract_int (e, &order[i]); | 6724 gfc_extract_int (e, &order[i]); |
6277 | 6725 |
6278 gcc_assert (order[i] >= 1 && order[i] <= rank); | 6726 if (order[i] < 1 || order[i] > rank) |
6727 { | |
6728 gfc_error ("Element with a value of %d in ORDER at %L must be " | |
6729 "in the range [1, ..., %d] for the RESHAPE intrinsic " | |
6730 "near %L", order[i], &order_exp->where, rank, | |
6731 &shape_exp->where); | |
6732 return &gfc_bad_expr; | |
6733 } | |
6734 | |
6279 order[i]--; | 6735 order[i]--; |
6280 gcc_assert (x[order[i]] == 0); | 6736 if (x[order[i]] != 0) |
6737 { | |
6738 gfc_error ("ORDER at %L is not a permutation of the size of " | |
6739 "SHAPE at %L", &order_exp->where, &shape_exp->where); | |
6740 return &gfc_bad_expr; | |
6741 } | |
6281 x[order[i]] = 1; | 6742 x[order[i]] = 1; |
6282 } | 6743 } |
6283 } | 6744 } |
6284 | 6745 |
6285 /* Count the elements in the source and padding arrays. */ | 6746 /* Count the elements in the source and padding arrays. */ |
6554 c->value.character.string) + 1; | 7015 c->value.character.string) + 1; |
6555 if (indx > len) | 7016 if (indx > len) |
6556 indx = 0; | 7017 indx = 0; |
6557 } | 7018 } |
6558 else | 7019 else |
6559 { | 7020 for (indx = len; indx > 0; indx--) |
6560 i = 0; | 7021 { |
6561 for (indx = len; indx > 0; indx--) | 7022 for (i = 0; i < lenc; i++) |
6562 { | 7023 { |
6563 for (i = 0; i < lenc; i++) | 7024 if (c->value.character.string[i] |
6564 { | 7025 == e->value.character.string[indx - 1]) |
6565 if (c->value.character.string[i] | 7026 break; |
6566 == e->value.character.string[indx - 1]) | 7027 } |
6567 break; | 7028 if (i < lenc) |
6568 } | 7029 break; |
6569 if (i < lenc) | 7030 } |
6570 break; | |
6571 } | |
6572 } | |
6573 } | 7031 } |
6574 | 7032 |
6575 result = gfc_get_int_expr (k, &e->where, indx); | 7033 result = gfc_get_int_expr (k, &e->where, indx); |
6576 return range_check (result, "SCAN"); | 7034 return range_check (result, "SCAN"); |
6577 } | 7035 } |
6938 gfc_expr * | 7396 gfc_expr * |
6939 gfc_simplify_sizeof (gfc_expr *x) | 7397 gfc_simplify_sizeof (gfc_expr *x) |
6940 { | 7398 { |
6941 gfc_expr *result = NULL; | 7399 gfc_expr *result = NULL; |
6942 mpz_t array_size; | 7400 mpz_t array_size; |
7401 size_t res_size; | |
6943 | 7402 |
6944 if (x->ts.type == BT_CLASS || x->ts.deferred) | 7403 if (x->ts.type == BT_CLASS || x->ts.deferred) |
6945 return NULL; | 7404 return NULL; |
6946 | 7405 |
6947 if (x->ts.type == BT_CHARACTER | 7406 if (x->ts.type == BT_CHARACTER |
6953 && !gfc_array_size (x, &array_size)) | 7412 && !gfc_array_size (x, &array_size)) |
6954 return NULL; | 7413 return NULL; |
6955 | 7414 |
6956 result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind, | 7415 result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind, |
6957 &x->where); | 7416 &x->where); |
6958 mpz_set_si (result->value.integer, gfc_target_expr_size (x)); | 7417 gfc_target_expr_size (x, &res_size); |
7418 mpz_set_si (result->value.integer, res_size); | |
6959 | 7419 |
6960 return result; | 7420 return result; |
6961 } | 7421 } |
6962 | 7422 |
6963 | 7423 |
6967 gfc_simplify_storage_size (gfc_expr *x, | 7427 gfc_simplify_storage_size (gfc_expr *x, |
6968 gfc_expr *kind) | 7428 gfc_expr *kind) |
6969 { | 7429 { |
6970 gfc_expr *result = NULL; | 7430 gfc_expr *result = NULL; |
6971 int k; | 7431 int k; |
7432 size_t siz; | |
6972 | 7433 |
6973 if (x->ts.type == BT_CLASS || x->ts.deferred) | 7434 if (x->ts.type == BT_CLASS || x->ts.deferred) |
6974 return NULL; | 7435 return NULL; |
6975 | 7436 |
6976 if (x->ts.type == BT_CHARACTER && x->expr_type != EXPR_CONSTANT | 7437 if (x->ts.type == BT_CHARACTER && x->expr_type != EXPR_CONSTANT |
6982 if (k == -1) | 7443 if (k == -1) |
6983 return &gfc_bad_expr; | 7444 return &gfc_bad_expr; |
6984 | 7445 |
6985 result = gfc_get_constant_expr (BT_INTEGER, k, &x->where); | 7446 result = gfc_get_constant_expr (BT_INTEGER, k, &x->where); |
6986 | 7447 |
6987 mpz_set_si (result->value.integer, gfc_element_size (x)); | 7448 gfc_element_size (x, &siz); |
7449 mpz_set_si (result->value.integer, siz); | |
6988 mpz_mul_ui (result->value.integer, result->value.integer, BITS_PER_UNIT); | 7450 mpz_mul_ui (result->value.integer, result->value.integer, BITS_PER_UNIT); |
6989 | 7451 |
6990 return range_check (result, "STORAGE_SIZE"); | 7452 return range_check (result, "STORAGE_SIZE"); |
6991 } | 7453 } |
6992 | 7454 |
7088 | 7550 |
7089 gfc_expr * | 7551 gfc_expr * |
7090 gfc_simplify_sngl (gfc_expr *a) | 7552 gfc_simplify_sngl (gfc_expr *a) |
7091 { | 7553 { |
7092 gfc_expr *result; | 7554 gfc_expr *result; |
7555 int tmp1, tmp2; | |
7093 | 7556 |
7094 if (a->expr_type != EXPR_CONSTANT) | 7557 if (a->expr_type != EXPR_CONSTANT) |
7095 return NULL; | 7558 return NULL; |
7096 | 7559 |
7560 /* For explicit conversion, turn off -Wconversion and -Wconversion-extra | |
7561 warnings. */ | |
7562 tmp1 = warn_conversion; | |
7563 tmp2 = warn_conversion_extra; | |
7564 warn_conversion = warn_conversion_extra = 0; | |
7565 | |
7097 result = gfc_real2real (a, gfc_default_real_kind); | 7566 result = gfc_real2real (a, gfc_default_real_kind); |
7567 | |
7568 warn_conversion = tmp1; | |
7569 warn_conversion_extra = tmp2; | |
7570 | |
7098 return range_check (result, "SNGL"); | 7571 return range_check (result, "SNGL"); |
7099 } | 7572 } |
7100 | 7573 |
7101 | 7574 |
7102 gfc_expr * | 7575 gfc_expr * |
7181 mpz_init_set_ui (size, 1); | 7654 mpz_init_set_ui (size, 1); |
7182 | 7655 |
7183 nelem = mpz_get_si (size) * ncopies; | 7656 nelem = mpz_get_si (size) * ncopies; |
7184 if (nelem > flag_max_array_constructor) | 7657 if (nelem > flag_max_array_constructor) |
7185 { | 7658 { |
7186 if (gfc_current_ns->sym_root->n.sym->attr.flavor == FL_PARAMETER) | 7659 if (gfc_init_expr_flag) |
7187 { | 7660 { |
7188 gfc_error ("The number of elements (%d) in the array constructor " | 7661 gfc_error ("The number of elements (%d) in the array constructor " |
7189 "at %L requires an increase of the allowed %d upper " | 7662 "at %L requires an increase of the allowed %d upper " |
7190 "limit. See %<-fmax-array-constructor%> option.", | 7663 "limit. See %<-fmax-array-constructor%> option.", |
7191 nelem, &source->where, flag_max_array_constructor); | 7664 nelem, &source->where, flag_max_array_constructor); |
7193 } | 7666 } |
7194 else | 7667 else |
7195 return NULL; | 7668 return NULL; |
7196 } | 7669 } |
7197 | 7670 |
7198 if (source->expr_type == EXPR_CONSTANT) | 7671 if (source->expr_type == EXPR_CONSTANT |
7672 || source->expr_type == EXPR_STRUCTURE) | |
7199 { | 7673 { |
7200 gcc_assert (dim == 0); | 7674 gcc_assert (dim == 0); |
7201 | 7675 |
7202 result = gfc_get_array_expr (source->ts.type, source->ts.kind, | 7676 result = gfc_get_array_expr (source->ts.type, source->ts.kind, |
7203 &source->where); | 7677 &source->where); |
8007 goto oops; | 8481 goto oops; |
8008 } | 8482 } |
8009 break; | 8483 break; |
8010 | 8484 |
8011 case BT_CHARACTER: | 8485 case BT_CHARACTER: |
8012 if (type == BT_CHARACTER) | 8486 switch (type) |
8013 f = gfc_character2character; | 8487 { |
8014 else | 8488 case BT_INTEGER: |
8015 goto oops; | 8489 f = gfc_character2int; |
8490 break; | |
8491 | |
8492 case BT_REAL: | |
8493 f = gfc_character2real; | |
8494 break; | |
8495 | |
8496 case BT_COMPLEX: | |
8497 f = gfc_character2complex; | |
8498 break; | |
8499 | |
8500 case BT_CHARACTER: | |
8501 f = gfc_character2character; | |
8502 break; | |
8503 | |
8504 case BT_LOGICAL: | |
8505 f = gfc_character2logical; | |
8506 break; | |
8507 | |
8508 default: | |
8509 goto oops; | |
8510 } | |
8016 break; | 8511 break; |
8017 | 8512 |
8018 default: | 8513 default: |
8019 oops: | 8514 oops: |
8020 gfc_internal_error ("gfc_convert_constant(): Unexpected type"); | 8515 return &gfc_bad_expr; |
8021 } | 8516 } |
8022 | 8517 |
8023 result = NULL; | 8518 result = NULL; |
8024 | 8519 |
8025 switch (e->expr_type) | 8520 switch (e->expr_type) |
8044 gfc_expr *tmp; | 8539 gfc_expr *tmp; |
8045 if (c->iterator == NULL) | 8540 if (c->iterator == NULL) |
8046 { | 8541 { |
8047 if (c->expr->expr_type == EXPR_ARRAY) | 8542 if (c->expr->expr_type == EXPR_ARRAY) |
8048 tmp = gfc_convert_constant (c->expr, type, kind); | 8543 tmp = gfc_convert_constant (c->expr, type, kind); |
8544 else if (c->expr->expr_type == EXPR_OP) | |
8545 { | |
8546 if (!gfc_simplify_expr (c->expr, 1)) | |
8547 return &gfc_bad_expr; | |
8548 tmp = f (c->expr, kind); | |
8549 } | |
8049 else | 8550 else |
8050 tmp = f (c->expr, kind); | 8551 tmp = f (c->expr, kind); |
8051 } | 8552 } |
8052 else | 8553 else |
8053 tmp = gfc_convert_constant (c->expr, type, kind); | 8554 tmp = gfc_convert_constant (c->expr, type, kind); |