From patchwork Fri Jan 9 18:16:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 4597 Received: (qmail 4666 invoked by alias); 9 Jan 2015 18:17:41 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 4542 invoked by uid 89); 9 Jan 2015 18:17:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qg0-f42.google.com X-Received: by 10.140.108.74 with SMTP id i68mr27742572qgf.35.1420827455869; Fri, 09 Jan 2015 10:17:35 -0800 (PST) From: Richard Henderson To: libc-alpha@sourceware.org Cc: roland@hack.frob.com Subject: [PATCH B2/2] Use builtin_unreachable in assert Date: Fri, 9 Jan 2015 10:16:59 -0800 Message-Id: <1420827419-18655-3-git-send-email-rth@twiddle.net> In-Reply-To: <1420827419-18655-1-git-send-email-rth@twiddle.net> References: <1420827419-18655-1-git-send-email-rth@twiddle.net> Finally, use __builtin_unreachable to tell the compiler about impossible paths. The amount of code change with gcc 4.9.2 is enormous, and is usually difficult to tell whether the change is definitely for the better. Most of the time the difference begins with a branch test being reversed, after which none of the remainder of the code lines up. I did see one definitely positive case, gconv_builtin.os, which is small enough to evaluate easily: - 20: 48 8b 75 00 mov 0x0(%rbp),%rsi - 24: 4c 89 f7 mov %r14,%rdi - 27: e8 00 00 00 00 callq 2c <__gconv_get_builtin_trans+0x2c> - 28: R_X86_64_PLT32 __GI_strcmp-0x4 - 2c: 85 c0 test %eax,%eax - 2e: 74 0e je 3e <__gconv_get_builtin_trans+0x3e> - 30: 48 83 c3 01 add $0x1,%rbx - 34: 48 83 c5 20 add $0x20,%rbp - 38: 48 83 fb 0c cmp $0xc,%rbx - 3c: 75 e2 jne 20 <__gconv_get_builtin_trans+0x20> + 20: 48 83 c5 01 add $0x1,%rbp + 24: 48 83 c3 20 add $0x20,%rbx + 28: 48 8b 33 mov (%rbx),%rsi + 2b: 4c 89 f7 mov %r14,%rdi + 2e: e8 00 00 00 00 callq 33 <__gconv_get_builtin_trans+0x33> + 2f: R_X86_64_PLT32 __GI_strcmp-0x4 + 33: 85 c0 test %eax,%eax + 35: 75 e9 jne 20 <__gconv_get_builtin_trans+0x20> The assert following the loop results in the elimination of the loop comparison, leaving only the strcmp test controlling loop exit. In leiu of investigaing all such, here's the final size comparison: text data bss dec hex filename 1623772 20968 18160 1662900 195fb4 bld-A1/libc.so 1623788 20968 18160 1662916 195fc4 bld-B1/libc.so 1623604 20968 18160 1662732 195f0c bld-B2/libc.so r~ PS: Note that __builtin_unreachable was introduced in gcc 4.5, therefore no version test is required. * include/assert.h (assert): Use __builtin_unreachable. (assert_perror): Use __builtin_unreachable. --- include/assert.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/assert.h b/include/assert.h index d7e2759..bd3ef51 100644 --- a/include/assert.h +++ b/include/assert.h @@ -29,6 +29,6 @@ hidden_proto (__assert_perror_fail) #ifdef NDEBUG # undef assert # undef assert_perror -# define assert(expr) ((void)(0 && (expr))) -# define assert_perror(errnum) ((void)(0 && (errnum))) +# define assert(e) ((e) ? (void)0 : __builtin_unreachable ()) +# define assert_perror(e) (!(e) ? (void)0 : __builtin_unreachable ()) #endif