[LLVMdev] First class function pointers

Jon Harrop jon at ffconsultancy.com
Thu Feb 5 20:32:16 PST 2009


On Friday 06 February 2009 03:33:57 Chris Lattner wrote:
> On Feb 5, 2009, at 3:42 PM, Jon Harrop wrote:
> > Unless I am mistaken, LLVM barfs if I try to pass an LLVM function
> > to another
> > function as an argument because functions are second class.
>
> Huh?  can you give an example as llvm IR?  You can certainly pass
> functions by-value as a function pointer.

Sorry, I seem to have confused myself. I was const bitcasting the function to 
a function pointer but that is redundant, presumably because the value 
returned when you define a function already represents a function pointer.

Anyway, I still do not understand why functions are not listed as first-class 
types in the documentation if values of the "function" type can be produced 
by instructions, passed as arguments and used as operands to instructions?

You may be interested in the IR anyway because it is a test of tail calls in 
LLVM:

define fastcc i32 @even(i32 (i32)*, i32) {
entry:
        %2 = add i32 %1, 1              ; <i32> [#uses=1]
        %3 = tail call fastcc i32 %0(i32 %2)            ; <i32> [#uses=1]
        ret i32 %3
}

define fastcc i32 @odd(i32) {
entry:
        %1 = call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @buf, 
i32 0, i32 0), i32 %0)             ; <i32> [#uses=0]
        %2 = icmp slt i32 %0, 1000000           ; <i1> [#uses=1]
        br i1 %2, label %pass, label %fail

fail:           ; preds = %entry
        ret i32 0

pass:           ; preds = %entry
        %3 = add i32 %0, 1              ; <i32> [#uses=1]
        %4 = tail call fastcc i32 @even(i32 (i32)* @odd, 
i32 %3)               ; <i32> [#uses=1]
        ret i32 %4
}

declare i32 @printf(i8*, ...)

define i32 @eval() {
entry:
        %0 = call fastcc i32 @even(i32 (i32)* @odd, i32 0)              ; 
<i32> [#uses=0]
        %1 = call i32 (i8*, ...)* @printf(i8* getelementptr ([3 x i8]* @buf1, 
i32 0, i32 0))            ; <i32> [#uses=0]
        %2 = call i32 (i8*, ...)* @printf(i8* getelementptr ([2 x i8]* @buf2, 
i32 0, i32 0))            ; <i32> [#uses=0]
        ret i32 0
}

Note that the branch location that "even" jumps to is dynamic, being passed in 
as an argument. LLVM passes this test but other VMs (such as Mono) fail.

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e



More information about the llvm-dev mailing list