------- Additional Comments From sebastian dot pop at cri dot ensmp dot fr 2005-04-29 19:51 ------- Subject: Re: [PR tree-optimization/21029, RFC] harmful chrec type conversions
Thanks to Roger Sayle for pointing me at this PR. Alexandre Oliva wrote: > > This is not a final patch; if the idea is considered sound, I'd simply > remove the if and the then-dead remaining code in chrec_convert. The code following the if is not dead, at least it still is used in some cases after hand inlining count_ev_in_wider_type. I would propose this patch that is about the same as yours > Index: gcc/ChangeLog > from Alexandre Oliva <[EMAIL PROTECTED]> > > PR tree-optimization/21029 > * tree-chrec.c (chrec_convert): Handle same-precision integral > types that differ in signedness like widening conversions. > with some more changes as follow: * tree-chrec.c (chrec_convert): Handle same-precision integral types that differ in signedness like widening conversions. Inline count_ev_in_wider_type. * tree-chrec.h (count_ev_in_wider_type): Remove declaration. * tree-scalar-evolution.c (count_ev_in_wider_type): Removed. Zdenek, does this change look right to you? Index: tree-chrec.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-chrec.c,v retrieving revision 2.15 diff -c -3 -p -r2.15 tree-chrec.c *** tree-chrec.c 21 Apr 2005 08:48:51 -0000 2.15 --- tree-chrec.c 29 Apr 2005 19:31:51 -0000 *************** tree *** 1036,1085 **** chrec_convert (tree type, tree chrec) { ! tree ct; ! if (automatically_generated_chrec_p (chrec)) return chrec; ! ct = chrec_type (chrec); if (ct == type) return chrec; ! if (TYPE_PRECISION (ct) < TYPE_PRECISION (type)) ! return count_ev_in_wider_type (type, chrec); ! ! switch (TREE_CODE (chrec)) { ! case POLYNOMIAL_CHREC: ! return build_polynomial_chrec (CHREC_VARIABLE (chrec), ! chrec_convert (type, ! CHREC_LEFT (chrec)), ! chrec_convert (type, ! CHREC_RIGHT (chrec))); ! ! default: ! { ! tree res = fold_convert (type, chrec); ! ! /* Don't propagate overflows. */ ! TREE_OVERFLOW (res) = 0; ! if (CONSTANT_CLASS_P (res)) ! TREE_CONSTANT_OVERFLOW (res) = 0; ! ! /* But reject constants that don't fit in their type after conversion. ! This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the ! natural values associated with TYPE_PRECISION and TYPE_UNSIGNED, ! and can cause problems later when computing niters of loops. Note ! that we don't do the check before converting because we don't want ! to reject conversions of negative chrecs to unsigned types. */ ! if (TREE_CODE (res) == INTEGER_CST ! && TREE_CODE (type) == INTEGER_TYPE ! && !int_fits_type_p (res, type)) ! res = chrec_dont_know; ! ! return res; ! } } } /* Returns the type of the chrec. */ --- 1036,1104 ---- chrec_convert (tree type, tree chrec) { ! tree ct, base, step; ! struct loop *loop; ! if (automatically_generated_chrec_p (chrec)) return chrec; ! ct = chrec_type (chrec); if (ct == type) return chrec; ! if (!evolution_function_is_affine_p (chrec)) { ! switch (TREE_CODE (chrec)) ! { ! case POLYNOMIAL_CHREC: ! return build_polynomial_chrec (CHREC_VARIABLE (chrec), ! chrec_convert (type, ! CHREC_LEFT (chrec)), ! chrec_convert (type, ! CHREC_RIGHT (chrec))); ! ! default: ! { ! tree res = fold_convert (type, chrec); ! ! /* Don't propagate overflows. */ ! TREE_OVERFLOW (res) = 0; ! if (CONSTANT_CLASS_P (res)) ! TREE_CONSTANT_OVERFLOW (res) = 0; ! ! /* But reject constants that don't fit in their type after ! conversion. This can happen if TYPE_MIN_VALUE or ! TYPE_MAX_VALUE are not the natural values associated ! with TYPE_PRECISION and TYPE_UNSIGNED, and can cause ! problems later when computing niters of loops. Note ! that we don't do the check before converting because we ! don't want to reject conversions of negative chrecs to ! unsigned types. */ ! if (TREE_CODE (res) == INTEGER_CST ! && TREE_CODE (type) == INTEGER_TYPE ! && !int_fits_type_p (res, type)) ! res = chrec_dont_know; ! ! return res; ! } ! } } + + /* BASE and STEP are INTEGER_CSTs. */ + base = CHREC_LEFT (chrec); + step = CHREC_RIGHT (chrec); + loop = current_loops->parray[CHREC_VARIABLE (chrec)]; + + /* TODO -- if we knew the statement at that the conversion occurs, + we could pass it to can_count_iv_in_wider_type and get a better + result. */ + step = can_count_iv_in_wider_type (loop, type, base, step, NULL_TREE); + if (!step) + return fold_convert (type, chrec); + + base = chrec_convert (type, base); + + return build_polynomial_chrec (CHREC_VARIABLE (chrec), base, step); } /* Returns the type of the chrec. */ Index: tree-chrec.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-chrec.h,v retrieving revision 2.8 diff -c -3 -p -r2.8 tree-chrec.h *** tree-chrec.h 28 Apr 2005 05:38:34 -0000 2.8 --- tree-chrec.h 29 Apr 2005 19:31:51 -0000 *************** extern tree chrec_fold_plus (tree, tree, *** 68,74 **** extern tree chrec_fold_minus (tree, tree, tree); extern tree chrec_fold_multiply (tree, tree, tree); extern tree chrec_convert (tree, tree); - extern tree count_ev_in_wider_type (tree, tree); extern tree chrec_type (tree); /* Operations. */ --- 68,73 ---- Index: tree-scalar-evolution.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-scalar-evolution.c,v retrieving revision 2.21 diff -c -3 -p -r2.21 tree-scalar-evolution.c *** tree-scalar-evolution.c 21 Apr 2005 08:48:53 -0000 2.21 --- tree-scalar-evolution.c 29 Apr 2005 19:31:52 -0000 *************** find_var_scev_info (tree var) *** 350,382 **** return &res->chrec; } - /* Tries to express CHREC in wider type TYPE. */ - - tree - count_ev_in_wider_type (tree type, tree chrec) - { - tree base, step; - struct loop *loop; - - if (!evolution_function_is_affine_p (chrec)) - return fold_convert (type, chrec); - - base = CHREC_LEFT (chrec); - step = CHREC_RIGHT (chrec); - loop = current_loops->parray[CHREC_VARIABLE (chrec)]; - - /* TODO -- if we knew the statement at that the conversion occurs, - we could pass it to can_count_iv_in_wider_type and get a better - result. */ - step = can_count_iv_in_wider_type (loop, type, base, step, NULL_TREE); - if (!step) - return fold_convert (type, chrec); - base = chrec_convert (type, base); - - return build_polynomial_chrec (CHREC_VARIABLE (chrec), - base, step); - } - /* Return true when CHREC contains symbolic names defined in LOOP_NB. */ --- 350,355 ---- -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21029