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.

> Regards,
> Kai
>

Reply via email to