[Gfortran, Patch] PR12456 - Optimize single character.
Feng Wang
wf_cs@yahoo.com
Fri Jan 6 10:00:00 GMT 2006
--- Andrew Pinski <pinskia@physics.uc.edu> wrote:
>
> On Jan 3, 2006, at 11:40 PM, Feng Wang wrote:
>
> > Index: trans-expr.c
> > ===================================================================
> >
> > + /* Deal with single character specially. */
> > + if (sc1 != NULL_TREE && sc2 != NULL_TREE)
> > + {
> > + lse.expr = build2 (MINUS_EXPR, gfc_get_int_type (4), sc1, sc2);
> > + }
>
> This is wrong with respect with types.
> You want to do something like:
> lse.expr = fold_convert (gfc_get_int_type (4),
> fold_build2 (MINUS_EXPR, gfc_character1_type_node,
> sc1, sc2));
>
> This will get the types correctly but this does the subtraction in the
> character
> type which is unsigned. Hmm, Maybe it should look like this changing
> the type of
> the characters to signed integers and then doing the subtraction in
> that type:
> {
> tree type = gfc_get_int_type (4)
> sc1 = fold_convert (type, sc1);
> sc2 = fold_convert (type, sc2);
>
> lse.expr = fold_build2 (MINUS_EXPR, type, sc1, sc2);
> }
Yes, you are right. The type of character is unsigned char. We should first
convert to singned integer.
Paul said the use of gfc_get_int_type (4) is wrong. I agree. We should avoid
using anything "machine" dependent when dealing with language layer items. What
about gfc_get_int_type (gfc_default_integer_kind)? Paul, could you explain
more?
>
> > @@ -2545,6 +2570,22 @@ gfc_conv_string_parameter (gfc_se * se)
> > && TREE_CODE (TREE_TYPE (se->string_length)) == INTEGER_TYPE);
> > }
> >
> > +/* If a string's length is one, we convert it to a single character.
> > */
> > +
> > +tree
> > +gfc_to_single_character (tree str, tree len)
> > +{
> > + gcc_assert (POINTER_TYPE_P (TREE_TYPE (str)));
> > +
> > + if (INTEGER_CST_P (len) && TREE_INT_CST_LOW (len) == 1
> > + && TREE_INT_CST_HIGH (len) == 0)
> > + {
> > + str = build1 (NOP_EXPR, pchar_type_node, str);
>
> Since we know that this is a pointer already, can you use
> "fold_convert (pchar_type_node, str);" instead of "build1 (NOP_EXPR"?
> This will remove an extra NOP_EXPR if we don't need it and
> also try to fold it if we can.
OK.
>
> > Index: trans-intrinsic.c
> > ===================================================================
> > --- trans-intrinsic.c (revision 109308)
> > +++ trans-intrinsic.c (working copy)
> > @@ -2267,10 +2267,27 @@ gfc_conv_intrinsic_strcmp (gfc_se * se,
> > {
> ....
> > + if (arg1 != NULL_TREE && arg2 != NULL_TREE)
> > + {
> > + se->expr = build2 (MINUS_EXPR, gfc_get_int_type (4), arg1,
> > arg2);
> > + }
> > + else
> > + {
> > + /* Build a call for the comparison. */
> > + se->expr = build_function_call_expr
> > (gfor_fndecl_compare_string, args);
> > + }
> >
> > type = gfc_typenode_for_spec (&expr->ts);
> > se->expr = build2 (op, type, se->expr,
> The same issue as gfc_conv_expr_op applies here also.
>
> Everything else looks good. Can you retest with my suggestions and
> repost
> it?
>
> I should note for some cleanup; it would be better if there is a
> function
> which takes the common parts of gfc_conv_intrinsic_strcmp and
> gfc_conv_expr_op
> since they do similar things. But that is for a different time.
>
I will try.
Best Regards,
Feng Wang
--
Creative Compiler Research Group,
National University of Defense Technology, China.
___________________________________________________________
ÃÃ
Ȣ1GÃâ·ÃÃÃÃä°Ã·Ã°Ã·Ãì»øÃÃ
http://cn.mail.yahoo.com
More information about the Gcc-patches
mailing list