lib/checksum.c: optimize do_csum a bit
Ian Abbott [Thu, 7 Jul 2011 01:18:49 +0000 (01:18 +0000)]
Reduce the number of variables modified by the loop in do_csum() by 1,
which seems like a good idea.  On Nios II (a RISC CPU with 3-operand
instruction set) it reduces the loop from 7 to 6 instructions, including
the conditional branch.

Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

lib/checksum.c

index 0975087..8df2f91 100644 (file)
@@ -49,7 +49,7 @@ static inline unsigned short from32to16(unsigned int x)
 
 static unsigned int do_csum(const unsigned char *buff, int len)
 {
-       int odd, count;
+       int odd;
        unsigned int result = 0;
 
        if (len <= 0)
@@ -64,25 +64,22 @@ static unsigned int do_csum(const unsigned char *buff, int len)
                len--;
                buff++;
        }
-       count = len >> 1;               /* nr of 16-bit words.. */
-       if (count) {
+       if (len >= 2) {
                if (2 & (unsigned long) buff) {
                        result += *(unsigned short *) buff;
-                       count--;
                        len -= 2;
                        buff += 2;
                }
-               count >>= 1;            /* nr of 32-bit words.. */
-               if (count) {
+               if (len >= 4) {
+                       const unsigned char *end = buff + ((unsigned)len & ~3);
                        unsigned int carry = 0;
                        do {
                                unsigned int w = *(unsigned int *) buff;
-                               count--;
                                buff += 4;
                                result += carry;
                                result += w;
                                carry = (w > result);
-                       } while (count);
+                       } while (buff < end);
                        result += carry;
                        result = (result & 0xffff) + (result >> 16);
                }