telling GCC that a pointer cannot be NULL

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

is it possible to tell GCC that a pointer cannot be NULL at a
particular point so the compiler can optimize the control flaw better
and avoid redundant NULL checks on the fast paths?

For example, consider first the following fragment that implement a
bump allocator:

struct Allocator {
    unsigned char *start;
    unsigned char *end;
};

static inline void *allocateFast(struct Allocator *a) {
    void *n = a->start;
    if (n != a->end) {
        a->start += 16; /* size of the thing to allocate. */
        return n; /* n cannot be NULL here */
    }
    return 0;
}

void *allocateSlow(struct Allocator *a);

void *allocate(struct Allocator *a) {
    void *p = allocateFast(a);
    return p ? p : allocateSlow(a);
}

If I compile the fragment with GCC 4.5 like in gcc -S -O3
-fomit-frame-pointer, then the compiler effectively generates the
following code for the body of the allocate function:

    void *n = a->start;
    if (n == a->end) goto slow;
    a->start += 16;
    if (!n) goto slow;
    return n;
  slow:
    return allocateSlow(a);

Note an extra if (!n) check that the compiler inserts as it does not
know that n cannot be NULL at that point.

This extra check can be eliminated if I change the code to:

#include <stdbool.h>

struct Allocator {
    unsigned char *start;
    unsigned char *end;
};

static inline bool allocateFast(struct Allocator *a, void **p) {
    void *n = a->start;
    if (n != a->end) {
        a->start += 16;
        *p = n;
        return true;
    }
    return false;
}

void *allocateSlow(struct Allocator *a);

void *allocate(struct Allocator *a) {
    void *p;
    if (allocateFast(a, &p))
        return p;
    return allocateSlow(a);
}

Now GCC generates code without the extra check:

    void *n = a->start;
    if (n == a->end) goto slow;
    a->start += 16;
    return n;
  slow:
    return allocateSlow(a);

But is it possible to avoid such refactoring and just tell GCC that
the pointer cannot be NULL? This way the refactoring that would touch
a substantial body of the code can be done later when the benefits of
the bump allocator would be apparent?


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux