From patchwork Sun Dec 5 22:01:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 48520 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 3D8D93858430 for ; Sun, 5 Dec 2021 22:02:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3D8D93858430 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638741743; bh=F81Yu4L4SYDf/WvwX22FrXO2vHW14XJrdhW7x52Ofds=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Fl4t7U1n+uSMpZGnuiel7poHYzUa5EP57GFQLkdecKH+gr0Jh1Wj5XxZOIrd46tMK 0rgr1oqcWhX9Pr2IdqPZxD7j7mwwGjs5Aad6ahA01HP3Kvt9g+M0ZJLQJTCkBMmQJS xPPcKM0IzuOY8Ei7KNXBCvxdgqN+Wy7rsNaWkLMY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 69A1E385AC08 for ; Sun, 5 Dec 2021 22:01:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 69A1E385AC08 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1C4E4113E for ; Sun, 5 Dec 2021 14:01:53 -0800 (PST) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.88]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B596E3F5A1 for ; Sun, 5 Dec 2021 14:01:52 -0800 (PST) To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH] gimple: Optimise inlined gimple_seq_last Date: Sun, 05 Dec 2021 22:01:51 +0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Richard Sandiford via Gcc-patches From: Richard Sandiford Reply-To: Richard Sandiford Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" In self-compilations, GCC doesn't realise that gimple_seq_last always returns nonnull when the argument is nonnull. Although it's a small thing in itself, the function is used (indirectly) many times and the extra null checks bloat what are otherwise simple loops. This patch adds an optimisation hint to tell the compiler that s && !s->prev is impossible. This gives a small (<1%) but measureable improvement in compile time. The original intention was to make a loop small enough that it could be turned into an inline function. The form of assertion in the patch: __extension__ ({ if (!(EXPR)) __builtin_unreachable (); (void) 0; }) seems to work more reliably than the form used by release-checking gcc_asserts: ((void)(__builtin_expect (!(EXPR), 0) ? __builtin_unreachable (), 0 : 0)) For that reason, I wondered about making gcc_assert use the new macro too. However, gcc_assert is currently inconsistent: it preserves side-effects even in release compilers when compiled with GCC, but it doesn't when compiled by other compilers. This difference dates back to 2013 (g:2df77822ee0974d84b2) and it looks like we now have several gcc_asserts that assume that side effects will be preserved. It therefore seemed better to deal with that separately. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Richard gcc/ * system.h (optimization_assert): New macro. * gimple.h (gimple_seq_last): Use it to assert that s->prev is never null. --- gcc/gimple.h | 2 ++ gcc/system.h | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/gcc/gimple.h b/gcc/gimple.h index f7fdefc5362..8162c1ea507 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1723,6 +1723,8 @@ gimple_seq_first_stmt_as_a_bind (gimple_seq s) static inline gimple_seq_node gimple_seq_last (gimple_seq s) { + /* Helps to avoid a double branch in callers. */ + optimization_assert (!s || s->prev); return s ? s->prev : NULL; } diff --git a/gcc/system.h b/gcc/system.h index 4ac656c9c3c..6e27b3270b9 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -778,6 +778,16 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN ATTRIBUTE_COLD; #define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__) +/* Tell the compiler of GCC that EXPR is known to be true. This is purely + an optimization hint and EXPR must not have any side effects. */ +#if (GCC_VERSION >= 4005) +#define optimization_assert(EXPR) \ + __extension__ ({ if (!(EXPR)) __builtin_unreachable (); (void) 0; }) +#else +/* Include EXPR, so that unused variable warnings do not occur. */ +#define optimization_assert(EXPR) ((void)(0 && (EXPR))) +#endif + /* Use gcc_assert(EXPR) to test invariants. */ #if ENABLE_ASSERT_CHECKING #define gcc_assert(EXPR) \