このページを編集する際は,編集に関する方針に従ってください.[]
概要[]
引数[]
- enum tree_code code
- tree type
- tree op0
実装[]
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 }