From patchwork Fri May 17 22:08:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Segher Boessenkool X-Patchwork-Id: 1101292 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-501074-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kernel.crashing.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="CV5B0/hL"; dkim-atps=neutral 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 455Mr4515fz9s6w for ; Sat, 18 May 2019 08:08:29 +1000 (AEST) 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:cc:subject:date:message-id; q=dns; s=default; b=FYhrmVAynFnx +Z3vFS+Latw3Rrm+xOK6hJb7p0n8Xk5lmqnfbsu/zUxRXmLCeDUQjooa1DKa7jF9 ugsf1JYDvCid2q0Z/FHIxO1zR1PswcR0FqimNoKEBpUIKQ16wuNJ1lAPJlv0HmWF zLaUkoqUCKQm9DEIBcYGqBLPc8Z7OnM= 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:cc:subject:date:message-id; s=default; bh=vMwNt9IMOhlicMEbO1 ikPmrjneM=; b=CV5B0/hLEEKAxkSttmvyFW+f2xAeid32ONlvdanEigRzMSr+gj mpPyj0wOYTbqk6gcRTviuxPBuqwEk7VMjb8/pJ2lpcmOPrzFFcWw+RcTaOwst5HV fypZha4RZOsvnlbcphJz+dd3uvpVBVE0Q5NaeFZQThPZBYT4qUyWjIFrU= Received: (qmail 130455 invoked by alias); 17 May 2019 22:08:21 -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 130445 invoked by uid 89); 17 May 2019 22:08:20 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3 autolearn=ham version=3.3.1 spammy=lr, calls_eh_return, eh_return, strategy X-HELO: gcc1-power7.osuosl.org Received: from gcc1-power7.osuosl.org (HELO gcc1-power7.osuosl.org) (140.211.15.137) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 May 2019 22:08:19 +0000 Received: by gcc1-power7.osuosl.org (Postfix, from userid 10019) id 89ADC12405B0; Fri, 17 May 2019 22:08:17 +0000 (UTC) From: Segher Boessenkool To: gcc-patches@gcc.gnu.org Cc: dje.gcc@gmail.com, Segher Boessenkool Subject: [PATCH] rs6000: Some rs6000_emit_epilogue improvements Date: Fri, 17 May 2019 22:08:12 +0000 Message-Id: X-IsSubscribed: yes This uses epilogue_type directly. It also changes some ints to bools, declares variables later, and simplifies some code. There is one actual change: else if (info->push_p && DEFAULT_ABI != ABI_V4 - && !crtl->calls_eh_return) + && epilogue_type != EPILOGUE_TYPE_EH_RETURN) { /* Prevent reordering memory accesses against stack pointer restore. */ (different because calls_eh_return can be true for sibcalls). This is a bugfix. The code was never exercised. One place in the epilogue still uses crtl->calls_eh_return. If that is changed the prologue has to have a corresponding change, and the emit_prologue function does not have an epilogue_type parameter, so bail on changing this for now. We might want to do this (saving the CR fields to separate stack slots) always, not just for functions calling eh_return, but that will require more investigation. Tested on powerpc64-linux ({-m32,-m64}, p7) and on powerpc64le-linux (p9); committing to trunk. Segher 2019-05-17 Segher Boessenkool * config/rs6000/rs6000.c (restore_saved_cr): Change a boolean argument to be type bool (was int before). (rs6000_emit_epilogue): Simplify some code. Declare some variables at first use. Use type bool for some variables. Fix a theoretical eh_return bug for svr4. --- gcc/config/rs6000/rs6000.c | 97 +++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 2992ba5..da7dae1 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -27712,7 +27712,7 @@ load_cr_save (int regno, rtx frame_reg_rtx, int offset, bool exit_func) /* Reload CR from REG. */ static void -restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func) +restore_saved_cr (rtx reg, bool using_mfcr_multiple, bool exit_func) { int count = 0; int i; @@ -27876,15 +27876,6 @@ emit_cfa_restores (rtx cfa_restores) void rs6000_emit_epilogue (enum epilogue_type epilogue_type) { - int sibcall = (epilogue_type == EPILOGUE_TYPE_SIBCALL); - rs6000_stack_t *info; - int restoring_GPRs_inline; - int restoring_FPRs_inline; - int using_load_multiple; - int using_mtcr_multiple; - int use_backchain_to_restore_sp; - int restore_lr; - int strategy; HOST_WIDE_INT frame_off = 0; rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); rtx frame_reg_rtx = sp_reg_rtx; @@ -27896,30 +27887,38 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) machine_mode fp_reg_mode = TARGET_HARD_FLOAT ? DFmode : SFmode; int fp_reg_size = 8; int i; - bool exit_func; unsigned ptr_regno; - info = rs6000_stack_info (); + rs6000_stack_t *info = rs6000_stack_info (); + + if (epilogue_type == EPILOGUE_TYPE_NORMAL && crtl->calls_eh_return) + epilogue_type = EPILOGUE_TYPE_EH_RETURN; + + int strategy = info->savres_strategy; + bool using_load_multiple = !!(strategy & REST_MULTIPLE); + bool restoring_GPRs_inline = !!(strategy & REST_INLINE_GPRS); + bool restoring_FPRs_inline = !!(strategy & REST_INLINE_FPRS); + if (epilogue_type == EPILOGUE_TYPE_SIBCALL) + { + restoring_GPRs_inline = true; + restoring_FPRs_inline = true; + } + + bool using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601 + || rs6000_tune == PROCESSOR_PPC603 + || rs6000_tune == PROCESSOR_PPC750 + || optimize_size); - strategy = info->savres_strategy; - using_load_multiple = strategy & REST_MULTIPLE; - restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS); - restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS); - using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601 - || rs6000_tune == PROCESSOR_PPC603 - || rs6000_tune == PROCESSOR_PPC750 - || optimize_size); /* Restore via the backchain when we have a large frame, since this is more efficient than an addis, addi pair. The second condition here will not trigger at the moment; We don't actually need a frame pointer for alloca, but the generic parts of the compiler give us one anyway. */ - use_backchain_to_restore_sp = (info->total_size + (info->lr_save_p - ? info->lr_save_offset - : 0) > 32767 - || (cfun->calls_alloca - && !frame_pointer_needed)); - restore_lr = (info->lr_save_p + bool use_backchain_to_restore_sp + = (info->total_size + (info->lr_save_p ? info->lr_save_offset : 0) > 32767 + || (cfun->calls_alloca && !frame_pointer_needed)); + + bool restore_lr = (info->lr_save_p && (restoring_FPRs_inline || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR)) && (restoring_GPRs_inline @@ -27929,10 +27928,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) if (WORLD_SAVE_P (info)) { - int i, j; - char rname[30]; - const char *alloc_rname; - rtvec p; + gcc_assert (epilogue_type != EPILOGUE_TYPE_SIBCALL); /* eh_rest_world_r10 will return to the location saved in the LR stack slot (which is not likely to be our caller.) @@ -27941,19 +27937,31 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) The exception-handling stuff that was here in 2.95 is no longer necessary. */ + rtvec p; p = rtvec_alloc (9 + 32 - info->first_gp_reg_save + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save + 63 + 1 - info->first_fp_reg_save); - strcpy (rname, ((crtl->calls_eh_return) ? - "*eh_rest_world_r10" : "*rest_world")); - alloc_rname = ggc_strdup (rname); + const char *rname; + switch (epilogue_type) + { + case EPILOGUE_TYPE_NORMAL: + rname = ggc_strdup ("*rest_world"); + break; - j = 0; + case EPILOGUE_TYPE_EH_RETURN: + rname = ggc_strdup ("*eh_rest_world_r10"); + break; + + default: + gcc_unreachable (); + } + + int j = 0; RTVEC_ELT (p, j++) = ret_rtx; RTVEC_ELT (p, j++) - = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname)); + = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, rname)); /* The instruction pattern requires a clobber here; it is shared with the restVEC helper. */ RTVEC_ELT (p, j++) = gen_hard_reg_clobber (Pmode, 11); @@ -27972,6 +27980,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) } } + int i; for (i = 0; i < 32 - info->first_gp_reg_save; i++) { rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); @@ -28196,7 +28205,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) } else if (info->push_p && DEFAULT_ABI != ABI_V4 - && !crtl->calls_eh_return) + && epilogue_type != EPILOGUE_TYPE_EH_RETURN) { /* Prevent reordering memory accesses against stack pointer restore. */ if (cfun->calls_alloca @@ -28356,9 +28365,9 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) function will deallocate the stack, so we don't need to worry about the unwinder restoring cr from an invalid stack frame location. */ - exit_func = (!restoring_FPRs_inline - || (!restoring_GPRs_inline - && info->first_fp_reg_save == 64)); + bool exit_func = (!restoring_FPRs_inline + || (!restoring_GPRs_inline + && info->first_fp_reg_save == 64)); /* In the ELFv2 ABI we need to restore all call-saved CR fields from *separate* slots if the routine calls __builtin_eh_return, so @@ -28424,7 +28433,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) restore_saved_lr (0, exit_func); /* Load exception handler data registers, if needed. */ - if (!sibcall && crtl->calls_eh_return) + if (epilogue_type == EPILOGUE_TYPE_EH_RETURN) { unsigned int i, regno; @@ -28615,13 +28624,13 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) RTX_FRAME_RELATED_P (insn) = 1; } - if (!sibcall && crtl->calls_eh_return) + if (epilogue_type == EPILOGUE_TYPE_EH_RETURN) { rtx sa = EH_RETURN_STACKADJ_RTX; emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa)); } - if (!sibcall && restoring_FPRs_inline) + if (epilogue_type != EPILOGUE_TYPE_SIBCALL && restoring_FPRs_inline) { if (cfa_restores) { @@ -28646,7 +28655,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) emit_jump_insn (targetm.gen_simple_return ()); } - if (!sibcall && !restoring_FPRs_inline) + if (epilogue_type != EPILOGUE_TYPE_SIBCALL && !restoring_FPRs_inline) { bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0; rtvec p = rtvec_alloc (3 + !!lr + 64 - info->first_fp_reg_save); @@ -28685,7 +28694,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) if (cfa_restores) { - if (sibcall) + if (epilogue_type == EPILOGUE_TYPE_SIBCALL) /* Ensure the cfa_restores are hung off an insn that won't be reordered above other restores. */ emit_insn (gen_blockage ());