Re: Some functions are not inlined by gcc 3.2, resulting code is ugly

From: Denis Vlasenko (vda@port.imtp.ilyichevsk.odessa.ua)
Date: Sun Nov 03 2002 - 19:23:01 EST


On 3 November 2002 13:23, Martin J. Bligh wrote:
> > Here is the cure: force_inline will guarantee inlining.
> >
> > To use _only_ with functions which meant to be almost
> > optimized away to nothing but are large and gcc might decide
> > they are _too_ large for inlining.
>
> So aside from the ugliness of code, which one actually runs faster?

This can *never* run faster non-inlined because it is called with
n being compile time constant:

static inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
        switch (n) {
                case 0:
                        return to;
                case 1:
                        *(unsigned char *)to = *(const unsigned char *)from;
                        return to;
                case 2:
                        *(unsigned short *)to = *(const unsigned short *)from;
                        return to;
                case 3:
                        *(unsigned short *)to = *(const unsigned short *)from;
                        *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
                        return to;
                case 4:
                        *(unsigned long *)to = *(const unsigned long *)from;
                        return to;
                case 6: /* for Ethernet addresses */
                        *(unsigned long *)to = *(const unsigned long *)from;
                        *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
                        return to;
                case 8:
                        *(unsigned long *)to = *(const unsigned long *)from;
                        *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
                        return to;
                case 12:
                        *(unsigned long *)to = *(const unsigned long *)from;
                        *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
                        *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
                        return to;
                case 16:
                        *(unsigned long *)to = *(const unsigned long *)from;
                        *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
                        *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
                        *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
                        return to;
                case 20:
                        *(unsigned long *)to = *(const unsigned long *)from;
                        *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
                        *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
                        *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
                        *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
                        return to;
        }
#define COMMON(x) \
__asm__ __volatile__( \
        "rep ; movsl" \
        x \
        : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
        : "0" (n/4),"1" ((long) to),"2" ((long) from) \
        : "memory");
{
        int d0, d1, d2;
        switch (n % 4) {
                case 0: COMMON(""); return to;
                case 1: COMMON("\n\tmovsb"); return to;
                case 2: COMMON("\n\tmovsw"); return to;
                default: COMMON("\n\tmovsw\n\tmovsb"); return to;
        }
}

--
vda
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Nov 07 2002 - 22:00:30 EST