This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH B2/2] Use builtin_unreachable in assert
- From: Richard Henderson <rth at twiddle dot net>
- To: libc-alpha at sourceware dot org
- Cc: roland at hack dot frob dot com
- Date: Fri, 9 Jan 2015 10:16:59 -0800
- Subject: [PATCH B2/2] Use builtin_unreachable in assert
- Authentication-results: sourceware.org; auth=none
- References: <1420827419-18655-1-git-send-email-rth at twiddle dot 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
--
2.1.0