From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yb1-xb2f.google.com (mail-yb1-xb2f.google.com [IPv6:2607:f8b0:4864:20::b2f]) by sourceware.org (Postfix) with ESMTPS id 0455F3858410 for ; Mon, 22 Jan 2024 15:48:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0455F3858410 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0455F3858410 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::b2f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705938501; cv=none; b=t9EXzBEjHNHi22/ocWpvWeNb6NQ+Socb6r0hNoVAeTYVLutG5FqTnVHLf3m7VVenS1/1z5HQfkVeSRn8kkQlpVT8smk98Ygt30J5agiQhnEFZ2Rr5s55gpBMSXpqSZUolhjKZ4BUdiEC2iKR6OWPPpzsQhR7BV1wntVaf8viwkk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705938501; c=relaxed/simple; bh=9GoGg1HCQfoUm2WQ4anQpllOAWVWMH5KfX+vYc+jTxk=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=eyqOT1pY5NfnYsV70lQUolgwhz+kh0UQlTifezXpmZxp6WnIMEcnkncN2CrKQr4lFLXm3MSBo1g/jqnBvkfdxPqZqHwnGk4PqUyznnWipuFpbwrP4IA3yDlEJXE1WBzVI728xq5b1RCesbsLsY4k4c5trN9bRbEvET87RJGua0E= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-yb1-xb2f.google.com with SMTP id 3f1490d57ef6-dbed179f0faso3172785276.1 for ; Mon, 22 Jan 2024 07:48:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705938498; x=1706543298; darn=gcc.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=1Wzq1kH6oXFwzw3q9eSSvU+J6j2qo8P8PmpkoQJexiI=; b=J57pP/V4crl7GCC990Kv5YxJkDtxfool4e/SWF2oSuWNBPaEXLdp1H2wEz+m53WcrW FK7bf+26bzEolgdffqQ/HC4rBkhOR40C/YjClKWOS22+G9wBTWKDzvpRgyDs7eBbmRut SaDPxMkb9SrJnU19fu5jpTvszA6gDqqdneaR7m0cxpvdhnguzHljKpJRKer/ZIbIgevK E9KYEPEODJJzFD1hM4MUK54WwDRfWQiKRNQYw3V5HBmDkF+tT86NThSpS8XCcC9dKes5 kAnPmaGNtvDRL2lP2y7KYn41anroJyEc8yDCWOmKWaO6tjOAwYkXISCkOFdceNPyCMGk Ol7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705938498; x=1706543298; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1Wzq1kH6oXFwzw3q9eSSvU+J6j2qo8P8PmpkoQJexiI=; b=Wxv7uZoylN8ZEYkFx969RsPqsF9I5U3Ei+G0twsAGGdhesqvqi9k7v/l/SuP2BgtR3 gwACBLzWP6XsWPrxR3ILp70r+F+diXQRygplSRWWU65GZLAW6bkWgg2rZuibGVSXtUKS Zfkr3BdYhZmacmFWh+Q40sB9UEXX6Ny2OLvzmDMTxX++akYp+Oe64PWrGrsKhYpEryz1 +pnD5A4TM9QajiaizwLsUrR8Ifp1qaYGlrsEYjQ5WB82SCoowUgq2VwcWxGxLcsGIjAF jprFA2rVIS0T9W5UB7hc0mHqh+FNhUBAlNnfkRtgN5+4vb8Lsxx3Qg9ucOX6O89YKlun YoFg== X-Gm-Message-State: AOJu0YyvXFXOD1pymzXDg0yrnCizIo6j44sdOIKQAyVtSXD0QBPHDuv4 62khPUrCkAqd413d4qz0jxn+YW73XpxfJHxsEXVS0U/Fw0IpzIQaj2Q6N9Ya6n0aylkXSArSFyI LzgSQZ0fl8NgmHyMEzyl96zrkkZg= X-Google-Smtp-Source: AGHT+IFNsEz+y2HGsxGSd6aXApFTdrgxe+GUV1qVfrjePtcE/V0uIWzKoPEXYy13jRcr9pM9+pg3pEJBr3Nvdlw2Au4= X-Received: by 2002:a25:2f85:0:b0:dc2:65e9:7faa with SMTP id v127-20020a252f85000000b00dc265e97faamr3636289ybv.45.1705938498204; Mon, 22 Jan 2024 07:48:18 -0800 (PST) MIME-Version: 1.0 References: <20240120142752.1387725-1-hjl.tools@gmail.com> <20240120142752.1387725-2-hjl.tools@gmail.com> In-Reply-To: From: "H.J. Lu" Date: Mon, 22 Jan 2024 07:47:42 -0800 Message-ID: Subject: Re: [PATCH 1/2] x86: Add no_callee_saved_registers function attribute To: Hongtao Liu Cc: gcc-patches@gcc.gnu.org, ubizjak@gmail.com, hongtao.liu@intel.com, jh@suse.cz Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-3020.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_SHORT,KAM_STOCKGEN,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Sun, Jan 21, 2024 at 8:03=E2=80=AFPM Hongtao Liu wr= ote: > > On Sat, Jan 20, 2024 at 10:30=E2=80=AFPM H.J. Lu wr= ote: > > > > When an interrupt handler is implemented by an assembly stub which does= : > > > > 1. Save all registers. > > 2. Call a C function. > > 3. Restore all registers. > > 4. Return from interrupt. > > > > it is completely unnecessary to save and restore any registers in the C > > function called by the assembly stub, even if they would normally be > > callee-saved. > > > > Add no_callee_saved_registers function attribute, which is complementar= y > > to no_caller_saved_registers function attribute, to mark a function whi= ch > > doesn't have any callee-saved registers. Such a function won't save an= d > > restore any registers. Classify function call-saved register handling > > type with: > > > > 1. Default call-saved registers. > > 2. No caller-saved registers with no_caller_saved_registers attribute. > > 3. No callee-saved registers with no_callee_saved_registers attribute. > > > > Disallow sibcall if callee is a no_callee_saved_registers function > > and caller isn't a no_callee_saved_registers function. Otherwise, > > callee-saved registers won't be preserved. > > > > After a no_callee_saved_registers function is called, all registers may > > be clobbered. If the calling function isn't a no_callee_saved_register= s > > function, we need to preserve all registers which aren't used by functi= on > > calls. > > > > gcc/ > > > > PR target/103503 > > PR target/113312 > > * config/i386/i386-expand.cc (ix86_expand_call): Set > > call_no_callee_saved_registers to true when calling function > > with no_callee_saved_registers attribute. Replace > > no_caller_saved_registers check with call_saved_registers check= . > > * config/i386/i386-options.cc (ix86_set_func_type): Set > > call_saved_registers to TYPE_NO_CALLEE_SAVED_REGISTERS for > > noreturn function. Disallow no_callee_saved_registers with > > interrupt or no_caller_saved_registers attributes together. > > (ix86_set_current_function): Replace no_caller_saved_registers > > check with call_saved_registers check. > > (ix86_handle_no_caller_saved_registers_attribute): Renamed to .= .. > > (ix86_handle_call_saved_registers_attribute): This. > > (ix86_gnu_attributes): Add > > ix86_handle_call_saved_registers_attribute. > > * config/i386/i386.cc (ix86_conditional_register_usage): Replac= e > > no_caller_saved_registers check with call_saved_registers check= . > > (ix86_function_ok_for_sibcall): Don't allow callee with > > no_callee_saved_registers attribute when the calling function > > has callee-saved registers. > > (ix86_comp_type_attributes): Also check > > no_callee_saved_registers. > > (ix86_epilogue_uses): Replace no_caller_saved_registers check > > with call_saved_registers check. > > (ix86_hard_regno_scratch_ok): Likewise. > > (ix86_save_reg): Replace no_caller_saved_registers check with > > call_saved_registers check. Don't save any registers for > > TYPE_NO_CALLEE_SAVED_REGISTERS. Save all registers with > > TYPE_DEFAULT_CALL_SAVED_REGISTERS if function with > > no_callee_saved_registers attribute is called. > > (find_drap_reg): Replace no_caller_saved_registers check with > > call_saved_registers check. > > * config/i386/i386.h (call_saved_registers_type): New enum. > > (machine_function): Replace no_caller_saved_registers with > > call_saved_registers. Add call_no_callee_saved_registers. > > * doc/extend.texi: Document no_callee_saved_registers attribute= . > > > > gcc/testsuite/ > > > > PR target/103503 > > PR target/113312 > > * gcc.dg/torture/no-callee-saved-run-1a.c: New file. > > * gcc.dg/torture/no-callee-saved-run-1b.c: Likewise. > > * gcc.target/i386/no-callee-saved-1.c: Likewise. > > * gcc.target/i386/no-callee-saved-2.c: Likewise. > > * gcc.target/i386/no-callee-saved-3.c: Likewise. > > * gcc.target/i386/no-callee-saved-4.c: Likewise. > > * gcc.target/i386/no-callee-saved-5.c: Likewise. > > * gcc.target/i386/no-callee-saved-6.c: Likewise. > > * gcc.target/i386/no-callee-saved-7.c: Likewise. > > * gcc.target/i386/no-callee-saved-8.c: Likewise. > > * gcc.target/i386/no-callee-saved-9.c: Likewise. > > * gcc.target/i386/no-callee-saved-10.c: Likewise. > > * gcc.target/i386/no-callee-saved-11.c: Likewise. > > * gcc.target/i386/no-callee-saved-12.c: Likewise. > > * gcc.target/i386/no-callee-saved-13.c: Likewise. > > * gcc.target/i386/no-callee-saved-14.c: Likewise. > > * gcc.target/i386/no-callee-saved-15.c: Likewise. > > * gcc.target/i386/no-callee-saved-16.c: Likewise. > > * gcc.target/i386/no-callee-saved-17.c: Likewise. > > * gcc.target/i386/no-callee-saved-18.c: Likewise. > > --- > > gcc/config/i386/i386-expand.cc | 72 ++++++++++++++++--- > > gcc/config/i386/i386-options.cc | 49 +++++++++---- > > gcc/config/i386/i386.cc | 70 ++++++++++++++---- > > gcc/config/i386/i386.h | 20 +++++- > > gcc/doc/extend.texi | 8 +++ > > .../gcc.dg/torture/no-callee-saved-run-1a.c | 23 ++++++ > > .../gcc.dg/torture/no-callee-saved-run-1b.c | 59 +++++++++++++++ > > .../gcc.target/i386/no-callee-saved-1.c | 30 ++++++++ > > .../gcc.target/i386/no-callee-saved-10.c | 46 ++++++++++++ > > .../gcc.target/i386/no-callee-saved-11.c | 11 +++ > > .../gcc.target/i386/no-callee-saved-12.c | 10 +++ > > .../gcc.target/i386/no-callee-saved-13.c | 16 +++++ > > .../gcc.target/i386/no-callee-saved-14.c | 16 +++++ > > .../gcc.target/i386/no-callee-saved-15.c | 17 +++++ > > .../gcc.target/i386/no-callee-saved-16.c | 16 +++++ > > .../gcc.target/i386/no-callee-saved-17.c | 16 +++++ > > .../gcc.target/i386/no-callee-saved-18.c | 51 +++++++++++++ > > .../gcc.target/i386/no-callee-saved-2.c | 30 ++++++++ > > .../gcc.target/i386/no-callee-saved-3.c | 8 +++ > > .../gcc.target/i386/no-callee-saved-4.c | 8 +++ > > .../gcc.target/i386/no-callee-saved-5.c | 11 +++ > > .../gcc.target/i386/no-callee-saved-6.c | 12 ++++ > > .../gcc.target/i386/no-callee-saved-7.c | 49 +++++++++++++ > > .../gcc.target/i386/no-callee-saved-8.c | 50 +++++++++++++ > > .../gcc.target/i386/no-callee-saved-9.c | 49 +++++++++++++ > > 25 files changed, 709 insertions(+), 38 deletions(-) > > create mode 100644 gcc/testsuite/gcc.dg/torture/no-callee-saved-run-1a= .c > > create mode 100644 gcc/testsuite/gcc.dg/torture/no-callee-saved-run-1b= .c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-1.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-10.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-11.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-12.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-13.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-14.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-15.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-16.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-17.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-18.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-2.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-3.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-4.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-5.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-6.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-7.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-8.c > > create mode 100644 gcc/testsuite/gcc.target/i386/no-callee-saved-9.c > > > > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expa= nd.cc > > index 52754e114f4..c0c7c697440 100644 > > --- a/gcc/config/i386/i386-expand.cc > > +++ b/gcc/config/i386/i386-expand.cc > > @@ -9739,17 +9739,41 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx c= allarg1, > > rtx use =3D NULL, call; > > unsigned int vec_len =3D 0. > > tree fndecl; > > + bool call_no_callee_saved_registers =3D false; > > > > if (GET_CODE (XEXP (fnaddr, 0)) =3D=3D SYMBOL_REF) > > { > > fndecl =3D SYMBOL_REF_DECL (XEXP (fnaddr, 0)); > > - if (fndecl > > - && (lookup_attribute ("interrupt", > > - TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))) > > - error ("interrupt service routine cannot be called directly"); > > + if (fndecl) > > + { > > + if (lookup_attribute ("interrupt", > > + TYPE_ATTRIBUTES (TREE_TYPE (fndecl)))) > > + error ("interrupt service routine cannot be called directly= "); > > + else if (lookup_attribute ("no_callee_saved_registers", > > + TYPE_ATTRIBUTES (TREE_TYPE (fndecl= )))) > > + { > > + cfun->machine->call_no_callee_saved_registers =3D true; > > + call_no_callee_saved_registers =3D true; > > + } > > + } > > } > > else > > - fndecl =3D NULL_TREE; > > + { > > + if (MEM_P (fnaddr)) > > + { > > + tree mem_expr =3D MEM_EXPR (fnaddr); > > + if (mem_expr !=3D nullptr > > + && TREE_CODE (mem_expr) =3D=3D MEM_REF > > + && lookup_attribute ("no_callee_saved_registers", > > + TYPE_ATTRIBUTES (TREE_TYPE (mem_expr= )))) > > + { > > + cfun->machine->call_no_callee_saved_registers =3D true; > > + call_no_callee_saved_registers =3D true; > > + } > > + } > > + > > + fndecl =3D NULL_TREE; > > + } > > > > if (pop =3D=3D const0_rtx) > > pop =3D NULL; > > @@ -9884,13 +9908,18 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx c= allarg1, > > vec[vec_len++] =3D pop; > > } > > > > - if (cfun->machine->no_caller_saved_registers > > + static const char ix86_call_used_regs[] =3D CALL_USED_REGISTERS; > > + > > + char clobbered_registers[FIRST_PSEUDO_REGISTER]; > > + memset (clobbered_registers, 0, sizeof (clobbered_registers)); > > + > > + if ((cfun->machine->call_saved_registers > > + =3D=3D TYPE_NO_CALLER_SAVED_REGISTERS) > > && (!fndecl > > || (!TREE_THIS_VOLATILE (fndecl) > > && !lookup_attribute ("no_caller_saved_registers", > > TYPE_ATTRIBUTES (TREE_TYPE (fndecl)= ))))) > > { > > - static const char ix86_call_used_regs[] =3D CALL_USED_REGISTERS; > > bool is_64bit_ms_abi =3D (TARGET_64BIT > > && ix86_function_abi (fndecl) =3D=3D MS_A= BI); > > char c_mask =3D CALL_USED_REGISTERS_MASK (is_64bit_ms_abi); > > @@ -9903,8 +9932,11 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx ca= llarg1, > > || (ix86_call_used_regs[i] & c_mask)) > > && !STACK_REGNO_P (i) > > && !MMX_REGNO_P (i)) > > - clobber_reg (&use, > > - gen_rtx_REG (GET_MODE (regno_reg_rtx[i]), i)); > > + { > > + clobber_reg (&use, > > + gen_rtx_REG (GET_MODE (regno_reg_rtx[i]), i)); > > + clobbered_registers[i] =3D 1; > > + } > > } > > else if (TARGET_64BIT_MS_ABI > > && (!callarg2 || INTVAL (callarg2) !=3D -2)) > > @@ -9917,6 +9949,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx cal= larg1, > > machine_mode mode =3D SSE_REGNO_P (regno) ? TImode : DImode; > > > > clobber_reg (&use, gen_rtx_REG (mode, regno)); > > + clobbered_registers[i] =3D 1; > > } > > > > /* Set here, but it may get cleared later. */ > > @@ -9953,6 +9986,27 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx ca= llarg1, > > resolver could be used which clobbers R11 and R10. */ > > clobber_reg (&use, gen_rtx_REG (DImode, R11_REG)); > > clobber_reg (&use, gen_rtx_REG (DImode, R10_REG)); > > + clobbered_registers[R11_REG] =3D 1; > > + clobbered_registers[R10_REG] =3D 1; > > + } > > + > > + if (call_no_callee_saved_registers) > > + { > > + /* After calling a no_callee_saved_registers function, all > > + registers may be clobbered. Clobber all registers that are > > + not clobbered yet and not used by the callee. */ > > + bool is_64bit_ms_abi =3D (TARGET_64BIT > > + && ix86_function_abi (fndecl) =3D=3D MS_A= BI); > > + char c_mask =3D CALL_USED_REGISTERS_MASK (is_64bit_ms_abi); > > + for (int i =3D 0; i < FIRST_PSEUDO_REGISTER; i++) > > + if (!fixed_regs[i] > > + && !clobbered_registers[i] > It seems to me clobbered_registers is only used here which seems > redundant, remove !clobbered_registers[i] should also be fine? > You are right. Here is the v2 patch set: https://patchwork.sourceware.org/project/gcc/list/?series=3D30050 Changes in v2: 1. Rebase against commit f9df00340e3 2. Don't add redundant clobbered_registers check in ix86_expand_call. Thanks. --=20 H.J.