From: "H. Peter Anvin" <hpa@zytor.com>

Declaring a function to return a const scalar value is pretty meaningless. 
These functions are really trying to say that they don't alter any external
state.

Fix that up by using __attribute__((const)), if the compiler supports that.


 include/asm-cris/arch-v10/byteorder.h |    5 +++--
 include/asm-i386/byteorder.h          |   20 ++++++--------------
 include/asm-ia64/byteorder.h          |    7 ++++---
 include/asm-m68k/byteorder.h          |    3 ++-
 include/asm-parisc/byteorder.h        |   11 ++++++-----
 include/asm-ppc/byteorder.h           |    5 +++--
 include/asm-ppc64/byteorder.h         |    7 ++++---
 include/asm-s390/byteorder.h          |   13 +++++++------
 include/asm-sh/byteorder.h            |    5 +++--
 include/asm-v850/byteorder.h          |    5 +++--
 include/asm-x86_64/byteorder.h        |    5 +++--
 include/linux/byteorder/swab.h        |    8 +++++---
 include/linux/compiler-gcc+.h         |    1 +
 include/linux/compiler-gcc2.h         |    1 +
 include/linux/compiler-gcc3.h         |    1 +
 include/linux/compiler.h              |   18 ++++++++++++++++++
 16 files changed, 70 insertions(+), 45 deletions(-)

diff -puN include/asm-cris/arch-v10/byteorder.h~const-fixes include/asm-cris/arch-v10/byteorder.h
--- 25/include/asm-cris/arch-v10/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-cris/arch-v10/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -2,20 +2,21 @@
 #define _CRIS_ARCH_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 /* we just define these two (as we can do the swap in a single
  * asm instruction in CRIS) and the arch-independent files will put
  * them together into ntohl etc.
  */
 
-extern __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+extern __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 	__asm__ ("swapwb %0" : "=r" (x) : "0" (x));
   
 	return(x);
 }
 
-extern __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+extern __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
 {
 	__asm__ ("swapb %0" : "=r" (x) : "0" (x));
 	
diff -puN include/asm-i386/byteorder.h~const-fixes include/asm-i386/byteorder.h
--- 25/include/asm-i386/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-i386/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -2,6 +2,7 @@
 #define _I386_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 
@@ -10,7 +11,7 @@
 #include <linux/config.h>
 #endif
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 #ifdef CONFIG_X86_BSWAP
 	__asm__("bswap %0" : "=r" (x) : "0" (x));
@@ -24,18 +25,7 @@ static __inline__ __const__ __u32 ___arc
 	return x;
 }
 
