Advertisement

このページを編集する際は,編集に関する方針に従ってください.

概要

引数

実装

2959 /* Return a simplified tree node for the truth-negation of ARG.  This
2960    never alters ARG itself.  We assume that ARG is an operation that
2961    returns a truth value (0 or 1).
2962 
2963    FIXME: one would think we would fold the result, but it causes
2964    problems with the dominator optimizer.  */
2965 tree
2966 invert_truthvalue (tree arg)
2967 {
2968   tree type = TREE_TYPE (arg);
2969   enum tree_code code = TREE_CODE (arg);
2970 
2971   if (code == ERROR_MARK)
2972     return arg;
2973 
2974   /* If this is a comparison, we can simply invert it, except for
2975      floating-point non-equality comparisons, in which case we just
2976      enclose a TRUTH_NOT_EXPR around what we have.  */
2977 
2978   if (TREE_CODE_CLASS (code) == tcc_comparison)
2979     {
2980       tree op_type = TREE_TYPE (TREE_OPERAND (arg, 0));
2981       if (FLOAT_TYPE_P (op_type)
2982           && flag_trapping_math
2983           && code != ORDERED_EXPR && code != UNORDERED_EXPR
2984           && code != NE_EXPR && code != EQ_EXPR)
2985         return build1 (TRUTH_NOT_EXPR, type, arg);
2986       else
2987         {
2988           code = invert_tree_comparison (code,
2989                                          HONOR_NANS (TYPE_MODE (op_type)));
2990           if (code == ERROR_MARK)
2991             return build1 (TRUTH_NOT_EXPR, type, arg);
2992           else
2993             return build2 (code, type,
2994                            TREE_OPERAND (arg, 0), TREE_OPERAND (arg, 1));
2995         }
2996     }
2997 
2998   switch (code)
2999     {
3000     case INTEGER_CST:
3001       return constant_boolean_node (integer_zerop (arg), type);
3002 
3003     case TRUTH_AND_EXPR:
3004       return build2 (TRUTH_OR_EXPR, type,
3005                      invert_truthvalue (TREE_OPERAND (arg, 0)),
3006                      invert_truthvalue (TREE_OPERAND (arg, 1)));
3007 
3008     case TRUTH_OR_EXPR:
3009       return build2 (TRUTH_AND_EXPR, type,
3010                      invert_truthvalue (TREE_OPERAND (arg, 0)),
3011                      invert_truthvalue (TREE_OPERAND (arg, 1)));
3012 
3013     case TRUTH_XOR_EXPR:
3014       /* Here we can invert either operand.  We invert the first operand
3015          unless the second operand is a TRUTH_NOT_EXPR in which case our
3016          result is the XOR of the first operand with the inside of the
3017          negation of the second operand.  */
3018 
3019       if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
3020         return build2 (TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
3021                        TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
3022       else
3023         return build2 (TRUTH_XOR_EXPR, type,
3024                        invert_truthvalue (TREE_OPERAND (arg, 0)),
3025                        TREE_OPERAND (arg, 1));
3026 
3027     case TRUTH_ANDIF_EXPR:
3028       return build2 (TRUTH_ORIF_EXPR, type,
3029                      invert_truthvalue (TREE_OPERAND (arg, 0)),
3030                      invert_truthvalue (TREE_OPERAND (arg, 1)));
3031 
3032     case TRUTH_ORIF_EXPR:
3033       return build2 (TRUTH_ANDIF_EXPR, type,
3034                      invert_truthvalue (TREE_OPERAND (arg, 0)),
3035                      invert_truthvalue (TREE_OPERAND (arg, 1)));
3036 
3037     case TRUTH_NOT_EXPR:
3038       return TREE_OPERAND (arg, 0);
3039 
3040     case COND_EXPR:
3041       {
3042         tree arg1 = TREE_OPERAND (arg, 1);
3043         tree arg2 = TREE_OPERAND (arg, 2);
3044         /* A COND_EXPR may have a throw as one operand, which
3045            then has void type.  Just leave void operands
3046            as they are.  */
3047         return build3 (COND_EXPR, type, TREE_OPERAND (arg, 0),
3048                        VOID_TYPE_P (TREE_TYPE (arg1))
3049                        ? arg1 : invert_truthvalue (arg1),
3050                        VOID_TYPE_P (TREE_TYPE (arg2))
3051                        ? arg2 : invert_truthvalue (arg2));
3052       }
3053 
3054     case COMPOUND_EXPR:
3055       return build2 (COMPOUND_EXPR, type, TREE_OPERAND (arg, 0),
3056                      invert_truthvalue (TREE_OPERAND (arg, 1)));
3057 
3058     case NON_LVALUE_EXPR:
3059       return invert_truthvalue (TREE_OPERAND (arg, 0));
3060 
3061     case NOP_EXPR:
3062       if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
3063         break;
3064 
3065     case CONVERT_EXPR:
3066     case FLOAT_EXPR:
3067       return build1 (TREE_CODE (arg), type,
3068                      invert_truthvalue (TREE_OPERAND (arg, 0)));
3069 
3070     case BIT_AND_EXPR:
3071       if (!integer_onep (TREE_OPERAND (arg, 1)))
3072         break;
3073       return build2 (EQ_EXPR, type, arg,
3074                      fold_convert (type, integer_zero_node));
3075 
3076     case SAVE_EXPR:
3077       return build1 (TRUTH_NOT_EXPR, type, arg);
3078 
3079     case CLEANUP_POINT_EXPR:
3080       return build1 (CLEANUP_POINT_EXPR, type,
3081                      invert_truthvalue (TREE_OPERAND (arg, 0)));
3082 
3083     default:
3084       break;
3085     }
3086   gcc_assert (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE);
3087   return build1 (TRUTH_NOT_EXPR, type, arg);
3088 }



リンク元

特に記載のない限り、コミュニティのコンテンツはCC-BY-SAライセンスの下で利用可能です。