Commits

camlspotter committed 03bcdcb

added sqrt_intr.ml, a use of intrinsics

  • Participants
  • Parent commits 120ab05

Comments (0)

Files changed (5)

File examples/OMakefile

 MyOCamlTestProgram(double, double)
 MyOCamlTestProgram(double_phantom, double_phantom)
 MyOCamlTestProgram(sqrt, sqrt)
+MyOCamlTestProgram(sqrt_intr, sqrt_intr)
 MyOCamlTestProgram(pi, pi)

File examples/double_phantom.ml

 
 let context = Llvm.global_context () 
 
+(* We only use one context, so just include it and available globally. *)
 include Create(struct let context = context end)
+
 open Type
 open Value
 
+(* We only use one module, so just include it and available globally. *)
 include CreateModule(struct
   let name = "mymodule"
   let opt = true
   ~dump:true 
   i32 (* return type *)
   ("param", i32) (* the parameter *)
-  & fun _self -> mul (Const.i32_of_int 2) (* the code *)
+  & fun _self x -> x *! (Const.i32_of_int 2) (* the code *)
 
 let run_double = ExecutionEngine.run_function1 double
 

File examples/pi.ml

 (* Simple monte-carlo to compute pi *)
 
+let (&) = (@@)
+
 open Llvm_phantom.Std
 module P = Phantom
 
 let random_point_1d = perform
   r_i32 <-- call random P.c0;
   r_double <-- sitofp r_i32 double;
-  fdiv r_double (Const.double rand_max) (* 0.0 - 1.0 *)
+  r_double /.! Const.double rand_max (* 0.0 - 1.0 *)
 
 let sq_dist_of_2d_point x y = perform
-  x2 <-- fmul x x;
-  y2 <-- fmul y y;
-  fadd x2 y2
+  x2 <-- x *.! x;
+  y2 <-- y *.! y;
+  x2 +.! y2
 
 let incr v = perform
-  i <-- gep_load v (Gep.pos 0) Gep.end_;
-  i' <-- add i (Const.i32_1);
-  gep_store i' ~dst:v (Gep.pos 0) Gep.end_
+  i <-- Gep.(gep_load v (pos 0) end_); (* CR jfuruse: this should be written like v.{pos 0} *)
+  i' <-- i +! Const.i32_1;
+  Gep.(gep_store i' ~dst:v (pos 0) end_) (* CR jfurus: this should be written like v.{pos 0} <- i' *)
 
 let number = 10000000
 
 let test = perform
-  (* CR jfuruse: Having alloca+initialize function would be nice,
-     since once I have forgotten resetting the content by 0! *)
-  in_points_ptr <-- alloca ~name:"in_points" i32;
-  gep_store (Const.i32_0) ~dst:in_points_ptr (Gep.pos 0) Gep.end_;
+  in_points_ptr <-- alloca_with ~name:"in_points" i32 (Const.i32_0);
   
   for_loop (Const.i32_of_int number)
     (fun n -> icmp Llvm.Icmp.Ne n Const.i32_0)
         (fcmp Llvm.Fcmp.Olt dist (Const.double 1.0))
         (incr in_points_ptr)
         (return ());
-      sub n Const.i32_1);
+      n -! Const.i32_1);
 
-  in_points <-- gep_load in_points_ptr (Gep.pos 0) Gep.end_;
+  in_points <-- Gep.(gep_load in_points_ptr (pos 0) end_);
   in_points <-- sitofp in_points double;
-  fdiv in_points (Const.double (Pervasives.float number /. 4.0))
+  in_points /.! Const.double (Pervasives.float number /. 4.0)
 
-let test_f = build (func0 "calc_pi" ~dump:true double () (fun _self () -> test))
+let test_f = build & func0 "calc_pi" ~dump:true double () & fun _self () -> test
 let run_test_f = ExecutionEngine.run_function0 test_f
 let run_test_ocaml () = Genvalue.as_float double (run_test_f ())
 
-let () = Printf.eprintf "sqrt(%d times)=%f\n" number (run_test_ocaml ())
+let () = Printf.eprintf "pi(%d times)=%f\n" number (run_test_ocaml ())

File examples/sqrt.ml

 (* Declare "sqrt" with its type double(double) *)
 let sqrt = External.declare "sqrt" double (Phantom.c1 double)
 
+let () = Value.dump sqrt
+
 let run_sqrt = ExecutionEngine.run_function1 sqrt
 
 let run_sqrt_ocaml x = Genvalue.as_float double (run_sqrt (Genvalue.of_float double x))

File examples/sqrt_intr.ml

+(* sqrt using via intrinsics *)
+
+let (&) = (@@) 
+
+open Llvm_phantom.Std
+module P = Phantom
+
+let context = Llvm.global_context () 
+
+include Create(struct let context = context end)
+open Type
+(* open Value *)
+
+include CreateModule(struct
+  let name = "mymodule"
+  let opt = true
+end)
+
+(* Declare "sqrt" with its type double(double) *)
+let sqrt = External.declare "llvm.sqrt.f64" double (Phantom.c1 double)
+
+let () = Value.dump sqrt
+
+let () = assert (Llvm.is_intrinsic !<sqrt)
+
+(* I do not know why but unlike C external function sqrt in sqrt.ml,
+   LLVM intrinsics cannot be called as a function. We must use it in another function,
+   or we get an error:
+
+   LLVM ERROR: Program used external function 'llvm.sqrt.f64' which could not be resolved!
+
+   The following is such a failure example:
+
+    let run_sqrt = ExecutionEngine.run_function1 sqrt
+    
+    let run_sqrt_ocaml x = Genvalue.as_float double (run_sqrt (Genvalue.of_float double x))
+    
+    let () = Printf.eprintf "sqrt(3.0)=%f\n" (run_sqrt_ocaml 3.0)
+*)
+
+let main = build & func1 "main" ~dump:true 
+  double (* return type *)
+  ("param", double) (* the parameter *)
+  & fun _self x -> call sqrt (P.c1 x)
+  
+let run = ExecutionEngine.run_function1 main
+
+let run_ocaml x = Genvalue.as_float double (run (Genvalue.of_float double x))
+
+let () = Printf.eprintf "sqrt(3.0)=%f\n" (run_ocaml 3.0)