This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH B2/2] Use builtin_unreachable in assert


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]