GCC Wikia
Advertisement

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

概要[]

引数[]

実装[]

 6562 /* Fold a unary expression of code CODE and type TYPE with operand
 6563    OP0.  Return the folded expression if folding is successful.
 6564    Otherwise, return NULL_TREE.  */
6565 
6566 tree
6567 fold_unary (enum tree_code code, tree type, tree op0)
6568 {
6569   tree tem;
6570   tree arg0;
6571   enum tree_code_class kind = TREE_CODE_CLASS (code);
6572 
6573   gcc_assert (IS_EXPR_CODE_CLASS (kind)
6574               && TREE_CODE_LENGTH (code) == 1);
6575 
6576   arg0 = op0;
6577   if (arg0)
6578     {
6579       if (code == [[NOP_EXPR>enum tree_code]] || code == [[CONVERT_EXPR>enum tree_code]]
6580           || code == [[FLOAT_EXPR>enum tree_code]] || code == [[ABS_EXPR>enum tree_code]])
6581         {
 6582           /* Don't use STRIP_NOPS, because signedness of argument type
 6583              matters.  */
6584           STRIP_SIGN_NOPS (arg0);
6585         }
6586       else
6587         {
 6588           /* Strip any conversions that don't change the mode.  This
 6589              is safe for every expression, except for a comparison
 6590              expression because its signedness is derived from its
 6591              operands.
 6592 
 6593              Note that this is done as an internal manipulation within
 6594              the constant folder, in order to find the simplest
 6595              representation of the arguments so that their form can be
 6596              studied.  In any cases, the appropriate type conversions
 6597              should be put back in the tree that will get out of the
 6598              constant folder.  */
6599           STRIP_NOPS (arg0);
6600         }
6601     }
6602 
6603   if (TREE_CODE_CLASS (code) == [[tcc_unary>enum tree_code_class]])
6604     {
6605       if (TREE_CODE (arg0) == [[COMPOUND_EXPR>enum tree_code]])
6606         return build2 ([[COMPOUND_EXPR>enum tree_code]], type, TREE_OPERAND (arg0, 0),
6607                        fold_build1 (code, type, TREE_OPERAND (arg0, 1)));
6608       else if (TREE_CODE (arg0) == [[COND_EXPR>enum tree_code]])
6609         {
6610           tree arg01 = TREE_OPERAND (arg0, 1);
6611           tree arg02 = TREE_OPERAND (arg0, 2);
6612           if (! VOID_TYPE_P (TREE_TYPE (arg01)))
6613             arg01 = fold_build1 (code, type, arg01);
6614           if (! VOID_TYPE_P (TREE_TYPE (arg02)))
6615             arg02 = fold_build1 (code, type, arg02);
6616           tem = fold_build3 ([[COND_EXPR>enum tree_code]], type, TREE_OPERAND (arg0, 0),
6617                              arg01, arg02);
6618 
 6619           /* If this was a conversion, and all we did was to move into
 6620              inside the COND_EXPR, bring it back out.  But leave it if
 6621              it is a conversion from integer to integer and the
 6622              result precision is no wider than a word since such a
 6623              conversion is cheap and may be optimized away by combine,
 6624              while it couldn't if it were outside the COND_EXPR.  Then return
 6625              so we don't get into an infinite recursion loop taking the
 6626              conversion out and then back in.  */
6627 
6628           if ((code == [[NOP_EXPR>enum tree_code]] || code == [[CONVERT_EXPR>enum tree_code]]
6629                || code == [[NON_LVALUE_EXPR>enum tree_code]])
6630               && TREE_CODE (tem) == [[COND_EXPR>enum tree_code]]
6631               && TREE_CODE (TREE_OPERAND (tem, 1)) == code
6632               && TREE_CODE (TREE_OPERAND (tem, 2)) == code
6633               && ! VOID_TYPE_P (TREE_OPERAND (tem, 1))
6634               && ! VOID_TYPE_P (TREE_OPERAND (tem, 2))
6635               && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))
6636                   == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 2), 0)))
6637               && (! (INTEGRAL_TYPE_P (TREE_TYPE (tem))
6638                      && (INTEGRAL_TYPE_P
6639                          (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (tem, 1), 0))))
6640                      && TYPE_PRECISION (TREE_TYPE (tem)) <= BITS_PER_WORD)
6641                   || flag_syntax_only))
6642             tem = build1 (code, type,
6643                           build3 (COND_EXPR,
6644                                   TREE_TYPE (TREE_OPERAND
6645                                              (TREE_OPERAND (tem, 1), 0)),
6646                                   TREE_OPERAND (tem, 0),
6647                                   TREE_OPERAND (TREE_OPERAND (tem, 1), 0),
6648                                   TREE_OPERAND (TREE_OPERAND (tem, 2), 0)));
6649           return tem;
6650         }
6651       else if (COMPARISON_CLASS_P (arg0))
6652         {
6653           if (TREE_CODE (type) == BOOLEAN_TYPE)
6654             {
6655               arg0 = copy_node (arg0);
6656               TREE_TYPE (arg0) = type;
6657               return arg0;
6658             }
6659           else if (TREE_CODE (type) != INTEGER_TYPE)
6660             return fold_build3 (COND_EXPR, type, arg0,
6661                                 fold_build1 (code, type,
6662                                              integer_one_node),
6663                                 fold_build1 (code, type,
6664                                              integer_zero_node));
6665         }
6666    }
6667 
6668   switch (code)
6669     {
6670     case NOP_EXPR:
6671     case FLOAT_EXPR:
6672     case CONVERT_EXPR:
6673     case FIX_TRUNC_EXPR:
6674     case FIX_CEIL_EXPR:
6675     case FIX_FLOOR_EXPR:
6676     case FIX_ROUND_EXPR:
6677       if (TREE_TYPE (op0) == type)
6678         return op0;
6679 
6680       /* Handle cases of two conversions in a row.  */
6681       if (TREE_CODE (op0) == NOP_EXPR
6682           || TREE_CODE (op0) == CONVERT_EXPR)
6683         {
6684           tree inside_type = TREE_TYPE (TREE_OPERAND (op0, 0));
6685           tree inter_type = TREE_TYPE (op0);
6686           int inside_int = INTEGRAL_TYPE_P (inside_type);
6687           int inside_ptr = POINTER_TYPE_P (inside_type);
6688           int inside_float = FLOAT_TYPE_P (inside_type);
6689           int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
6690           unsigned int inside_prec = TYPE_PRECISION (inside_type);
6691           int inside_unsignedp = TYPE_UNSIGNED (inside_type);
6692           int inter_int = INTEGRAL_TYPE_P (inter_type);
6693           int inter_ptr = POINTER_TYPE_P (inter_type);
6694           int inter_float = FLOAT_TYPE_P (inter_type);
6695           int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
6696           unsigned int inter_prec = TYPE_PRECISION (inter_type);
6697           int inter_unsignedp = TYPE_UNSIGNED (inter_type);
6698           int final_int = INTEGRAL_TYPE_P (type);
6699           int final_ptr = POINTER_TYPE_P (type);
6700           int final_float = FLOAT_TYPE_P (type);
6701           int final_vec = TREE_CODE (type) == VECTOR_TYPE;
6702           unsigned int final_prec = TYPE_PRECISION (type);
6703           int final_unsignedp = TYPE_UNSIGNED (type);
6704 
6705           /* In addition to the cases of two conversions in a row
6706              handled below, if we are converting something to its own
6707              type via an object of identical or wider precision, neither
6708              conversion is needed.  */
6709           if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (type)
6710               && ((inter_int && final_int) || (inter_float && final_float))
6711               && inter_prec >= final_prec)
6712             return fold_build1 (code, type, TREE_OPERAND (op0, 0));
6713 
6714           /* Likewise, if the intermediate and final types are either both
6715              float or both integer, we don't need the middle conversion if
6716              it is wider than the final type and doesn't change the signedness
6717              (for integers).  Avoid this if the final type is a pointer
6718              since then we sometimes need the inner conversion.  Likewise if
6719              the outer has a precision not equal to the size of its mode.  */
6720           if ((((inter_int || inter_ptr) && (inside_int || inside_ptr))
6721                || (inter_float && inside_float)
6722                || (inter_vec && inside_vec))
6723               && inter_prec >= inside_prec
6724               && (inter_float || inter_vec
6725                   || inter_unsignedp == inside_unsignedp)
6726               && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
6727                     && TYPE_MODE (type) == TYPE_MODE (inter_type))
6728               && ! final_ptr
6729               && (! final_vec || inter_prec == inside_prec))
6730             return fold_build1 (code, type, TREE_OPERAND (op0, 0));
6731 
6732           /* If we have a sign-extension of a zero-extended value, we can
6733              replace that by a single zero-extension.  */
6734           if (inside_int && inter_int && final_int
6735               && inside_prec < inter_prec && inter_prec < final_prec
6736               && inside_unsignedp && !inter_unsignedp)
6737             return fold_build1 (code, type, TREE_OPERAND (op0, 0));
6738 
6739           /* Two conversions in a row are not needed unless:
6740              - some conversion is floating-point (overstrict for now), or
6741              - some conversion is a vector (overstrict for now), or
6742              - the intermediate type is narrower than both initial and
6743                final, or
6744              - the intermediate type and innermost type differ in signedness,
6745                and the outermost type is wider than the intermediate, or
6746              - the initial type is a pointer type and the precisions of the
6747                intermediate and final types differ, or
6748              - the final type is a pointer type and the precisions of the
6749                initial and intermediate types differ.  */
6750           if (! inside_float && ! inter_float && ! final_float
6751               && ! inside_vec && ! inter_vec && ! final_vec
6752               && (inter_prec > inside_prec || inter_prec > final_prec)
6753               && ! (inside_int && inter_int
6754                     && inter_unsignedp != inside_unsignedp
6755                     && inter_prec < final_prec)
6756               && ((inter_unsignedp && inter_prec > inside_prec)
6757                   == (final_unsignedp && final_prec > inter_prec))
6758               && ! (inside_ptr && inter_prec != final_prec)
6759               && ! (final_ptr && inside_prec != inter_prec)
6760               && ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (type))
6761                     && TYPE_MODE (type) == TYPE_MODE (inter_type))
6762               && ! final_ptr)
6763             return fold_build1 (code, type, TREE_OPERAND (op0, 0));
6764         }
6765 
6766       /* Handle (T *)&A.B.C for A being of type T and B and C
6767          living at offset zero.  This occurs frequently in
6768          C++ upcasting and then accessing the base.  */
6769       if (TREE_CODE (op0) == ADDR_EXPR
6770           && POINTER_TYPE_P (type)
6771           && handled_component_p (TREE_OPERAND (op0, 0)))
6772         {
6773           HOST_WIDE_INT bitsize, bitpos;
6774           tree offset;
6775           enum machine_mode mode;
6776           int unsignedp, volatilep;
6777           tree base = TREE_OPERAND (op0, 0);
6778           base = get_inner_reference (base, &bitsize, &bitpos, &offset,
6779                                       &mode, &unsignedp, &volatilep, false);
6780           /* If the reference was to a (constant) zero offset, we can use
6781              the address of the base if it has the same base type
6782              as the result type.  */
6783           if (! offset && bitpos == 0
6784               && TYPE_MAIN_VARIANT (TREE_TYPE (type))
6785                   == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
6786             return fold_convert (type, build_fold_addr_expr (base));
6787         }
6788 
6789       if (TREE_CODE (op0) == MODIFY_EXPR
6790           && TREE_CONSTANT (TREE_OPERAND (op0, 1))
6791           /* Detect assigning a bitfield.  */
6792           && !(TREE_CODE (TREE_OPERAND (op0, 0)) == COMPONENT_REF
6793                && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (op0, 0), 1))))
6794         {
6795           /* Don't leave an assignment inside a conversion
6796              unless assigning a bitfield.  */
6797           tem = fold_build1 (code, type, TREE_OPERAND (op0, 1));
6798           /* First do the assignment, then return converted constant.  */
6799           tem = build2 (COMPOUND_EXPR, TREE_TYPE (tem), op0, tem);
6800           TREE_NO_WARNING (tem) = 1;
6801           TREE_USED (tem) = 1;
6802           return tem;
6803         }
6804 
6805       /* Convert (T)(x & c) into (T)x & (T)c, if c is an integer
6806          constants (if x has signed type, the sign bit cannot be set
6807          in c).  This folds extension into the BIT_AND_EXPR.  */
6808       if (INTEGRAL_TYPE_P (type)
6809           && TREE_CODE (type) != BOOLEAN_TYPE
6810           && TREE_CODE (op0) == BIT_AND_EXPR
6811           && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
6812         {
6813           tree and = op0;
6814           tree and0 = TREE_OPERAND (and, 0), and1 = TREE_OPERAND (and, 1);
6815           int change = 0;
6816 
6817           if (TYPE_UNSIGNED (TREE_TYPE (and))
6818               || (TYPE_PRECISION (type)
6819                   <= TYPE_PRECISION (TREE_TYPE (and))))
6820             change = 1;
6821           else if (TYPE_PRECISION (TREE_TYPE (and1))
6822                    <= HOST_BITS_PER_WIDE_INT
6823                    && host_integerp (and1, 1))
6824             {
6825               unsigned HOST_WIDE_INT cst;
6826 
6827               cst = tree_low_cst (and1, 1);
6828               cst &= (HOST_WIDE_INT) -1
6829                      << (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
6830               change = (cst == 0);
6831 #ifdef LOAD_EXTEND_OP
6832               if (change
6833                   && !flag_syntax_only
6834                   && (LOAD_EXTEND_OP (TYPE_MODE (TREE_TYPE (and0)))
6835                       == ZERO_EXTEND))
6836                 {
6837                   tree uns = lang_hooks.types.unsigned_type (TREE_TYPE (and0));
6838                   and0 = fold_convert (uns, and0);
6839                   and1 = fold_convert (uns, and1);
6840                 }
6841 #endif
6842             }
6843           if (change)
6844             {
6845               tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
6846                                         TREE_INT_CST_HIGH (and1));
6847               tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
6848                                     TREE_CONSTANT_OVERFLOW (and1));
6849               return fold_build2 (BIT_AND_EXPR, type,
6850                                   fold_convert (type, and0), tem);
6851             }
6852         }
6853 
6854       /* Convert (T1)((T2)X op Y) into (T1)X op Y, for pointer types T1 and
6855          T2 being pointers to types of the same size.  */
6856       if (POINTER_TYPE_P (type)
6857           && BINARY_CLASS_P (arg0)
6858           && TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
6859           && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (arg0, 0))))
6860         {
6861           tree arg00 = TREE_OPERAND (arg0, 0);
6862           tree t0 = type;
6863           tree t1 = TREE_TYPE (arg00);
6864           tree tt0 = TREE_TYPE (t0);
6865           tree tt1 = TREE_TYPE (t1);
6866           tree s0 = TYPE_SIZE (tt0);
6867           tree s1 = TYPE_SIZE (tt1);
6868 
6869           if (s0 && s1 && operand_equal_p (s0, s1, OEP_ONLY_CONST))
6870             return build2 (TREE_CODE (arg0), t0, fold_convert (t0, arg00),
6871                            TREE_OPERAND (arg0, 1));
6872         }
6873 
6874       tem = fold_convert_const (code, type, arg0);
6875       return tem ? tem : NULL_TREE;
6876 
6877     case VIEW_CONVERT_EXPR:
6878       if (TREE_CODE (op0) == VIEW_CONVERT_EXPR)
6879         return build1 (VIEW_CONVERT_EXPR, type, TREE_OPERAND (op0, 0));
6880       return NULL_TREE;
6881 
6882     case NEGATE_EXPR:
6883       if (negate_expr_p (arg0))
6884         return fold_convert (type, negate_expr (arg0));
6885       /* Convert - (~A) to A + 1.  */
6886       if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == BIT_NOT_EXPR)
6887         return fold_build2 (PLUS_EXPR, type, TREE_OPERAND (arg0, 0),
6888                             build_int_cst (type, 1));
6889       return NULL_TREE;
6890 
6891     case ABS_EXPR:
6892       if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
6893         return fold_abs_const (arg0, type);
6894       else if (TREE_CODE (arg0) == NEGATE_EXPR)
6895         return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0));
6896       /* Convert fabs((double)float) into (double)fabsf(float).  */
6897       else if (TREE_CODE (arg0) == NOP_EXPR
6898                && TREE_CODE (type) == REAL_TYPE)
6899         {
6900           tree targ0 = strip_float_extensions (arg0);
6901           if (targ0 != arg0)
6902             return fold_convert (type, fold_build1 (ABS_EXPR,
6903                                                     TREE_TYPE (targ0),
6904                                                     targ0));
6905         }
6906       /* ABS_EXPR<ABS_EXPR<x>> = ABS_EXPR<x> even if flag_wrapv is on.  */
6907       else if (tree_expr_nonnegative_p (arg0) || TREE_CODE (arg0) == ABS_EXPR)
6908         return arg0;
6909 
6910       /* Strip sign ops from argument.  */
6911       if (TREE_CODE (type) == REAL_TYPE)
6912         {
6913           tem = fold_strip_sign_ops (arg0);
6914           if (tem)
6915             return fold_build1 (ABS_EXPR, type, fold_convert (type, tem));
6916         }
6917       return NULL_TREE;
6918 
6919     case CONJ_EXPR:
6920       if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
6921         return fold_convert (type, arg0);
6922       else if (TREE_CODE (arg0) == COMPLEX_EXPR)
6923         return build2 (COMPLEX_EXPR, type,
6924                        TREE_OPERAND (arg0, 0),
6925                        negate_expr (TREE_OPERAND (arg0, 1)));
6926       else if (TREE_CODE (arg0) == COMPLEX_CST)
6927         return build_complex (type, TREE_REALPART (arg0),
6928                               negate_expr (TREE_IMAGPART (arg0)));
6929       else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
6930         return fold_build2 (TREE_CODE (arg0), type,
6931                             fold_build1 (CONJ_EXPR, type,
6932                                          TREE_OPERAND (arg0, 0)),
6933                             fold_build1 (CONJ_EXPR, type,
6934                                          TREE_OPERAND (arg0, 1)));
6935       else if (TREE_CODE (arg0) == CONJ_EXPR)
6936         return TREE_OPERAND (arg0, 0);
6937       return NULL_TREE;
6938 
6939     case BIT_NOT_EXPR:
6940       if (TREE_CODE (arg0) == INTEGER_CST)
6941         return fold_not_const (arg0, type);
6942       else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
6943         return TREE_OPERAND (arg0, 0);
6944       /* Convert ~ (-A) to A - 1.  */
6945       else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
6946         return fold_build2 (MINUS_EXPR, type, TREE_OPERAND (arg0, 0),
6947                             build_int_cst (type, 1));
6948       /* Convert ~ (A - 1) or ~ (A + -1) to -A.  */
6949       else if (INTEGRAL_TYPE_P (type)
6950                && ((TREE_CODE (arg0) == MINUS_EXPR
6951                     && integer_onep (TREE_OPERAND (arg0, 1)))
6952                    || (TREE_CODE (arg0) == PLUS_EXPR
6953                        && integer_all_onesp (TREE_OPERAND (arg0, 1)))))
6954         return fold_build1 (NEGATE_EXPR, type, TREE_OPERAND (arg0, 0));
6955       /* Convert ~(X ^ Y) to ~X ^ Y or X ^ ~Y if ~X or ~Y simplify.  */
6956       else if (TREE_CODE (arg0) == BIT_XOR_EXPR
6957                && (tem = fold_unary (BIT_NOT_EXPR, type,
6958                                      fold_convert (type,
6959                                                    TREE_OPERAND (arg0, 0)))))
6960         return fold_build2 (BIT_XOR_EXPR, type, tem,
6961                             fold_convert (type, TREE_OPERAND (arg0, 1)));
6962       else if (TREE_CODE (arg0) == BIT_XOR_EXPR
6963                && (tem = fold_unary (BIT_NOT_EXPR, type,
6964                                      fold_convert (type,
6965                                                    TREE_OPERAND (arg0, 1)))))
6966         return fold_build2 (BIT_XOR_EXPR, type,
6967                             fold_convert (type, TREE_OPERAND (arg0, 0)), tem);
6968 
6969       return NULL_TREE;
6970 
6971     case TRUTH_NOT_EXPR:
6972       /* The argument to invert_truthvalue must have Boolean type.  */
6973       if (TREE_CODE (TREE_TYPE (arg0)) != BOOLEAN_TYPE)
6974           arg0 = fold_convert (boolean_type_node, arg0);
6975 
6976       /* Note that the operand of this must be an int
6977          and its values must be 0 or 1.
6978          ("true" is a fixed value perhaps depending on the language,
6979          but we don't handle values other than 1 correctly yet.)  */
6980       tem = invert_truthvalue (arg0);
6981       /* Avoid infinite recursion.  */
6982       if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
6983         return NULL_TREE;
6984       return fold_convert (type, tem);
6985 
6986     case REALPART_EXPR:
6987       if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
6988         return NULL_TREE;
6989       else if (TREE_CODE (arg0) == COMPLEX_EXPR)
6990         return omit_one_operand (type, TREE_OPERAND (arg0, 0),
6991                                  TREE_OPERAND (arg0, 1));
6992       else if (TREE_CODE (arg0) == COMPLEX_CST)
6993         return TREE_REALPART (arg0);
6994       else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
6995         return fold_build2 (TREE_CODE (arg0), type,
6996                             fold_build1 (REALPART_EXPR, type,
6997                                          TREE_OPERAND (arg0, 0)),
6998                             fold_build1 (REALPART_EXPR, type,
6999                                          TREE_OPERAND (arg0, 1)));
7000       return NULL_TREE;
7001 
7002     case IMAGPART_EXPR:
7003       if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
7004         return fold_convert (type, integer_zero_node);
7005       else if (TREE_CODE (arg0) == COMPLEX_EXPR)
7006         return omit_one_operand (type, TREE_OPERAND (arg0, 1),
7007                                  TREE_OPERAND (arg0, 0));
7008       else if (TREE_CODE (arg0) == COMPLEX_CST)
7009         return TREE_IMAGPART (arg0);
7010       else if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
7011         return fold_build2 (TREE_CODE (arg0), type,
7012                             fold_build1 (IMAGPART_EXPR, type,
7013                                          TREE_OPERAND (arg0, 0)),
7014                             fold_build1 (IMAGPART_EXPR, type,
7015                                          TREE_OPERAND (arg0, 1)));
7016       return NULL_TREE;
7017 
7018     default:
7019       return NULL_TREE;
7020     } /* switch (code) */
7021 }


リンク元

Advertisement