So my Fib program is segfaulting and I'm not sure why. I think it might be because my declaration and use of sprintf is wrong. I notice llvm-gcc produces declarations containing "..." like: declare int %printf(sbyte*, ...) but I'm not sure how to do this so I've used: let sprintf declare_function "sprintf" (function_type (pointer_type i8_type) [| pointer_type i8_type; pointer_type i8_type; i32_type |]) m in which gives: declare i8* @sprintf(i8*, i8*, i32) What is the correct way to do this? -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/products/?e
On Monday 26 November 2007 00:40, Gordon Henriksen wrote:> The type you want is: > > let sp = pointer_type i8_type in > var_arg_function_type sp [| sp; sp |]Awesome stuff. Here is my most elegant Fibonacci example in OCaml so far: open Llvm let ( |> ) x f = f x let int n = const_int i32_type n let return b x = build_ret x b |> ignore let build_fib m let ty = function_type i32_type [| i32_type |] in let fibf = define_function "fib" ty m in let bb = builder_at_end (entry_block fibf) in let n = param fibf 0 in let retbb = append_block "return" fibf in let retb = builder_at_end retbb in let recursebb = append_block "recurse" fibf in let recurseb = builder_at_end recursebb in let ( <= ) f g = build_icmp Icmp_sle f g "cond" bb in build_cond_br (n <= int 2) retbb recursebb bb |> ignore; return retb (int 1); let apply f xs = build_call f xs "apply" recurseb in let ( +: ) f g = build_add f g "add" recurseb in let ( -: ) f g = build_sub f g "sub" recurseb in return recurseb (apply fibf [| n -: int 1 |] +: apply fibf [| n -: int 2 |]); fibf let main filename let m = create_module filename in let string = pointer_type i8_type in let printf declare_function "printf" (var_arg_function_type i32_type [|string|]) m in let main define_function "main" (function_type i32_type [| |]) m |> entry_block |> builder_at_end in let str s = define_global "buf" (const_stringz s) m in let int_spec = build_gep (str "%d\n") [| int 0; int 0 |] "int_spec" main in let n = build_call (build_fib m) [| const_int i32_type 40 |] "" main in let _ = build_call printf [| int_spec; n |] "" main in build_ret (const_null i32_type) main |> ignore; if not (Llvm_bitwriter.write_bitcode_file m filename) then exit 1; dispose_module m let () = match Sys.argv with | [|_; filename|] -> main filename | _ as a -> Printf.eprintf "Usage: %s <file>\n" a.(0) as you can see it already uses some functional features. Next, I'll move the hard-coded program into data and write a more generic compiler in it. Looks really good though... :-) -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. http://www.ffconsultancy.com/products/?e
On Nov 25, 2007, at 18:53, Jon Harrop wrote:> So my Fib program is segfaulting and I'm not sure why. I think it > might be because my declaration and use of sprintf is wrong. > > I notice llvm-gcc produces declarations containing "..." like: > > declare int %printf(sbyte*, ...) > > What is the correct way to do this?The type you want is: let sp = pointer_type i8_type in var_arg_function_type sp [| sp; sp |] — Gordon