2011/5/26 Richard Guenther <richard.guent...@gmail.com>:
> On Thu, May 26, 2011 at 1:20 PM, Kai Tietz <ktiet...@googlemail.com> wrote:
>> 2011/5/26 Richard Guenther <richard.guent...@gmail.com>:
>>> On Thu, May 26, 2011 at 1:11 PM, Kai Tietz <ktiet...@googlemail.com> wrote:
>>>> 2011/5/26 Richard Guenther <richard.guent...@gmail.com>:
>>>>> On Thu, May 26, 2011 at 12:46 PM, Richard Guenther
>>>>> <richard.guent...@gmail.com> wrote:
>>>>>> On Thu, May 26, 2011 at 12:20 PM, Kai Tietz <kti...@redhat.com> wrote:
>>>>>>> Hello,
>>>>>>>
>>>>>>> this patch ensures that after gimplification also comparison 
>>>>>>> expressions using FE's boolean_type_node.  As we need to deal here with 
>>>>>>> C/C++'s (obj-c/c++ and java's), Ada's, and Fortran's specific boolean 
>>>>>>> types, this patch alters some checks in tree-cfg for Ada's sake, and we 
>>>>>>> need to deal in fold-const about type-conversion of comparisons special.
>>>>>>> Additionally it takes care that in forwprop pass we don't do type 
>>>>>>> hoising for boolean types.
>>>>>>>
>>>>>>> ChangeLog
>>>>>>>
>>>>>>> 2011-05-26  Kai Tietz
>>>>>>>
>>>>>>>          * gimplify.c (gimple_boolify): Boolify all comparison
>>>>>>>          expressions.
>>>>>>>          (gimplify_expr): Use 'useless_type_conversion_p' for comparing
>>>>>>>          org_type with boolean_type_node for TRUTH-expressions and 
>>>>>>> comparisons.
>>>>>>>          * fold-const.c (fold_unary_loc): Handle comparison conversions 
>>>>>>> with
>>>>>>>          boolean-type special.
>>>>>>>          * tree-cfg.c (verify_gimple_comparison): Adjust check for 
>>>>>>> boolean
>>>>>>>          or compatible types.
>>>>>>>          (verify_gimple_assign_unary): Likewise.
>>>>>>>          * tree-ssa-forwprop.c (forward_propagate_comparison): Handle
>>>>>>>          boolean case special.
>>>>>>>
>>>>>>> Tested on x86_64-pc-linux-gnu (multilib) with regression test for all 
>>>>>>> standard languages (C, C++, Obj-C, Fortran, Java) plus Obj-C++ and Ada. 
>>>>>>> Ok for apply?
>>>>>>
>>>>>> It obviously isn't ok to apply before a patch has gone in that will 
>>>>>> resolve
>>>>>> all of the FAILs you specify.  Comments on the patch:
>>>>>>
>>>>>> @@ -7281,9 +7284,28 @@ gimplify_expr (tree *expr_p, gimple_seq
>>>>>>                 plain wrong if bitfields are involved.  */
>>>>>>                {
>>>>>>                  tree type = TREE_TYPE (TREE_OPERAND (*expr_p, 1));
>>>>>> +                 tree org_type = TREE_TYPE (*expr_p);
>>>>>> +
>>>>>> +                 if (!useless_type_conversion_p (org_type, 
>>>>>> boolean_type_node))
>>>>>> +                   {
>>>>>> +                     TREE_TYPE (*expr_p) = boolean_type_node;
>>>>>> +                     *expr_p = fold_convert_loc (saved_location, 
>>>>>> org_type, *expr_p);
>>>>>> +                     ret = GS_OK;
>>>>>> +                     goto dont_recalculate;
>>>>>> +                   }
>>>>>>
>>>>>> The above should be only done for !AGGREGATE_TYPE_P.  Probably then
>>>>>> the strange dont_recalcuate goto can go away as well.
>>>>>>
>>>>>>                  if (!AGGREGATE_TYPE_P (type))
>>>>>> -                   goto expr_2;
>>>>>> +                   {
>>>>>> +                     enum gimplify_status r0, r1;
>>>>>> +
>>>>>> +                     r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), 
>>>>>> pre_p,
>>>>>> +                                         post_p, is_gimple_val, 
>>>>>> fb_rvalue);
>>>>>> +                     r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), 
>>>>>> pre_p,
>>>>>> +                                         post_p, is_gimple_val, 
>>>>>> fb_rvalue);
>>>>>> +
>>>>>> +                     ret = MIN (r0, r1);
>>>>>> +                   }
>>>>>> +
>>>>>>
>>>>>> why change this?
>>>>>>
>>>>>> @@ -7641,6 +7641,12 @@ fold_unary_loc (location_t loc, enum tre
>>>>>>        }
>>>>>>       else if (COMPARISON_CLASS_P (arg0))
>>>>>>        {
>>>>>> +         /* Don't optimize type change, if op0 is of kind 
>>>>>> boolean_type_node.
>>>>>> +            Otherwise this will lead to race-condition on gimplification
>>>>>> +            trying to boolify comparison expression.  */
>>>>>> +         if (TREE_TYPE (op0) == boolean_type_node)
>>>>>> +           return NULL_TREE;
>>>>>> +
>>>>>>          if (TREE_CODE (type) == BOOLEAN_TYPE)
>>>>>>            {
>>>>>>              arg0 = copy_node (arg0);
>>>>>>
>>>>>> The code leading here looks quite strange to me ...
>>>>>>
>>>>>> tree
>>>>>> fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
>>>>>> {
>>>>>> ...
>>>>>>  if (TREE_CODE_CLASS (code) == tcc_unary)
>>>>>>    {
>>>>>> ...
>>>>>>      else if (COMPARISON_CLASS_P (arg0))
>>>>>>        {
>>>>>>          if (TREE_CODE (type) == BOOLEAN_TYPE)
>>>>>>            {
>>>>>>              arg0 = copy_node (arg0);
>>>>>>              TREE_TYPE (arg0) = type;
>>>>>>              return arg0;
>>>>>>            }
>>>>>>          else if (TREE_CODE (type) != INTEGER_TYPE)
>>>>>>            return fold_build3_loc (loc, COND_EXPR, type, arg0,
>>>>>>                                fold_build1_loc (loc, code, type,
>>>>>>                                             integer_one_node),
>>>>>>                                fold_build1_loc (loc, code, type,
>>>>>>                                             integer_zero_node));
>>>>>>        }
>>>>>>
>>>>>> so, for any tcc_unary, like NEGATE_EXPR, with BOOLEAN_TYPE,
>>>>>> return arg0 ... sure.  Same for the 2nd case.  ~ (a == b) isn't
>>>>>> the same as a == b ? ~1 : ~0.  I _suppose_ those cases were
>>>>>> ment for CONVERT_EXPR_CODE_P (code) instead of all of tcc_unary,
>>>>>> in which case they should be dropped or moved below where we
>>>>>> handle conversions explicitly.
>>>>>>
>>>>>> That said - does anyone remember anything about that above code?
>>>>>> Trying to do some svn blame history tracking now ...
>>>>>
>>>>> Oh, the patch continues...
>>>>>
>>>>> @@ -3208,7 +3208,10 @@ verify_gimple_comparison (tree type, tre
>>>>>        && (!POINTER_TYPE_P (op0_type)
>>>>>           || !POINTER_TYPE_P (op1_type)
>>>>>           || TYPE_MODE (op0_type) != TYPE_MODE (op1_type)))
>>>>> -      || !INTEGRAL_TYPE_P (type))
>>>>> +      || !(TREE_CODE (type) == BOOLEAN_TYPE
>>>>> +          || (TREE_TYPE (type) && TREE_CODE (type) == INTEGER_TYPE
>>>>> +              && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE)
>>>>> +          || (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1)))
>>>>>     {
>>>>>
>>>>> why that strange TREE_TYPE (TREE_TYPE ())) thing again?  Drop
>>>>> that.
>>>>>
>>>>> @@ -3352,6 +3355,8 @@ verify_gimple_assign_unary (gimple stmt)
>>>>>     case TRUTH_NOT_EXPR:
>>>>>       /* We require two-valued operand types.  */
>>>>>       if (!(TREE_CODE (rhs1_type) == BOOLEAN_TYPE
>>>>> +           || (TREE_TYPE (rhs1_type) && TREE_CODE (rhs1_type) == 
>>>>> INTEGER_TYPE
>>>>> +               && TREE_CODE (TREE_TYPE (rhs1_type)) == BOOLEAN_TYPE)
>>>>>            || (INTEGRAL_TYPE_P (rhs1_type)
>>>>>                && TYPE_PRECISION (rhs1_type) == 1)))
>>>>>         {
>>>>>
>>>>> likewise.
>>>>
>>>> Well, those checks are necessary for Ada and its crippled
>>>> boolean_type_node and computed boolean-based integer construct.  Ada
>>>> derives here the boolean-type to an integer with range 0..1 and the
>>>> only way to find out that it is in fact such a beast is by looking
>>>> into TREE_TYPE of type.  See here Ada's code for getting base-type
>>>> information.
>>>> As such things are treated as compatible they can appear for TRUTH_NOT
>>>> expressions and comparisons.
>>>
>>> No they can't as we boolify them.
>>>
>>> Richard.
>>
>> Well, they do.  Test can prove this by running fortran's dg tests.
>>
>> The logic we do in gimplification is:
>>
>> 1) save original type of expression.
>> 2) set expression's type to boolean_type_node.
>> 3) if conversion from boolean_type_node to saved type isn't useless
>> (and here we have the issue about Fortran's different booleans with
>> different modes, which make those kinds not useless) then cast
>> expression's result to original type and retry gimplification.
>> 4) Otherwise gimplify operands and continue.
>
> You don't make sense.  Btw,
>
>>>>> +                 if (!useless_type_conversion_p (org_type, 
>>>>> boolean_type_node))
>>>>> +                   {
>>>>> +                     TREE_TYPE (*expr_p) = boolean_type_node;
>>>>> +                     *expr_p = fold_convert_loc (saved_location, 
>>>>> org_type,
>
> is bogus it should be
>
> TREE_TYPE (*expr_p) = boolean_type_node;
> if (!useless_type_conversion_p (org_type, boolean_type_node))
>  {
>    *expr_p = fold_convert_loc (saved_location, org_type,

Well, I spared here the type conversion to boolean_type_node for
useless conversion, but it doesn't change anything about the endless
recursion here. As long as fold_convert_loc modifies *expr_p's type
back to original type it will loop for ever for those cases I
described above.
Please don't forget that boolean_type_node is FE type here and not the
later 1-bit BOOL_SIZE type set in free_lang_data.

Kai

Reply via email to