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