-/* gcc should generate this for open coded C now too. May be worth switching to 
-   it because inline assembly cannot be scheduled. -AK */
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
-{
-	__asm__("xchgb %b0,%h0"		/* swap bytes		*/
-		: "=q" (x)
-		:  "0" (x));
-		return x;
-}
-
-
-static inline __u64 ___arch__swab64(__u64 val) 
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val)
 { 
 	union { 
 		struct { __u32 a,b; } s;
@@ -54,9 +44,11 @@ static inline __u64 ___arch__swab64(__u6
 	return v.u;	
 } 
 
+/* Do not define swab16.  Gcc is smart enough to recognize "C" version and
+   convert it into rotation or exhange.  */
+
 #define __arch__swab64(x) ___arch__swab64(x)
 #define __arch__swab32(x) ___arch__swab32(x)
-#define __arch__swab16(x) ___arch__swab16(x)
 
 #define __BYTEORDER_HAS_U64__
 
diff -puN include/asm-ia64/byteorder.h~const-fixes include/asm-ia64/byteorder.h
--- 25/include/asm-ia64/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-ia64/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -8,8 +8,9 @@
 
 #include <asm/types.h>
 #include <asm/intrinsics.h>
+#include <linux/compiler.h>
 
-static __inline__ __const__ __u64
+static __inline__ __attribute_const__ __u64
 __ia64_swab64 (__u64 x)
 {
 	__u64 result;
@@ -18,13 +19,13 @@ __ia64_swab64 (__u64 x)
 	return result;
 }
 
-static __inline__ __const__ __u32
+static __inline__ __attribute_const__ __u32
 __ia64_swab32 (__u32 x)
 {
 	return __ia64_swab64(x) >> 32;
 }
 
-static __inline__ __const__ __u16
+static __inline__ __attribute_const__ __u16
 __ia64_swab16(__u16 x)
 {
 	return __ia64_swab64(x) >> 48;
diff -puN include/asm-m68k/byteorder.h~const-fixes include/asm-m68k/byteorder.h
--- 25/include/asm-m68k/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-m68k/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -2,10 +2,11 @@
 #define _M68K_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 val)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val)
 {
 	__asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val));
 	return val;
diff -puN include/asm-parisc/byteorder.h~const-fixes include/asm-parisc/byteorder.h
--- 25/include/asm-parisc/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-parisc/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -2,10 +2,11 @@
 #define _PARISC_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
 {
 	__asm__("dep %0, 15, 8, %0\n\t"		/* deposit 00ab -> 0bab */
 		"shd %%r0, %0, 8, %0"		/* shift 000000ab -> 00ba */
@@ -14,7 +15,7 @@ static __inline__ __const__ __u16 ___arc
 	return x;
 }
 
-static __inline__ __const__ __u32 ___arch__swab24(__u32 x)
+static __inline__ __attribute_const__ __u32 ___arch__swab24(__u32 x)
 {
 	__asm__("shd %0, %0, 8, %0\n\t"		/* shift xabcxabc -> cxab */
 		"dep %0, 15, 8, %0\n\t"		/* deposit cxab -> cbab */
@@ -24,7 +25,7 @@ static __inline__ __const__ __u32 ___arc
 	return x;
 }
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 	unsigned int temp;
 	__asm__("shd %0, %0, 16, %1\n\t"	/* shift abcdabcd -> cdab */
@@ -47,7 +48,7 @@ static __inline__ __const__ __u32 ___arc
 **      HSHR    67452301 -> *6*4*2*0 into %0
 **      OR      %0 | %1  -> 76543210 into %0 (all done!)
 */
-static __inline__ __const__ __u64 ___arch__swab64(__u64 x) {
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) {
 	__u64 temp;
 	__asm__("permh,3210 %0, %0\n\t"
 		"hshl %0, 8, %1\n\t"
@@ -60,7 +61,7 @@ static __inline__ __const__ __u64 ___arc
 #define __arch__swab64(x) ___arch__swab64(x)
 #define __BYTEORDER_HAS_U64__
 #elif !defined(__STRICT_ANSI__)
-static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
 {
 	__u32 t1 = ___arch__swab32((__u32) x);
 	__u32 t2 = ___arch__swab32((__u32) (x >> 32));
diff -puN include/asm-ppc64/byteorder.h~const-fixes include/asm-ppc64/byteorder.h
--- 25/include/asm-ppc64/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-ppc64/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -9,6 +9,7 @@
  */
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 #ifdef __KERNEL__
@@ -40,7 +41,7 @@ static __inline__ void st_le32(volatile 
 }
 
 #if 0
-static __inline__ __const__ __u16 ___arch__swab16(__u16 value)
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
 {
 	__u16 result;
 
@@ -50,7 +51,7 @@ static __inline__ __const__ __u16 ___arc
 	return result;
 }
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 value)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
 {
 	__u32 result;
 
@@ -62,7 +63,7 @@ static __inline__ __const__ __u32 ___arc
 	return result;
 }
 
-static __inline__ __const__ __u64 ___arch__swab64(__u64 value)
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value)
 {
 	__u64 result;
 #error implement me
diff -puN include/asm-ppc/byteorder.h~const-fixes include/asm-ppc/byteorder.h
--- 25/include/asm-ppc/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-ppc/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -2,6 +2,7 @@
 #define _PPC_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 #ifdef __KERNEL__
@@ -32,7 +33,7 @@ extern __inline__ void st_le32(volatile 
 	__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
 }
 
-static __inline__ __const__ __u16 ___arch__swab16(__u16 value)
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
 {
 	__u16 result;
 
@@ -40,7 +41,7 @@ static __inline__ __const__ __u16 ___arc
 	return result;
 }
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 value)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
 {
 	__u32 result;
 
diff -puN include/asm-s390/byteorder.h~const-fixes include/asm-s390/byteorder.h
--- 25/include/asm-s390/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-s390/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -10,11 +10,12 @@
  */
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 
 #ifdef __s390x__
-static __inline__ __const__ __u64 ___arch__swab64p(__u64 *x)
+static __inline__ __attribute_const__ __u64 ___arch__swab64p(__u64 *x)
 {
 	__u64 result;
 
@@ -24,7 +25,7 @@ static __inline__ __const__ __u64 ___arc
 	return result;
 }
 
-static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
 {
 	__u64 result;
 
@@ -40,7 +41,7 @@ static __inline__ void ___arch__swab64s(
 }
 #endif /* __s390x__ */
 
-static __inline__ __const__ __u32 ___arch__swab32p(__u32 *x)
+static __inline__ __attribute_const__ __u32 ___arch__swab32p(__u32 *x)
 {
 	__u32 result;
 	
@@ -58,7 +59,7 @@ static __inline__ __const__ __u32 ___arc
 	return result;
 }
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 #ifndef __s390x__
 	return ___arch__swab32p(&x);
@@ -77,7 +78,7 @@ static __inline__ void ___arch__swab32s(
 	*x = ___arch__swab32p(x);
 }
 
-static __inline__ __const__ __u16 ___arch__swab16p(__u16 *x)
+static __inline__ __attribute_const__ __u16 ___arch__swab16p(__u16 *x)
 {
 	__u16 result;
 	
@@ -93,7 +94,7 @@ static __inline__ __const__ __u16 ___arc
 	return result;
 }
 
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
 {
 	return ___arch__swab16p(&x);
 }
diff -puN include/asm-sh/byteorder.h~const-fixes include/asm-sh/byteorder.h
--- 25/include/asm-sh/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-sh/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -6,8 +6,9 @@
  */
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 	__asm__("swap.b	%0, %0\n\t"
 		"swap.w %0, %0\n\t"
@@ -17,7 +18,7 @@ static __inline__ __const__ __u32 ___arc
 	return x;
 }
 
-static __inline__ __const__ __u16 ___arch__swab16(__u16 x)
+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
 {
 	__asm__("swap.b %0, %0"
 		: "=r" (x)
diff -puN include/asm-v850/byteorder.h~const-fixes include/asm-v850/byteorder.h
--- 25/include/asm-v850/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-v850/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -15,17 +15,18 @@
 #define __V850_BYTEORDER_H__
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 
-static __inline__ __const__ __u32 ___arch__swab32 (__u32 word)
+static __inline__ __attribute_const__ __u32 ___arch__swab32 (__u32 word)
 {
 	__u32 res;
 	__asm__ ("bsw %1, %0" : "=r" (res) : "r" (word));
 	return res;
 }
 
-static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word)
+static __inline__ __attribute_const__ __u16 ___arch__swab16 (__u16 half_word)
 {
 	__u16 res;
 	__asm__ ("bsh %1, %0" : "=r" (res) : "r" (half_word));
diff -puN include/asm-x86_64/byteorder.h~const-fixes include/asm-x86_64/byteorder.h
--- 25/include/asm-x86_64/byteorder.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/asm-x86_64/byteorder.h	2003-12-21 23:45:22.000000000 -0800
@@ -2,16 +2,17 @@
 #define _X86_64_BYTEORDER_H
 
 #include <asm/types.h>
+#include <linux/compiler.h>
 
 #ifdef __GNUC__
 
-static __inline__ __const__ __u64 ___arch__swab64(__u64 x)
+static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x)
 {
 	__asm__("bswapq %0" : "=r" (x) : "0" (x));
 	return x;
 }
 
-static __inline__ __const__ __u32 ___arch__swab32(__u32 x)
+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
 	__asm__("bswapl %0" : "=r" (x) : "0" (x));
 	return x;
diff -puN include/linux/byteorder/swab.h~const-fixes include/linux/byteorder/swab.h
--- 25/include/linux/byteorder/swab.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/linux/byteorder/swab.h	2003-12-21 23:45:22.000000000 -0800
@@ -15,6 +15,8 @@
  *
  */
 
+#include <linux/compiler.h>
+
 /* casts are necessary for constants, because we never know how for sure
  * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
  */
@@ -128,7 +130,7 @@
 #endif /* OPTIMIZE */
 
 
-static __inline__ __const__ __u16 __fswab16(__u16 x)
+static __inline__ __attribute_const__ __u16 __fswab16(__u16 x)
 {
 	return __arch__swab16(x);
 }
@@ -141,7 +143,7 @@ static __inline__ void __swab16s(__u16 *
 	__arch__swab16s(addr);
 }
 
-static __inline__ __const__ __u32 __fswab32(__u32 x)
+static __inline__ __attribute_const__ __u32 __fswab32(__u32 x)
 {
 	return __arch__swab32(x);
 }
@@ -155,7 +157,7 @@ static __inline__ void __swab32s(__u32 *
 }
 
 #ifdef __BYTEORDER_HAS_U64__
-static __inline__ __const__ __u64 __fswab64(__u64 x)
+static __inline__ __attribute_const__ __u64 __fswab64(__u64 x)
 {
 #  ifdef __SWAB_64_THRU_32__
 	__u32 h = x >> 32;
diff -puN include/linux/compiler-gcc2.h~const-fixes include/linux/compiler-gcc2.h
--- 25/include/linux/compiler-gcc2.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/linux/compiler-gcc2.h	2003-12-21 23:45:22.000000000 -0800
@@ -20,4 +20,5 @@
  */
 #if __GNUC_MINOR__ >= 96
 # define __attribute_pure__	__attribute__((pure))
+# define __attribute_const__	__attribute__((__const__))
 #endif
diff -puN include/linux/compiler-gcc3.h~const-fixes include/linux/compiler-gcc3.h
--- 25/include/linux/compiler-gcc3.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/linux/compiler-gcc3.h	2003-12-21 23:45:22.000000000 -0800
@@ -20,3 +20,4 @@
 #endif
 
 #define __attribute_pure__	__attribute__((pure))
+#define __attribute_const__	__attribute__((__const__))
diff -puN include/linux/compiler-gcc+.h~const-fixes include/linux/compiler-gcc+.h
--- 25/include/linux/compiler-gcc+.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/linux/compiler-gcc+.h	2003-12-21 23:45:22.000000000 -0800
@@ -12,3 +12,4 @@
 #define __deprecated		__attribute__((deprecated))
 #define __attribute_used__	__attribute__((__used__))
 #define __attribute_pure__	__attribute__((pure))
+#define __attribute_const__	__attribute__((__const__))
diff -puN include/linux/compiler.h~const-fixes include/linux/compiler.h
--- 25/include/linux/compiler.h~const-fixes	2003-12-21 23:45:22.000000000 -0800
+++ 25-akpm/include/linux/compiler.h	2003-12-21 23:45:22.000000000 -0800
@@ -76,6 +76,24 @@
 # define __attribute_pure__	/* unimplemented */
 #endif
 
+/*
+ * From the GCC manual:
+ *
+ * Many functions do not examine any values except their arguments,
+ * and have no effects except the return value.  Basically this is
+ * just slightly more strict class than the `pure' attribute above,
+ * since function is not allowed to read global memory.
+ *
+ * Note that a function that has pointer arguments and examines the
+ * data pointed to must _not_ be declared `const'.  Likewise, a
+ * function that calls a non-`const' function usually must not be
+ * `const'.  It does not make sense for a `const' function to return
+ * `void'.
+ */
+#ifndef __attribute_const__
+# define __attribute_const__	/* unimplemented */
+#endif
+
 /* Optimization barrier */
 #ifndef barrier
 # define barrier() __memory_barrier()

_