[PATCH 8/8] Use __builtin_constant_p to determine if we can use lswapl

Matt Turner mattst88 at gmail.com
Tue Aug 16 19:58:27 PDT 2011


If the address of the swapped memory location is known at compile time,
we can check its alignment at no runtime cost and use lswapl instead.

           text   data    bss      dec     hex  filename
before: 1872820  52136  78040  2002996  1e9034  hw/xfree86/Xorg
after:  1864396  52136  78040  1994572  1e6f4c  hw/xfree86/Xorg

bswap instructions: 131 ->  308 (used in lswapl)
rol instructions:   943 -> 1174 (used in lswaps)

Signed-off-by: Matt Turner <mattst88 at gmail.com>
---
 include/misc.h |   15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/misc.h b/include/misc.h
index cfe734f..b340591 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -270,6 +270,11 @@ void __attribute__((error("wrong sized variable passed to swap"))) wrong_size(vo
 static inline void wrong_size(void)
 {
 }
+
+static inline void __builtin_constant_p(int x)
+{
+	return 0;
+}
 #endif
 
 /* byte swap a 32-bit value */
@@ -286,7 +291,10 @@ static inline void swap_uint32(uint32_t *x)
 #define swapl(x) do { \
 		if (sizeof(*(x)) != 4) \
 			wrong_size(); \
-		swap_uint32((uint32_t *)(x)); \
+		if (__builtin_constant_p((uintptr_t)(x) & 3) && ((uintptr_t)(x) & 3) == 0) \
+			*(x) = lswapl(*(x)); \
+		else \
+			swap_uint32((uint32_t *)(x)); \
 	} while (0)
 
 /* byte swap a 16-bit value */
@@ -300,7 +308,10 @@ static inline void swap_uint16(uint16_t *x)
 #define swaps(x) do { \
 		if (sizeof(*(x)) != 2) \
 			wrong_size(); \
-		swap_uint16((uint16_t *)(x)); \
+		if (__builtin_constant_p((uintptr_t)(x) & 1) && ((uintptr_t)(x) & 1) == 0) \
+			*(x) = lswaps(*(x)); \
+		else \
+			swap_uint16((uint16_t *)(x)); \
 	} while (0)
 
 /* copy 32-bit value from src to dst byteswapping on the way */
-- 
1.7.3.4



More information about the xorg-devel mailing list