[LLVMdev] How to declare and use sprintf

Jon Harrop jon at ffconsultancy.com
Sun Nov 25 16:37:51 PST 2007


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



More information about the llvm-dev mailing list