From patchwork Mon Aug 24 11:18:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 509991 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DEC921402A0 for ; Mon, 24 Aug 2015 21:19:10 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=wGa4vTbQ; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=yX3S3/3SrEaqFANK Xl19+Rumckdi0LdZHJ8Mnwqv6qenu+QRvmI5JjDWe9H2/p6u83xfaX9MG44b4jsW MbSxcahzjp+91YJpfvgCIc/xSJ8pd2QHXXuiBKHePDJ3CmxHyd7W0zQ5c0vP/+2L SYZqaOXvLVjMVQJyWBYf6f9qdgI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=JNAZ4BAygpbS4vv4psX9ni wKVrI=; b=wGa4vTbQ2SBcJ0YDvwVHc3N3z9BRKJGFBku3pHQOTRfdrbu554PFzv kyd/rWrd5wqjVRk6L7nhxyMvPRVpReW7CJn3hDXYGjMCSykQu/nmNIx+1sqh9v+d KJ5Mb+mTCaM2T7Bjao98sWnY16ByPQbCfbAkX2IdsU5zYJf/wDnKQ= Received: (qmail 39372 invoked by alias); 24 Aug 2015 11:19:04 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 39360 invoked by uid 89); 24 Aug 2015 11:19:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (207.82.80.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 24 Aug 2015 11:19:01 +0000 Received: from cam-owa2.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-22-jGnbPrYHRhS8NzflyzNmlQ-1; Mon, 24 Aug 2015 12:18:56 +0100 Received: from localhost ([10.1.2.79]) by cam-owa2.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 24 Aug 2015 12:18:56 +0100 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Use cmpmem optabs in builtins.c Date: Mon, 24 Aug 2015 12:18:55 +0100 Message-ID: <87si796ijk.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-MC-Unique: jGnbPrYHRhS8NzflyzNmlQ-1 Similarly to the patch for cmpstr(n), this patch uses the optabs interface for cmpmem instead of using HAVE_cmpmmsi and CODE_FOR_cmpmemsi directly. Tested on x86_64-linux-gnu. OK to install? Thanks, Richard gcc/ * builtins.c (expand_cmpstrn): Rename to... (expand_cmpstrn_or_cmpmem): ...this. (expand_builtin_strcmp, expand_builtin_strncmp): Update accordingly. (expand_builtin_memcmp): Use optabs instead of HAVE_cmpmem/gen_cmpmem. Remove mode argument. (expand_builtin): Update accordingly. diff --git a/gcc/builtins.c b/gcc/builtins.c index def13c9..10c45bb 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -119,7 +119,6 @@ static rtx expand_builtin_next_arg (void); static rtx expand_builtin_va_start (tree); static rtx expand_builtin_va_end (tree); static rtx expand_builtin_va_copy (tree); -static rtx expand_builtin_memcmp (tree, rtx, machine_mode); static rtx expand_builtin_strcmp (tree, rtx); static rtx expand_builtin_strncmp (tree, rtx, machine_mode); static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, machine_mode); @@ -3944,13 +3943,14 @@ expand_cmpstr (insn_code icode, rtx target, rtx arg1_rtx, rtx arg2_rtx, return NULL_RTX; } -/* Try to expand cmpstrn operation ICODE with the given operands. +/* Try to expand cmpstrn or cmpmem operation ICODE with the given operands. ARG3_TYPE is the type of ARG3_RTX. Return the result rtx on success, otherwise return null. */ static rtx -expand_cmpstrn (insn_code icode, rtx target, rtx arg1_rtx, rtx arg2_rtx, - tree arg3_type, rtx arg3_rtx, HOST_WIDE_INT align) +expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx, + rtx arg2_rtx, tree arg3_type, rtx arg3_rtx, + HOST_WIDE_INT align) { machine_mode insn_mode = insn_data[icode].operand[0].mode; @@ -3971,15 +3971,11 @@ expand_cmpstrn (insn_code icode, rtx target, rtx arg1_rtx, rtx arg2_rtx, /* Expand expression EXP, which is a call to the memcmp built-in function. Return NULL_RTX if we failed and the caller should emit a normal call, - otherwise try to get the result in TARGET, if convenient (and in mode - MODE, if that's convenient). */ + otherwise try to get the result in TARGET, if convenient. */ static rtx -expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, - ATTRIBUTE_UNUSED machine_mode mode) +expand_builtin_memcmp (tree exp, rtx target) { - location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp); - if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)) return NULL_RTX; @@ -3987,78 +3983,66 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target, /* Note: The cmpstrnsi pattern, if it exists, is not suitable for implementing memcmp because it will stop if it encounters two zero bytes. */ -#if defined HAVE_cmpmemsi - { - rtx arg1_rtx, arg2_rtx, arg3_rtx; - rtx result; - rtx insn; - tree arg1 = CALL_EXPR_ARG (exp, 0); - tree arg2 = CALL_EXPR_ARG (exp, 1); - tree len = CALL_EXPR_ARG (exp, 2); + insn_code icode = direct_optab_handler (cmpmem_optab, SImode); + if (icode == CODE_FOR_nothing) + return NULL_RTX; - unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; - unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; - machine_mode insn_mode; + tree arg1 = CALL_EXPR_ARG (exp, 0); + tree arg2 = CALL_EXPR_ARG (exp, 1); + tree len = CALL_EXPR_ARG (exp, 2); - if (HAVE_cmpmemsi) - insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode; - else - return NULL_RTX; + unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT; + unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT; - /* If we don't have POINTER_TYPE, call the function. */ - if (arg1_align == 0 || arg2_align == 0) - return NULL_RTX; + /* If we don't have POINTER_TYPE, call the function. */ + if (arg1_align == 0 || arg2_align == 0) + return NULL_RTX; - /* Make a place to write the result of the instruction. */ - result = target; - if (! (result != 0 - && REG_P (result) && GET_MODE (result) == insn_mode - && REGNO (result) >= FIRST_PSEUDO_REGISTER)) - result = gen_reg_rtx (insn_mode); + machine_mode mode = TYPE_MODE (TREE_TYPE (exp)); + location_t loc = EXPR_LOCATION (exp); + rtx arg1_rtx = get_memory_rtx (arg1, len); + rtx arg2_rtx = get_memory_rtx (arg2, len); + rtx arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len)); - arg1_rtx = get_memory_rtx (arg1, len); - arg2_rtx = get_memory_rtx (arg2, len); - arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len)); + /* Set MEM_SIZE as appropriate. */ + if (CONST_INT_P (arg3_rtx)) + { + set_mem_size (arg1_rtx, INTVAL (arg3_rtx)); + set_mem_size (arg2_rtx, INTVAL (arg3_rtx)); + } - /* Set MEM_SIZE as appropriate. */ - if (CONST_INT_P (arg3_rtx)) - { - set_mem_size (arg1_rtx, INTVAL (arg3_rtx)); - set_mem_size (arg2_rtx, INTVAL (arg3_rtx)); - } + rtx result = expand_cmpstrn_or_cmpmem (icode, target, arg1_rtx, arg2_rtx, + TREE_TYPE (len), arg3_rtx, + MIN (arg1_align, arg2_align)); + if (result) + { + /* Return the value in the proper mode for this function. */ + if (GET_MODE (result) == mode) + return result; - if (HAVE_cmpmemsi) - insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx, - GEN_INT (MIN (arg1_align, arg2_align))); - else - gcc_unreachable (); + if (target != 0) + { + convert_move (target, result, 0); + return target; + } - if (insn) - emit_insn (insn); - else - emit_library_call_value (memcmp_libfunc, result, LCT_PURE, - TYPE_MODE (integer_type_node), 3, - XEXP (arg1_rtx, 0), Pmode, - XEXP (arg2_rtx, 0), Pmode, - convert_to_mode (TYPE_MODE (sizetype), arg3_rtx, - TYPE_UNSIGNED (sizetype)), - TYPE_MODE (sizetype)); - - /* Return the value in the proper mode for this function. */ - mode = TYPE_MODE (TREE_TYPE (exp)); - if (GET_MODE (result) == mode) - return result; - else if (target != 0) - { - convert_move (target, result, 0); - return target; - } - else return convert_to_mode (mode, result, 0); - } -#endif /* HAVE_cmpmemsi. */ + } - return NULL_RTX; + result = target; + if (! (result != 0 + && REG_P (result) && GET_MODE (result) == mode + && REGNO (result) >= FIRST_PSEUDO_REGISTER)) + result = gen_reg_rtx (mode); + + emit_library_call_value (memcmp_libfunc, result, LCT_PURE, + TYPE_MODE (integer_type_node), 3, + XEXP (arg1_rtx, 0), Pmode, + XEXP (arg2_rtx, 0), Pmode, + convert_to_mode (TYPE_MODE (sizetype), arg3_rtx, + TYPE_UNSIGNED (sizetype)), + TYPE_MODE (sizetype)); + return result; } /* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX @@ -4142,9 +4126,9 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target) if (len && !TREE_SIDE_EFFECTS (len)) { arg3_rtx = expand_normal (len); - result = expand_cmpstrn (cmpstrn_icode, target, arg1_rtx, - arg2_rtx, TREE_TYPE (len), arg3_rtx, - MIN (arg1_align, arg2_align)); + result = expand_cmpstrn_or_cmpmem + (cmpstrn_icode, target, arg1_rtx, arg2_rtx, TREE_TYPE (len), + arg3_rtx, MIN (arg1_align, arg2_align)); } } @@ -4254,9 +4238,9 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target, arg1_rtx = get_memory_rtx (arg1, len); arg2_rtx = get_memory_rtx (arg2, len); arg3_rtx = expand_normal (len); - result = expand_cmpstrn (cmpstrn_icode, target, arg1_rtx, arg2_rtx, - TREE_TYPE (len), arg3_rtx, - MIN (arg1_align, arg2_align)); + result = expand_cmpstrn_or_cmpmem (cmpstrn_icode, target, arg1_rtx, + arg2_rtx, TREE_TYPE (len), arg3_rtx, + MIN (arg1_align, arg2_align)); if (result) { /* Return the value in the proper mode for this function. */ @@ -6351,7 +6335,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, case BUILT_IN_BCMP: case BUILT_IN_MEMCMP: - target = expand_builtin_memcmp (exp, target, mode); + target = expand_builtin_memcmp (exp, target); if (target) return target; break;