From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3296 invoked by alias); 2 May 2017 12:54:01 -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 3274 invoked by uid 89); 2 May 2017 12:54:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_MANYTO,KAM_STOCKGEN,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=HX-Envelope-From:sk:Richard, HTo:U*rth, henderson, Henderson 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; Tue, 02 May 2017 12:53:58 +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 668B72B; Tue, 2 May 2017 05:53:58 -0700 (PDT) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 174E03F23B; Tue, 2 May 2017 05:53:56 -0700 (PDT) Subject: Re: [PATCH][AARCH64]Simplify call, call_value, sibcall, sibcall_value patterns. To: Renlin Li , "gcc-patches@gcc.gnu.org" , James Greenhalgh , Richard Henderson , Wilco Dijkstra , Ramana Radhakrishnan References: <5840444E.4020200@foss.arm.com> From: "Richard Earnshaw (lists)" Message-ID: <2a3dfac4-372e-9744-7680-809be729daad@arm.com> Date: Tue, 02 May 2017 13:02:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 In-Reply-To: <5840444E.4020200@foss.arm.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2017-05/txt/msg00093.txt.bz2 On 01/12/16 15:39, Renlin Li wrote: > Hi all, > > This patch refactors the code used in call, call_value, sibcall, > sibcall_value expanders. > > Before the change, the logic is following: > > call expander --> call_internal --> call_reg/call_symbol > call_vlaue expander --> call_value_internal --> > call_value_reg/call_value_symbol > > sibcall expander --> sibcall_internal --> sibcall_insn > sibcall_value expander --> sibcall_value_internal --> sibcall_value_insn > > After the change, the logic is simplified into: > > call expander --> aarch64_expand_call() --> call_insn > call_value expander --> aarch64_expand_call() --> call_value_insn > > sibcall expander --> aarch64_expand_call() --> sibcall_insn > sibcall_value expander --> aarch64_expand_call() --> sibcall_value_insn > > The code are factored out from each expander into aarch64_expand_call (). > > This also fixes the two issues Richard Henderson suggests in comments 8: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64971 > > aarch64-none-elf regression test Okay, aarch64-linux bootstrap Okay. > Okay for trunk? > > Regards, > Renlin Li > > > gcc/ChangeLog: > > 2016-12-01 Renlin Li > > * config/aarch64/aarch64-protos.h (aarch64_expand_call): Declare. > * config/aarch64/aarch64.c (aarch64_expand_call): Define. > * config/aarch64/constraints.md (Usf): Add long call check. > * config/aarch64/aarch64.md (call): Use aarch64_expand_call. > (call_value): Likewise. > (sibcall): Likewise. > (sibcall_value): Likewise. > (call_insn): New. > (call_value_insn): New. > (sibcall_insn): Update rtx pattern. > (sibcall_value_insn): Likewise. > (call_internal): Remove. > (call_value_internal): Likewise. > (sibcall_internal): Likewise. > (sibcall_value_internal): Likewise. > (call_reg): Likewise. > (call_symbol): Likewise. > (call_value_reg): Likewise. > (call_value_symbol): Likewise. > > > new.diff > > > diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h > index 7f67f14..3a5babb 100644 > --- a/gcc/config/aarch64/aarch64-protos.h > +++ b/gcc/config/aarch64/aarch64-protos.h > @@ -305,6 +305,7 @@ bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT); > bool aarch64_constant_address_p (rtx); > bool aarch64_emit_approx_div (rtx, rtx, rtx); > bool aarch64_emit_approx_sqrt (rtx, rtx, bool); > +void aarch64_expand_call (rtx, rtx, bool); > bool aarch64_expand_movmem (rtx *); > bool aarch64_float_const_zero_rtx_p (rtx); > bool aarch64_function_arg_regno_p (unsigned); > diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c > index 68a3380..c313cf5 100644 > --- a/gcc/config/aarch64/aarch64.c > +++ b/gcc/config/aarch64/aarch64.c > @@ -4343,6 +4343,51 @@ aarch64_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2) > return true; > } > > +/* This function is used by the call expanders of the machine description. > + RESULT is the register in which the result is returned. It's NULL for > + "call" and "sibcall". > + MEM is the location of the function call. > + SIBCALL indicates whether this function call is normal call or sibling call. > + It will generate different pattern accordingly. */ > + > +void > +aarch64_expand_call (rtx result, rtx mem, bool sibcall) > +{ > + rtx call, callee, tmp; > + rtvec vec; > + machine_mode mode; > + > + gcc_assert (MEM_P (mem)); > + callee = XEXP (mem, 0); > + mode = GET_MODE (callee); > + gcc_assert (mode == Pmode); > + > + /* Decide if we should generate indirect calls by loading the > + 64-bit address of the callee into a register before performing Drop '64-bit'. This code should also work for ILP32, where the addresses are 32-bit. > + the branch-and-link. */ > + > + if (GET_CODE (callee) == SYMBOL_REF Use SYMBOL_REF_P. OK with those changes. R. > + ? (aarch64_is_long_call_p (callee) > + || aarch64_is_noplt_call_p (callee)) > + : !REG_P (callee)) > + XEXP (mem, 0) = force_reg (mode, callee); > + > + call = gen_rtx_CALL (VOIDmode, mem, const0_rtx); > + > + if (result != NULL_RTX) > + call = gen_rtx_SET (result, call); > + > + if (sibcall) > + tmp = ret_rtx; > + else > + tmp = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM)); > + > + vec = gen_rtvec (2, call, tmp); > + call = gen_rtx_PARALLEL (VOIDmode, vec); > + > + aarch64_emit_call_insn (call); > +} > + > /* Emit call insn with PAT and do aarch64-specific handling. */ > > void > diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md > index bc6d8a2..5682686 100644 > --- a/gcc/config/aarch64/aarch64.md > +++ b/gcc/config/aarch64/aarch64.md > @@ -718,12 +718,6 @@ > ;; Subroutine calls and sibcalls > ;; ------------------------------------------------------------------- > > -(define_expand "call_internal" > - [(parallel [(call (match_operand 0 "memory_operand" "") > - (match_operand 1 "general_operand" "")) > - (use (match_operand 2 "" "")) > - (clobber (reg:DI LR_REGNUM))])]) > - > (define_expand "call" > [(parallel [(call (match_operand 0 "memory_operand" "") > (match_operand 1 "general_operand" "")) > @@ -732,57 +726,22 @@ > "" > " > { > - rtx callee, pat; > - > - /* In an untyped call, we can get NULL for operand 2. */ > - if (operands[2] == NULL) > - operands[2] = const0_rtx; > - > - /* Decide if we should generate indirect calls by loading the > - 64-bit address of the callee into a register before performing > - the branch-and-link. */ > - callee = XEXP (operands[0], 0); > - if (GET_CODE (callee) == SYMBOL_REF > - ? (aarch64_is_long_call_p (callee) > - || aarch64_is_noplt_call_p (callee)) > - : !REG_P (callee)) > - XEXP (operands[0], 0) = force_reg (Pmode, callee); > - > - pat = gen_call_internal (operands[0], operands[1], operands[2]); > - aarch64_emit_call_insn (pat); > + aarch64_expand_call (NULL_RTX, operands[0], false); > DONE; > }" > ) > > -(define_insn "*call_reg" > - [(call (mem:DI (match_operand:DI 0 "register_operand" "r")) > +(define_insn "*call_insn" > + [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "r, Usf")) > (match_operand 1 "" "")) > - (use (match_operand 2 "" "")) > (clobber (reg:DI LR_REGNUM))] > "" > - "blr\\t%0" > - [(set_attr "type" "call")] > -) > - > -(define_insn "*call_symbol" > - [(call (mem:DI (match_operand:DI 0 "" "")) > - (match_operand 1 "" "")) > - (use (match_operand 2 "" "")) > - (clobber (reg:DI LR_REGNUM))] > - "GET_CODE (operands[0]) == SYMBOL_REF > - && !aarch64_is_long_call_p (operands[0]) > - && !aarch64_is_noplt_call_p (operands[0])" > - "bl\\t%a0" > - [(set_attr "type" "call")] > + "@ > + blr\\t%0 > + bl\\t%a0" > + [(set_attr "type" "call, call")] > ) > > -(define_expand "call_value_internal" > - [(parallel [(set (match_operand 0 "" "") > - (call (match_operand 1 "memory_operand" "") > - (match_operand 2 "general_operand" ""))) > - (use (match_operand 3 "" "")) > - (clobber (reg:DI LR_REGNUM))])]) > - > (define_expand "call_value" > [(parallel [(set (match_operand 0 "" "") > (call (match_operand 1 "memory_operand" "") > @@ -792,60 +751,23 @@ > "" > " > { > - rtx callee, pat; > - > - /* In an untyped call, we can get NULL for operand 3. */ > - if (operands[3] == NULL) > - operands[3] = const0_rtx; > - > - /* Decide if we should generate indirect calls by loading the > - 64-bit address of the callee into a register before performing > - the branch-and-link. */ > - callee = XEXP (operands[1], 0); > - if (GET_CODE (callee) == SYMBOL_REF > - ? (aarch64_is_long_call_p (callee) > - || aarch64_is_noplt_call_p (callee)) > - : !REG_P (callee)) > - XEXP (operands[1], 0) = force_reg (Pmode, callee); > - > - pat = gen_call_value_internal (operands[0], operands[1], operands[2], > - operands[3]); > - aarch64_emit_call_insn (pat); > + aarch64_expand_call (operands[0], operands[1], false); > DONE; > }" > ) > > -(define_insn "*call_value_reg" > +(define_insn "*call_value_insn" > [(set (match_operand 0 "" "") > - (call (mem:DI (match_operand:DI 1 "register_operand" "r")) > + (call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "r, Usf")) > (match_operand 2 "" ""))) > - (use (match_operand 3 "" "")) > (clobber (reg:DI LR_REGNUM))] > "" > - "blr\\t%1" > - [(set_attr "type" "call")] > - > -) > - > -(define_insn "*call_value_symbol" > - [(set (match_operand 0 "" "") > - (call (mem:DI (match_operand:DI 1 "" "")) > - (match_operand 2 "" ""))) > - (use (match_operand 3 "" "")) > - (clobber (reg:DI LR_REGNUM))] > - "GET_CODE (operands[1]) == SYMBOL_REF > - && !aarch64_is_long_call_p (operands[1]) > - && !aarch64_is_noplt_call_p (operands[1])" > - "bl\\t%a1" > - [(set_attr "type" "call")] > + "@ > + blr\\t%1 > + bl\\t%a1" > + [(set_attr "type" "call, call")] > ) > > -(define_expand "sibcall_internal" > - [(parallel [(call (match_operand 0 "memory_operand" "") > - (match_operand 1 "general_operand" "")) > - (return) > - (use (match_operand 2 "" ""))])]) > - > (define_expand "sibcall" > [(parallel [(call (match_operand 0 "memory_operand" "") > (match_operand 1 "general_operand" "")) > @@ -853,29 +775,11 @@ > (use (match_operand 2 "" ""))])] > "" > { > - rtx pat; > - rtx callee = XEXP (operands[0], 0); > - if (!REG_P (callee) > - && ((GET_CODE (callee) != SYMBOL_REF) > - || aarch64_is_noplt_call_p (callee))) > - XEXP (operands[0], 0) = force_reg (Pmode, callee); > - > - if (operands[2] == NULL_RTX) > - operands[2] = const0_rtx; > - > - pat = gen_sibcall_internal (operands[0], operands[1], operands[2]); > - aarch64_emit_call_insn (pat); > + aarch64_expand_call (NULL_RTX, operands[0], true); > DONE; > } > ) > > -(define_expand "sibcall_value_internal" > - [(parallel [(set (match_operand 0 "" "") > - (call (match_operand 1 "memory_operand" "") > - (match_operand 2 "general_operand" ""))) > - (return) > - (use (match_operand 3 "" ""))])]) > - > (define_expand "sibcall_value" > [(parallel [(set (match_operand 0 "" "") > (call (match_operand 1 "memory_operand" "") > @@ -884,19 +788,7 @@ > (use (match_operand 3 "" ""))])] > "" > { > - rtx pat; > - rtx callee = XEXP (operands[1], 0); > - if (!REG_P (callee) > - && ((GET_CODE (callee) != SYMBOL_REF) > - || aarch64_is_noplt_call_p (callee))) > - XEXP (operands[1], 0) = force_reg (Pmode, callee); > - > - if (operands[3] == NULL_RTX) > - operands[3] = const0_rtx; > - > - pat = gen_sibcall_value_internal (operands[0], operands[1], operands[2], > - operands[3]); > - aarch64_emit_call_insn (pat); > + aarch64_expand_call (operands[0], operands[1], true); > DONE; > } > ) > @@ -904,8 +796,7 @@ > (define_insn "*sibcall_insn" > [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucs, Usf")) > (match_operand 1 "" "")) > - (return) > - (use (match_operand 2 "" ""))] > + (return)] > "SIBLING_CALL_P (insn)" > "@ > br\\t%0 > @@ -918,8 +809,7 @@ > (call (mem:DI > (match_operand:DI 1 "aarch64_call_insn_operand" "Ucs, Usf")) > (match_operand 2 "" ""))) > - (return) > - (use (match_operand 3 "" ""))] > + (return)] > "SIBLING_CALL_P (insn)" > "@ > br\\t%1 > diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md > index 7a2847a..bd28386 100644 > --- a/gcc/config/aarch64/constraints.md > +++ b/gcc/config/aarch64/constraints.md > @@ -118,7 +118,8 @@ > (define_constraint "Usf" > "@internal Usf is a symbol reference under the context where plt stub allowed." > (and (match_code "symbol_ref") > - (match_test "!aarch64_is_noplt_call_p (op)"))) > + (match_test "!(aarch64_is_noplt_call_p (op) > + || aarch64_is_long_call_p (op))"))) > > (define_constraint "UsM" > "@internal >