If you have the following code in "alloc.c":
typedef __typeof__(sizeof(int)) size_t;
extern void *calloc (size_t __nmemb, size_t __size)
__attribute__ ((__nothrow__ )) __attribute__ ((__malloc__)) ;
extern void free (void *__ptr) __attribute__ ((__nothrow__ ));
struct _astruct {
int l;
};
int main() {
struct _astruct *f = (struct _astruct*)calloc(1, sizeof(struct _astruct));
f->l = 99;
int x = f->l;
free(f);
return x;
}
(I know that's not the preferred way to declare calloc/free, but it's for simplicity of output below.)
Then you run "clang -O3 -S -emit-llvm alloc.c" with Clang/LLVM 3.3, you get:
; ModuleID = 'alloc.c'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: nounwind readnone uwtable
define i32 @main() #0 {
entry:
ret i32 99
}
attributes #0 = { nounwind readnone uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }
You can see that it has eliminated the call to calloc altogether. Awesome. In general, though, a compiler can't eliminate calls to functions that it does not have the source to (there may be side-effects). So it seems that Clang has special case code for calloc/free. This is supported by the fact that if you chanage all occurrences to "calloc" in the code to be "_calloc", the "allocation" comes back.
So my question is, is there any way to tell Clang/LLVM that a particular function is an "allocation only" function? Perhaps some annotation I could put on the definition of one of my own functions that would allow LLVM to optimize away allocations just as it can for calloc/malloc.