From patchwork Thu Sep 30 10:19:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 45600 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A704D3858422 for ; Thu, 30 Sep 2021 10:20:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A704D3858422 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1632997203; bh=kAVhNaOFfaiI1jNpSKBdA+CHXbiwh24G/AxLpPvf98Q=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=YyDN2VuJvA5vTGasskGpTb92pFuRYFNx70HS4v6yUcI0Q5IjkFc47QenHpH3RQMWm HbwREkc5QV2NKTLUQ63xqVXkxB/LyPtKWX31/vb2KANBCCyYdFH4etHBoKuK1nT6MB WoW3TpH2IJhPvdAxJeMBcTE0lE35g9JDYwWT2A18= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 9EDD33858415 for ; Thu, 30 Sep 2021 10:19:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9EDD33858415 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-51-8EnvUq_QOSKeix4Npa86pA-1; Thu, 30 Sep 2021 06:19:39 -0400 X-MC-Unique: 8EnvUq_QOSKeix4Npa86pA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id CBA9210247A9 for ; Thu, 30 Sep 2021 10:19:38 +0000 (UTC) Received: from localhost (unknown [10.33.36.42]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4D3535D9CA for ; Thu, 30 Sep 2021 10:19:38 +0000 (UTC) Date: Thu, 30 Sep 2021 11:19:37 +0100 To: libc-alpha@sourceware.org Subject: [PATCH] Add alloc_align attribute to memalign et al Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-13.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jonathan Wakely via Libc-alpha From: Jonathan Wakely Reply-To: Jonathan Wakely Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" commit ec065256995fc8756972291a79011320fa180649 Author: Jonathan Wakely Date: Thu Sep 30 10:48:40 2021 +0100 Add alloc_align attribute to memalign et al GCC 4.9.0 added the alloc_align attribute to say that a function argument specifies the alignment of the returned pointer. Clang supports the attribute too. Using the attribute can allow a compiler to generate better code if it knows the returned pointer has a minimum alignment. See https://gcc.gnu.org/PR60092 for more details. GCC implicitly knows the semantics of aligned_alloc and posix_memalign, but not the obsolete memalign. As a result, GCC generates worse code when memalign is used, compared to aligned_alloc. Clang knows about aligned_alloc and memalign, but not posix_memalign. This change adds a new __attribute_alloc_align__ macro to and then uses it on memalign (where it helps GCC) and aligned_alloc (where GCC and Clang already know the semantics, but it doesn't hurt) and xposix_memalign. It can't be used on posix_memalign because that doesn't return a pointer (the allocated pointer is returned via a void** parameter instead). Unlike the alloc_size attribute, alloc_align only allows a single argument. That means the new __attribute_alloc_align__ macro doesn't really need to be used with double parentheses to protect a comma between its arguments. For consistency with __attribute_alloc_size__ this patch defines it the same way, so that double parentheses are required. Signed-off-by: Jonathan Wakely diff --git a/malloc/malloc.h b/malloc/malloc.h index 2df0b38050..78d3ad82b2 100644 --- a/malloc/malloc.h +++ b/malloc/malloc.h @@ -64,8 +64,8 @@ extern void free (void *__ptr) __THROW; /* Allocate SIZE bytes allocated to ALIGNMENT bytes. */ extern void *memalign (size_t __alignment, size_t __size) - __THROW __attribute_malloc__ __attribute_alloc_size__ ((2)) __wur - __attr_dealloc_free; + __THROW __attribute_malloc__ __attribute_alloc_align__ ((1)) + __attribute_alloc_size__ ((2)) __wur __attr_dealloc_free; /* Allocate SIZE bytes on a page boundary. */ extern void *valloc (size_t __size) __THROW __attribute_malloc__ diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h index 4dac9d264d..7b2a9bd3b0 100644 --- a/misc/sys/cdefs.h +++ b/misc/sys/cdefs.h @@ -243,6 +243,15 @@ # define __attribute_alloc_size__(params) /* Ignore. */ #endif +/* Tell the compiler which argument to an allocation function + indicates the alignment of the allocation. */ +#if __GNUC_PREREQ (4, 9) || __glibc_has_attribute (__alloc_align__) +# define __attribute_alloc_align__(param) \ + __attribute__ ((__alloc_align__ param)) +#else +# define __attribute_alloc_align__(param) /* Ignore. */ +#endif + /* At some point during the gcc 2.96 development the `pure' attribute for functions was introduced. We don't want to use it unconditionally (although this would be possible) since it generates warnings. */ diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h index 0481c12355..45df9a12c6 100644 --- a/stdlib/stdlib.h +++ b/stdlib/stdlib.h @@ -589,7 +589,8 @@ extern int posix_memalign (void **__memptr, size_t __alignment, size_t __size) #ifdef __USE_ISOC11 /* ISO C variant of aligned allocation. */ extern void *aligned_alloc (size_t __alignment, size_t __size) - __THROW __attribute_malloc__ __attribute_alloc_size__ ((2)) __wur; + __THROW __attribute_malloc__ __attribute_alloc_align__ ((1)) + __attribute_alloc_size__ ((2)) __wur; #endif /* Abort execution and generate a core-dump. */ diff --git a/support/support.h b/support/support.h index 837a806531..91c7178f06 100644 --- a/support/support.h +++ b/support/support.h @@ -98,8 +98,8 @@ extern void *xrealloc (void *o, size_t n) extern char *xstrdup (const char *) __attribute_malloc__ __attr_dealloc_free __returns_nonnull; void *xposix_memalign (size_t alignment, size_t n) - __attribute_malloc__ __attribute_alloc_size__ ((2)) __attr_dealloc_free - __returns_nonnull; + __attribute_malloc__ __attribute_alloc_align__ ((1)) + __attribute_alloc_size__ ((2)) __attr_dealloc_free __returns_nonnull; char *xasprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2), malloc)) __attr_dealloc_free __returns_nonnull; This change was inspired by the observation in https://twitter.com/taviso/status/1443335323702816773 that GCC produces worse code for memalign than for aligned_alloc. Tested x86_64-pc-linux-gnu. OK to push?