From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29295 invoked by alias); 9 Dec 2016 13:25:13 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 29269 invoked by uid 89); 9 Dec 2016 13:25:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Dec 2016 13:25:05 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 59CB1707; Fri, 9 Dec 2016 05:25:04 -0800 (PST) Received: from localhost (e105548-lin.manchester.arm.com [10.45.32.67]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0396E3F477 for ; Fri, 9 Dec 2016 05:25:03 -0800 (PST) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [48/67] Make subroutines of num_sign_bit_copies operate on scalar_int_mode References: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> Date: Fri, 09 Dec 2016 13:25:00 -0000 In-Reply-To: <87h96dp8u6.fsf@e105548-lin.cambridge.arm.com> (Richard Sandiford's message of "Fri, 09 Dec 2016 12:48:01 +0000") Message-ID: <87pol1grpt.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2016-12/txt/msg00822.txt.bz2 Similarly to the nonzero_bits patch, this one moves the mode class check and VOIDmode handling from num_sign_bit_copies1 to num_sign_bit_copies itself, then changes the subroutines to operate on scalar_int_modes. gcc/ 2016-11-24 Richard Sandiford Alan Hayward David Sherwood * rtlanal.c (num_sign_bit_copies): Handle VOIDmode here rather than in subroutines. Return 1 for non-integer modes. (cached_num_sign_bit_copies): Change the type of the mode parameter to scalar_int_mode. (num_sign_bit_copies1): Likewise. Remove early exit for other mode classes. Handle CONST_INT_P first and then check whether X also has a scalar integer mode. Check the same thing for inner registers of a SUBREG and for values that are being extended or truncated. diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 84e19e4..b70f6ce 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -49,11 +49,12 @@ static unsigned HOST_WIDE_INT cached_nonzero_bits (const_rtx, scalar_int_mode, static unsigned HOST_WIDE_INT nonzero_bits1 (const_rtx, scalar_int_mode, const_rtx, machine_mode, unsigned HOST_WIDE_INT); -static unsigned int cached_num_sign_bit_copies (const_rtx, machine_mode, const_rtx, - machine_mode, +static unsigned int cached_num_sign_bit_copies (const_rtx, scalar_int_mode, + const_rtx, machine_mode, unsigned int); -static unsigned int num_sign_bit_copies1 (const_rtx, machine_mode, const_rtx, - machine_mode, unsigned int); +static unsigned int num_sign_bit_copies1 (const_rtx, scalar_int_mode, + const_rtx, machine_mode, + unsigned int); rtx_subrtx_bound_info rtx_all_subrtx_bounds[NUM_RTX_CODE]; rtx_subrtx_bound_info rtx_nonconst_subrtx_bounds[NUM_RTX_CODE]; @@ -4208,7 +4209,12 @@ nonzero_bits (const_rtx x, machine_mode mode) unsigned int num_sign_bit_copies (const_rtx x, machine_mode mode) { - return cached_num_sign_bit_copies (x, mode, NULL_RTX, VOIDmode, 0); + if (mode == VOIDmode) + mode = GET_MODE (x); + scalar_int_mode int_mode; + if (!is_a (mode, &int_mode)) + return 1; + return cached_num_sign_bit_copies (x, int_mode, NULL_RTX, VOIDmode, 0); } /* Return true if nonzero_bits1 might recurse into both operands @@ -4775,8 +4781,8 @@ num_sign_bit_copies_binary_arith_p (const_rtx x) first or the second level. */ static unsigned int -cached_num_sign_bit_copies (const_rtx x, machine_mode mode, const_rtx known_x, - machine_mode known_mode, +cached_num_sign_bit_copies (const_rtx x, scalar_int_mode mode, + const_rtx known_x, machine_mode known_mode, unsigned int known_ret) { if (x == known_x && mode == known_mode) @@ -4821,44 +4827,48 @@ cached_num_sign_bit_copies (const_rtx x, machine_mode mode, const_rtx known_x, } /* Return the number of bits at the high-order end of X that are known to - be equal to the sign bit. X will be used in mode MODE; if MODE is - VOIDmode, X will be used in its own mode. The returned value will always - be between 1 and the number of bits in MODE. */ + be equal to the sign bit. X will be used in mode MODE. The returned + value will always be between 1 and the number of bits in MODE. */ static unsigned int -num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, +num_sign_bit_copies1 (const_rtx x, scalar_int_mode mode, const_rtx known_x, machine_mode known_mode, unsigned int known_ret) { enum rtx_code code = GET_CODE (x); - machine_mode inner_mode; + unsigned int bitwidth = GET_MODE_PRECISION (mode); int num0, num1, result; unsigned HOST_WIDE_INT nonzero; - /* If we weren't given a mode, use the mode of X. If the mode is still - VOIDmode, we don't know anything. Likewise if one of the modes is - floating-point. */ + if (CONST_INT_P (x)) + { + /* If the constant is negative, take its 1's complement and remask. + Then see how many zero bits we have. */ + nonzero = UINTVAL (x) & GET_MODE_MASK (mode); + if (bitwidth <= HOST_BITS_PER_WIDE_INT + && (nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))) != 0) + nonzero = (~nonzero) & GET_MODE_MASK (mode); - if (mode == VOIDmode) - mode = GET_MODE (x); + return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); + } gcc_checking_assert (mode != BLKmode); - if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)) - || VECTOR_MODE_P (GET_MODE (x)) || VECTOR_MODE_P (mode)) + scalar_int_mode xmode, inner_mode; + if (!is_a (GET_MODE (x), &xmode)) return 1; + unsigned int xmode_width = GET_MODE_PRECISION (xmode); + /* For a smaller mode, just ignore the high bits. */ - unsigned int bitwidth = GET_MODE_PRECISION (mode); - if (bitwidth < GET_MODE_PRECISION (GET_MODE (x))) + if (bitwidth < xmode_width) { - num0 = cached_num_sign_bit_copies (x, GET_MODE (x), + num0 = cached_num_sign_bit_copies (x, xmode, known_x, known_mode, known_ret); - return MAX (1, - num0 - (int) (GET_MODE_PRECISION (GET_MODE (x)) - bitwidth)); + return MAX (1, num0 - (int) (xmode_width - bitwidth)); } - if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_PRECISION (GET_MODE (x))) + if (bitwidth > xmode_width) { /* If this machine does not do all register operations on the entire register and MODE is wider than the mode of X, we can say nothing @@ -4869,8 +4879,8 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, /* Likewise on machines that do, if the mode of the object is smaller than a word and loads of that size don't sign extend, we can say nothing about the high order bits. */ - if (GET_MODE_PRECISION (GET_MODE (x)) < BITS_PER_WORD - && load_extend_op (GET_MODE (x)) != SIGN_EXTEND) + if (xmode_width < BITS_PER_WORD + && load_extend_op (xmode) != SIGN_EXTEND) return 1; } @@ -4887,7 +4897,7 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, we can do this only if the target does not support different pointer or address modes depending on the address space. */ if (target_default_pointer_address_modes_p () - && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode + && ! POINTERS_EXTEND_UNSIGNED && xmode == Pmode && mode == Pmode && REG_POINTER (x) && !targetm.have_ptr_extend ()) return GET_MODE_PRECISION (Pmode) - GET_MODE_PRECISION (ptr_mode) + 1; @@ -4912,22 +4922,14 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, case MEM: /* Some RISC machines sign-extend all loads of smaller than a word. */ - if (load_extend_op (GET_MODE (x)) == SIGN_EXTEND) - return MAX (1, ((int) bitwidth - - (int) GET_MODE_PRECISION (GET_MODE (x)) + 1)); + if (load_extend_op (xmode) == SIGN_EXTEND) + return MAX (1, ((int) bitwidth - (int) xmode_width + 1)); break; - case CONST_INT: - /* If the constant is negative, take its 1's complement and remask. - Then see how many zero bits we have. */ - nonzero = UINTVAL (x) & GET_MODE_MASK (mode); - if (bitwidth <= HOST_BITS_PER_WIDE_INT - && (nonzero & (HOST_WIDE_INT_1U << (bitwidth - 1))) != 0) - nonzero = (~nonzero) & GET_MODE_MASK (mode); - - return (nonzero == 0 ? bitwidth : bitwidth - floor_log2 (nonzero) - 1); - case SUBREG: + if (!is_a (GET_MODE (SUBREG_REG (x)), &inner_mode)) + break; + /* If this is a SUBREG for a promoted object that is sign-extended and we are looking at it in a wider mode, we know that at least the high-order bits are known to be sign bit copies. */ @@ -4936,16 +4938,13 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, { num0 = cached_num_sign_bit_copies (SUBREG_REG (x), mode, known_x, known_mode, known_ret); - return MAX ((int) bitwidth - - (int) GET_MODE_PRECISION (GET_MODE (x)) + 1, - num0); + return MAX ((int) bitwidth - (int) xmode_width + 1, num0); } /* For a smaller object, just ignore the high bits. */ - inner_mode = GET_MODE (SUBREG_REG (x)); if (bitwidth <= GET_MODE_PRECISION (inner_mode)) { - num0 = cached_num_sign_bit_copies (SUBREG_REG (x), VOIDmode, + num0 = cached_num_sign_bit_copies (SUBREG_REG (x), inner_mode, known_x, known_mode, known_ret); return MAX (1, num0 - (int) (GET_MODE_PRECISION (inner_mode) - bitwidth)); @@ -4975,15 +4974,18 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, break; case SIGN_EXTEND: - return (bitwidth - GET_MODE_PRECISION (GET_MODE (XEXP (x, 0))) - + cached_num_sign_bit_copies (XEXP (x, 0), VOIDmode, - known_x, known_mode, known_ret)); + if (is_a (GET_MODE (XEXP (x, 0)), &inner_mode)) + return (bitwidth - GET_MODE_PRECISION (inner_mode) + + cached_num_sign_bit_copies (XEXP (x, 0), inner_mode, + known_x, known_mode, known_ret)); + break; case TRUNCATE: /* For a smaller object, just ignore the high bits. */ - num0 = cached_num_sign_bit_copies (XEXP (x, 0), VOIDmode, + inner_mode = as_a (GET_MODE (XEXP (x, 0))); + num0 = cached_num_sign_bit_copies (XEXP (x, 0), inner_mode, known_x, known_mode, known_ret); - return MAX (1, (num0 - (int) (GET_MODE_PRECISION (GET_MODE (XEXP (x, 0))) + return MAX (1, (num0 - (int) (GET_MODE_PRECISION (inner_mode) - bitwidth))); case NOT: @@ -5160,7 +5162,7 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, known_x, known_mode, known_ret); if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) > 0 - && INTVAL (XEXP (x, 1)) < GET_MODE_PRECISION (GET_MODE (x))) + && INTVAL (XEXP (x, 1)) < xmode_width) num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1))); return num0; @@ -5170,7 +5172,7 @@ num_sign_bit_copies1 (const_rtx x, machine_mode mode, const_rtx known_x, if (!CONST_INT_P (XEXP (x, 1)) || INTVAL (XEXP (x, 1)) < 0 || INTVAL (XEXP (x, 1)) >= (int) bitwidth - || INTVAL (XEXP (x, 1)) >= GET_MODE_PRECISION (GET_MODE (x))) + || INTVAL (XEXP (x, 1)) >= xmode_width) return 1; num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,