tree chrec_convert_aggressive (tree type, tree chrec) { tree inner_type, left, right, lc, rc, rtype; if (automatically_generated_chrec_p (chrec) || TREE_CODE (chrec) != POLYNOMIAL_CHREC) return NULL_TREE; inner_type = TREE_TYPE (chrec); if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type)) return NULL_TREE; /* If we cannot perform arithmetic in TYPE, avoid creating an scev. */ if (avoid_arithmetics_in_type_p (type)) return NULL_TREE; rtype = POINTER_TYPE_P (type) ? sizetype : type; left = CHREC_LEFT (chrec); right = CHREC_RIGHT (chrec); lc = chrec_convert_aggressive (type, left); if (!lc) lc = chrec_convert (type, left, NULL); rc = chrec_convert_aggressive (rtype, right); if (!rc) rc = chrec_convert (rtype, right, NULL); return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc); }
tree chrec_convert_aggressive (tree type, tree chrec, bool *fold_conversions) { tree inner_type, left, right, lc, rc, rtype; gcc_assert (fold_conversions != NULL); if (automatically_generated_chrec_p (chrec) || TREE_CODE (chrec) != POLYNOMIAL_CHREC) return NULL_TREE; inner_type = TREE_TYPE (chrec); if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type)) return NULL_TREE; if (useless_type_conversion_p (type, inner_type)) return NULL_TREE; if (!*fold_conversions && evolution_function_is_affine_p (chrec)) { tree base, step; struct loop *loop; loop = get_chrec_loop (chrec); base = CHREC_LEFT (chrec); step = CHREC_RIGHT (chrec); if (convert_affine_scev (loop, type, &base, &step, NULL, true)) return build_polynomial_chrec (loop->num, base, step); } rtype = POINTER_TYPE_P (type) ? sizetype : type; left = CHREC_LEFT (chrec); right = CHREC_RIGHT (chrec); lc = chrec_convert_aggressive (type, left, fold_conversions); if (!lc) lc = chrec_convert (type, left, NULL); rc = chrec_convert_aggressive (rtype, right, fold_conversions); if (!rc) rc = chrec_convert (rtype, right, NULL); *fold_conversions = true; return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc); }