From patchwork Sat Sep 29 03:12:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 976537 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-486657-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="H0o1CCOo"; 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 42MYWB5gRmz9sBq for ; Sat, 29 Sep 2018 13:12:21 +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:to:cc :from:subject:date:mime-version:content-type :content-transfer-encoding:message-id; q=dns; s=default; b=ekIpF qFxhSfG8k7nax0rsfyvRgK6Aj+RgZnrsiw7eXBNXeJt75Nt8t302l+7OPYT3yoAd AaAiF5/gURdxwAktHY+TRxvC4V2Rvu7/lo0WcbSnZTMplya3u1V5AZSzVWSCMsyA aZjripwe5XE143Btt8DBgNZDmhFCUJzzj8DVs8= 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:to:cc :from:subject:date:mime-version:content-type :content-transfer-encoding:message-id; s=default; bh=XBhOQdpbI7m yVh3VC3V98AYSi+g=; b=H0o1CCOouIhaOsLC/zNaRowF4bSUjaerAxVuWq94aTF jQbZ9R9Kxw6P3SsMUY7aISmRKbqcQdFh3n0nlREuOuwucMMF6Jl8qblDBd1YhSBl socGdYIYTy3ER04pvoOi0yjrafRCqMI5lNqkJrGeBreMupRfnuvWrpLxPsdTFf2Q = Received: (qmail 116855 invoked by alias); 29 Sep 2018 03:12:13 -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 116846 invoked by uid 89); 29 Sep 2018 03:12:13 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=H*m:linux, U**, sk:rs6000_ X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 29 Sep 2018 03:12:10 +0000 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w8T39JrL050241 for ; Fri, 28 Sep 2018 23:12:08 -0400 Received: from e16.ny.us.ibm.com (e16.ny.us.ibm.com [129.33.205.206]) by mx0a-001b2d01.pphosted.com with ESMTP id 2msx2amy57-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 28 Sep 2018 23:12:08 -0400 Received: from localhost by e16.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 28 Sep 2018 23:12:07 -0400 Received: from b01cxnp22035.gho.pok.ibm.com (9.57.198.25) by e16.ny.us.ibm.com (146.89.104.203) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Fri, 28 Sep 2018 23:12:04 -0400 Received: from b01ledav003.gho.pok.ibm.com (b01ledav003.gho.pok.ibm.com [9.57.199.108]) by b01cxnp22035.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w8T3C3vc47251618 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sat, 29 Sep 2018 03:12:03 GMT Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6800AB2067; Fri, 28 Sep 2018 23:10:20 -0400 (EDT) Received: from b01ledav003.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E10BAB2068; Fri, 28 Sep 2018 23:10:19 -0400 (EDT) Received: from otta.local (unknown [9.80.200.29]) by b01ledav003.gho.pok.ibm.com (Postfix) with ESMTP; Fri, 28 Sep 2018 23:10:19 -0400 (EDT) To: GCC Patches Cc: Vladimir N Makarov , Jeff Law , Segher Boessenkool , Eric Botcazou , Richard Biener From: Peter Bergner Subject: [PATCH][IRA, LRA] Fix PR87466, all pseudos live across setjmp are spilled Date: Fri, 28 Sep 2018 22:12:02 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 MIME-Version: 1.0 x-cbid: 18092903-0072-0000-0000-000003AC65C3 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00009789; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000267; SDB=6.01095159; UDB=6.00566177; IPR=6.00875196; MB=3.00023548; MTD=3.00000008; XFM=3.00000015; UTC=2018-09-29 03:12:06 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18092903-0073-0000-0000-000049950758 Message-Id: <7f0ff8da-a164-bf05-c668-c69f7b8f314b@linux.ibm.com> X-IsSubscribed: yes Currently, both IRA and LRA spill all pseudo regs that are live across a setjmp call. If the target has a sane setjmp, then the compiler should not have to treat the setjmp call any differently than is does any other normal function call. Namely, just mark all pseudos that are live across the setjmp as conflicting with the volatile registers. This issue was discussed in the following gcc mailing list thread: https://gcc.gnu.org/ml/gcc/2018-03/msg00014.html ...and some people mentioned that some systems do not have sane setjmp implementations and therefore need the spill all pseudos live across setjmps to get correct functionality. It was decided in the thread above that we should create a target hook that can allow targets to tell IRA and LRA whether or not they have a sane setjmp implementation. The following patch implements that idea along with converting the rs6000 port to use the hook. This patch passed bootstrap and regtesting on powerpc64le-linux with no regressions. Ok for trunk? Peter gcc/ PR rtl-optimization/87466 * target.def (is_reg_clobbering_setjmp_p): New target hook. * doc/tm.texi.in (TARGET_IS_REG_CLOBBERING_SETJMP_P): New hook. * doc/tm.texi: Regenerate. * targhooks.c (default_is_reg_clobbering_setjmp_p): Declare. * targhooks.h (default_is_reg_clobbering_setjmp_p): New function. * ira-lives.c (process_bb_node_lives): Use the new target hook. * lra-lives.c (process_bb_lives): Likewise. * config/rs6000/rs6000.c (TARGET_IS_REG_CLOBBERING_SETJMP_P): Define. (rs6000_is_reg_clobbering_setjmp_p): New function. gcc/testsuite/ PR rtl-optimization/87466 * gcc.target/powerpc/pr87466.c: New test. Index: gcc/target.def =================================================================== --- gcc/target.def (revision 264698) +++ gcc/target.def (working copy) @@ -3123,6 +3123,20 @@ In order to enforce the representation o int, (scalar_int_mode mode, scalar_int_mode rep_mode), default_mode_rep_extended) + DEFHOOK +(is_reg_clobbering_setjmp_p, + "On some targets, it is assumed that the compiler will spill all registers\n\ + that are live across a call to @code{setjmp}, while other targets treat\n\ + @code{setjmp} calls as normal function calls.\n\ + \n\ + This hook returns true if @var{insn} is a @code{setjmp} call that must\n\ + have all registers that are live across it spilled. Define this to return\n\ + false if the target does not need to spill all registers across calls to\n\ + @code{setjmp} calls. The default implementation conservatively assumes all\n\ + registers must be spilled across @code{setjmp} calls.", +bool, (const rtx_insn *insn), +default_is_reg_clobbering_setjmp_p) + /* True if MODE is valid for a pointer in __attribute__((mode("MODE"))). */ DEFHOOK (valid_pointer_mode, Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in (revision 264698) +++ gcc/doc/tm.texi.in (working copy) @@ -7507,6 +7507,8 @@ You need not define this macro if it wou @hook TARGET_MODE_REP_EXTENDED +@hook TARGET_IS_REG_CLOBBERING_SETJMP_P + @defmac STORE_FLAG_VALUE A C expression describing the value returned by a comparison operator with an integral mode and stored by a store-flag instruction Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 264698) +++ gcc/doc/tm.texi (working copy) @@ -11000,6 +11000,18 @@ In order to enforce the representation o @code{mode}. @end deftypefn +@deftypefn {Target Hook} bool TARGET_IS_REG_CLOBBERING_SETJMP_P (const rtx_insn *@var{insn}) +On some targets, it is assumed that the compiler will spill all registers + that are live across a call to @code{setjmp}, while other targets treat + @code{setjmp} calls as normal function calls. + + This hook returns true if @var{insn} is a @code{setjmp} call that must + have all registers that are live across it spilled. Define this to return + false if the target does not need to spill all registers across calls to + @code{setjmp} calls. The default implementation conservatively assumes all + registers must be spilled across @code{setjmp} calls. +@end deftypefn + @defmac STORE_FLAG_VALUE A C expression describing the value returned by a comparison operator with an integral mode and stored by a store-flag instruction Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c (revision 264698) +++ gcc/targhooks.c (working copy) @@ -209,6 +209,15 @@ default_builtin_setjmp_frame_value (void return virtual_stack_vars_rtx; } +/* The default implementation of TARGET_IS_REG_CLOBBERING_SETJMP_P. */ + +bool +default_is_reg_clobbering_setjmp_p (const rtx_insn *insn) +{ + return CALL_P (insn) + && find_reg_note (insn, REG_SETJMP, NULL_RTX) != NULL_RTX; +} + /* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */ bool Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h (revision 264698) +++ gcc/targhooks.h (working copy) @@ -42,6 +42,7 @@ extern bool default_return_in_memory (co extern rtx default_expand_builtin_saveregs (void); extern void default_setup_incoming_varargs (cumulative_args_t, machine_mode, tree, int *, int); extern rtx default_builtin_setjmp_frame_value (void); +extern bool default_is_reg_clobbering_setjmp_p (const rtx_insn *); extern bool default_pretend_outgoing_varargs_named (cumulative_args_t); extern scalar_int_mode default_eh_return_filter_mode (void); Index: gcc/ira-lives.c =================================================================== --- gcc/ira-lives.c (revision 264698) +++ gcc/ira-lives.c (working copy) @@ -1209,8 +1209,7 @@ process_bb_node_lives (ira_loop_tree_nod call, if this function receives a nonlocal goto. */ if (cfun->has_nonlocal_label - || find_reg_note (insn, REG_SETJMP, - NULL_RTX) != NULL_RTX) + || targetm.is_reg_clobbering_setjmp_p (insn)) { SET_HARD_REG_SET (OBJECT_CONFLICT_HARD_REGS (obj)); SET_HARD_REG_SET (OBJECT_TOTAL_CONFLICT_HARD_REGS (obj)); Index: gcc/lra-lives.c =================================================================== --- gcc/lra-lives.c (revision 264698) +++ gcc/lra-lives.c (working copy) @@ -893,8 +893,7 @@ process_bb_lives (basic_block bb, int &c sparseset_ior (pseudos_live_through_calls, pseudos_live_through_calls, pseudos_live); if (cfun->has_nonlocal_label - || find_reg_note (curr_insn, REG_SETJMP, - NULL_RTX) != NULL_RTX) + || targetm.is_reg_clobbering_setjmp_p (curr_insn)) sparseset_ior (pseudos_live_through_setjumps, pseudos_live_through_setjumps, pseudos_live); } Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 264698) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -1978,6 +1978,9 @@ static const struct attribute_spec rs600 #undef TARGET_ASM_GLOBALIZE_DECL_NAME #define TARGET_ASM_GLOBALIZE_DECL_NAME rs6000_globalize_decl_name #endif + +#undef TARGET_IS_REG_CLOBBERING_SETJMP_P +#define TARGET_IS_REG_CLOBBERING_SETJMP_P rs6000_is_reg_clobbering_setjmp_p /* Processor table. */ @@ -38696,6 +38699,14 @@ rs6000_starting_frame_offset (void) return 0; return RS6000_STARTING_FRAME_OFFSET; } + +/* Implement TARGET_IS_REG_CLOBBERING_SETJMP_P. */ + +static bool +rs6000_is_reg_clobbering_setjmp_p (const rtx_insn *insn ATTRIBUTE_UNUSED) +{ + return false; +} /* Create an alias for a mangled name where we have changed the mangling (in Index: gcc/testsuite/gcc.target/powerpc/pr87466.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr87466.c (nonexistent) +++ gcc/testsuite/gcc.target/powerpc/pr87466.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do compile { target powerpc*-*-* } } */ +/* { dg-options "-O2" } */ + +#include +#include + +extern void foo (jmp_buf); + +long +c (long var) +{ + jmp_buf env; + if (setjmp(env) != 0) + abort(); + foo (env); + return var; +} + +/* { dg-final { scan-assembler {\mmr\M} } } */