C and Objective Caml bindings for PassManagers.
[oota-llvm.git] / bindings / ocaml / llvm / llvm.ml
index 63079f21072692ba1b4b022551d27bceb1b5a5e3..dfa772be0a01f96881808072bb6809405f350252 100644 (file)
-(*===-- tools/ml/llvm.ml - LLVM Ocaml Interface ---------------------------===*
+(*===-- llvm/llvm.ml - LLVM Ocaml Interface --------------------------------===*
  *
  *                     The LLVM Compiler Infrastructure
  *
- * This file was developed by Gordon Henriksen and is distributed under the
- * University of Illinois Open Source License. See LICENSE.TXT for details.
- *
- *===----------------------------------------------------------------------===
- *
- * This interface provides an ocaml API for the LLVM intermediate
- * representation, the classes in the VMCore library.
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
  *
  *===----------------------------------------------------------------------===*)
 
 
-(* These abstract types correlate directly to the LLVM VMCore classes. *)
 type llmodule
 type lltype
+type lltypehandle
 type llvalue
-type llbasicblock (* These are actually values, but
-                     benefit from type checking. *)
+type llbasicblock
 type llbuilder
-
-type type_kind =
-  Void_type
-| Float_type
-| Double_type
-| X86fp80_type
-| Fp128_type
-| Ppc_fp128_type
-| Label_type
-| Integer_type
-| Function_type
-| Struct_type
-| Array_type
-| Pointer_type 
-| Opaque_type
-| Vector_type
-
-type linkage =
-  External_linkage
-| Link_once_linkage
-| Weak_linkage
-| Appending_linkage
-| Internal_linkage
-| Dllimport_linkage
-| Dllexport_linkage
-| External_weak_linkage
-| Ghost_linkage
-
-type visibility =
-  Default_visibility
-| Hidden_visibility
-| Protected_visibility
-
-let ccc = 0
-let fastcc = 8
-let coldcc = 9
-let x86_stdcallcc = 64
-let x86_fastcallcc = 65
-
-type int_predicate =
-  Icmp_eq
-| Icmp_ne
-| Icmp_ugt
-| Icmp_uge
-| Icmp_ult
-| Icmp_ule
-| Icmp_sgt
-| Icmp_sge
-| Icmp_slt
-| Icmp_sle
-
-type real_predicate =
-  Fcmp_false
-| Fcmp_oeq
-| Fcmp_ogt
-| Fcmp_oge
-| Fcmp_olt
-| Fcmp_ole
-| Fcmp_one
-| Fcmp_ord
-| Fcmp_uno
-| Fcmp_ueq
-| Fcmp_ugt
-| Fcmp_uge
-| Fcmp_ult
-| Fcmp_ule
-| Fcmp_une
-| Fcmp_true
+type llmoduleprovider
+type llmemorybuffer
+
+module TypeKind = struct
+  type t =
+  | Void
+  | Float
+  | Double
+  | X86fp80
+  | Fp128
+  | Ppc_fp128
+  | Label
+  | Integer
+  | Function
+  | Struct
+  | Array
+  | Pointer
+  | Opaque
+  | Vector
+end
+
+module Linkage = struct
+  type t =
+  | External
+  | Link_once
+  | Weak
+  | Appending
+  | Internal
+  | Dllimport
+  | Dllexport
+  | External_weak
+  | Ghost
+end
+
+module Visibility = struct
+  type t =
+  | Default
+  | Hidden
+  | Protected
+end
+
+module CallConv = struct
+  let c = 0
+  let fast = 8
+  let cold = 9
+  let x86_stdcall = 64
+  let x86_fastcall = 65
+end
+
+module Icmp = struct
+  type t =
+  | Eq
+  | Ne
+  | Ugt
+  | Uge
+  | Ult
+  | Ule
+  | Sgt
+  | Sge
+  | Slt
+  | Sle
+end
+
+module Fcmp = struct
+  type t =
+  | False
+  | Oeq
+  | Ogt
+  | Oge
+  | Olt
+  | Ole
+  | One
+  | Ord
+  | Uno
+  | Ueq
+  | Ugt
+  | Uge
+  | Ult
+  | Ule
+  | Une
+  | True
+end
+
+exception IoError of string
+
+external register_exns : exn -> unit = "llvm_register_core_exns"
+let _ = register_exns (IoError "")
 
 
 (*===-- Modules -----------------------------------------------------------===*)
 
-(* Creates a module with the supplied module ID. Modules are not garbage
-   collected; it is mandatory to call dispose_module to free memory. *)
 external create_module : string -> llmodule = "llvm_create_module"
-
-(* Disposes a module. All references to subordinate objects are invalidated;
-   referencing them will invoke undefined behavior. *)
 external dispose_module : llmodule -> unit = "llvm_dispose_module"
-
-(* Adds a named type to the module's symbol table. Returns true if successful.
-   If such a name already exists, then no entry is added and returns false. *)
+external target_triple: llmodule -> string
+                      = "llvm_target_triple"
+external set_target_triple: string -> llmodule -> unit
+                          = "llvm_set_target_triple"
+external data_layout: llmodule -> string
+                    = "llvm_data_layout"
+external set_data_layout: string -> llmodule -> unit
+                        = "llvm_set_data_layout"
 external define_type_name : string -> lltype -> llmodule -> bool
                           = "llvm_add_type_name"
-
 external delete_type_name : string -> llmodule -> unit
                           = "llvm_delete_type_name"
-
+external dump_module : llmodule -> unit = "llvm_dump_module"
 
 (*===-- Types -------------------------------------------------------------===*)
 
-external classify_type : lltype -> type_kind = "llvm_classify_type"
-external refine_abstract_type : lltype -> lltype -> unit
-                              = "llvm_refine_abstract_type"
+external classify_type : lltype -> TypeKind.t = "llvm_classify_type"
 
 (*--... Operations on integer types ........................................--*)
 external _i1_type : unit -> lltype = "llvm_i1_type"
@@ -128,7 +138,7 @@ let i16_type = _i16_type ()
 let i32_type = _i32_type ()
 let i64_type = _i64_type ()
 
-external make_integer_type : int -> lltype = "llvm_make_integer_type"
+external integer_type : int -> lltype = "llvm_integer_type"
 external integer_bitwidth : lltype -> int = "llvm_integer_bitwidth"
 
 (*--... Operations on real types ...........................................--*)
@@ -145,86 +155,143 @@ let fp128_type = _fp128_type ()
 let ppc_fp128_type = _ppc_fp128_type ()
 
 (*--... Operations on function types .......................................--*)
-(* FIXME: handle parameter attributes *)
-external make_function_type : lltype -> lltype array -> bool -> lltype
-                            = "llvm_make_function_type"
+external function_type : lltype -> lltype array -> lltype = "llvm_function_type"
+external var_arg_function_type : lltype -> lltype array -> lltype
+                               = "llvm_var_arg_function_type"
 external is_var_arg : lltype -> bool = "llvm_is_var_arg"
-external return_type : lltype -> lltype = "llvm_return_type"
+external return_type : lltype -> lltype = "LLVMGetReturnType"
 external param_types : lltype -> lltype array = "llvm_param_types"
 
 (*--... Operations on struct types .........................................--*)
-external make_struct_type : lltype array -> bool -> lltype
-                          = "llvm_make_struct_type"
+external struct_type : lltype array -> lltype = "llvm_struct_type"
+external packed_struct_type : lltype array -> lltype = "llvm_packed_struct_type"
 external element_types : lltype -> lltype array = "llvm_element_types"
 external is_packed : lltype -> bool = "llvm_is_packed"
 
 (*--... Operations on pointer, vector, and array types .....................--*)
-external make_array_type : lltype -> int -> lltype = "llvm_make_array_type"
-external make_pointer_type : lltype -> lltype = "llvm_make_pointer_type"
-external make_vector_type : lltype -> int -> lltype = "llvm_make_vector_type"
+external array_type : lltype -> int -> lltype = "llvm_array_type"
+external pointer_type : lltype -> lltype = "llvm_pointer_type"
+external qualified_pointer_type : lltype -> int -> lltype
+                                = "llvm_qualified_pointer_type"
+external vector_type : lltype -> int -> lltype = "llvm_vector_type"
 
-external element_type : lltype -> lltype = "llvm_element_type"
+external element_type : lltype -> lltype = "LLVMGetElementType"
 external array_length : lltype -> int = "llvm_array_length"
+external address_space : lltype -> int = "llvm_address_space"
 external vector_size : lltype -> int = "llvm_vector_size"
 
 (*--... Operations on other types ..........................................--*)
-external make_opaque_type : unit -> lltype = "llvm_make_opaque_type"
+external opaque_type : unit -> lltype = "llvm_opaque_type"
 external _void_type : unit -> lltype = "llvm_void_type"
 external _label_type : unit -> lltype = "llvm_label_type"
 
 let void_type = _void_type ()
 let label_type = _label_type ()
 
+(*--... Operations on type handles .........................................--*)
+external handle_to_type : lltype -> lltypehandle = "llvm_handle_to_type"
+external type_of_handle : lltypehandle -> lltype = "llvm_type_of_handle"
+external refine_type : lltype -> lltype -> unit = "llvm_refine_type"
+
 
 (*===-- Values ------------------------------------------------------------===*)
 
 external type_of : llvalue -> lltype = "llvm_type_of"
 external value_name : llvalue -> string = "llvm_value_name"
 external set_value_name : string -> llvalue -> unit = "llvm_set_value_name"
+external dump_value : llvalue -> unit = "llvm_dump_value"
 
 (*--... Operations on constants of (mostly) any type .......................--*)
 external is_constant : llvalue -> bool = "llvm_is_constant"
-external make_null : lltype -> llvalue = "LLVMGetNull"
-external make_all_ones : (*int|vec*)lltype -> llvalue = "LLVMGetAllOnes"
-external make_undef : lltype -> llvalue = "LLVMGetUndef"
+external const_null : lltype -> llvalue = "LLVMConstNull"
+external const_all_ones : (*int|vec*)lltype -> llvalue = "LLVMConstAllOnes"
+external undef : lltype -> llvalue = "LLVMGetUndef"
 external is_null : llvalue -> bool = "llvm_is_null"
 external is_undef : llvalue -> bool = "llvm_is_undef"
 
 (*--... Operations on scalar constants .....................................--*)
-external make_int_constant : lltype -> int -> bool -> llvalue
-                           = "llvm_make_int_constant"
-external make_int64_constant : lltype -> Int64.t -> bool -> llvalue
-                             = "llvm_make_int64_constant"
-external make_real_constant : lltype -> float -> llvalue
-                            = "llvm_make_real_constant"
+external const_int : lltype -> int -> llvalue = "llvm_const_int"
+external const_of_int64 : lltype -> Int64.t -> bool -> llvalue
+                        = "llvm_const_of_int64"
+external const_float : lltype -> float -> llvalue = "llvm_const_float"
 
 (*--... Operations on composite constants ..................................--*)
-external make_string_constant : string -> bool -> llvalue
-                              = "llvm_make_string_constant"
-external make_array_constant : lltype -> llvalue array -> llvalue
-                             = "llvm_make_array_constant"
-external make_struct_constant : llvalue array -> bool -> llvalue
-                              = "llvm_make_struct_constant"
-external make_vector_constant : llvalue array -> llvalue
-                              = "llvm_make_vector_constant"
+external const_string : string -> llvalue = "llvm_const_string"
+external const_stringz : string -> llvalue = "llvm_const_stringz"
+external const_array : lltype -> llvalue array -> llvalue = "llvm_const_array"
+external const_struct : llvalue array -> llvalue = "llvm_const_struct"
+external const_packed_struct : llvalue array -> llvalue
+                             = "llvm_const_packed_struct"
+external const_vector : llvalue array -> llvalue = "llvm_const_vector"
+
+(*--... Constant expressions ...............................................--*)
+external size_of : lltype -> llvalue = "LLVMSizeOf"
+external const_neg : llvalue -> llvalue = "LLVMConstNeg"
+external const_not : llvalue -> llvalue = "LLVMConstNot"
+external const_add : llvalue -> llvalue -> llvalue = "LLVMConstAdd"
+external const_sub : llvalue -> llvalue -> llvalue = "LLVMConstSub"
+external const_mul : llvalue -> llvalue -> llvalue = "LLVMConstMul"
+external const_udiv : llvalue -> llvalue -> llvalue = "LLVMConstUDiv"
+external const_sdiv : llvalue -> llvalue -> llvalue = "LLVMConstSDiv"
+external const_fdiv : llvalue -> llvalue -> llvalue = "LLVMConstFDiv"
+external const_urem : llvalue -> llvalue -> llvalue = "LLVMConstURem"
+external const_srem : llvalue -> llvalue -> llvalue = "LLVMConstSRem"
+external const_frem : llvalue -> llvalue -> llvalue = "LLVMConstFRem"
+external const_and : llvalue -> llvalue -> llvalue = "LLVMConstAnd"
+external const_or : llvalue -> llvalue -> llvalue = "LLVMConstOr"
+external const_xor : llvalue -> llvalue -> llvalue = "LLVMConstXor"
+external const_icmp : Icmp.t -> llvalue -> llvalue -> llvalue
+                    = "llvm_const_icmp"
+external const_fcmp : Fcmp.t -> llvalue -> llvalue -> llvalue
+                    = "llvm_const_fcmp"
+external const_shl : llvalue -> llvalue -> llvalue = "LLVMConstShl"
+external const_lshr : llvalue -> llvalue -> llvalue = "LLVMConstLShr"
+external const_ashr : llvalue -> llvalue -> llvalue = "LLVMConstAShr"
+external const_gep : llvalue -> llvalue array -> llvalue = "llvm_const_gep"
+external const_trunc : llvalue -> lltype -> llvalue = "LLVMConstTrunc"
+external const_sext : llvalue -> lltype -> llvalue = "LLVMConstSExt"
+external const_zext : llvalue -> lltype -> llvalue = "LLVMConstZExt"
+external const_fptrunc : llvalue -> lltype -> llvalue = "LLVMConstFPTrunc"
+external const_fpext : llvalue -> lltype -> llvalue = "LLVMConstFPExt"
+external const_uitofp : llvalue -> lltype -> llvalue = "LLVMConstUIToFP"
+external const_sitofp : llvalue -> lltype -> llvalue = "LLVMConstSIToFP"
+external const_fptoui : llvalue -> lltype -> llvalue = "LLVMConstFPToUI"
+external const_fptosi : llvalue -> lltype -> llvalue = "LLVMConstFPToSI"
+external const_ptrtoint : llvalue -> lltype -> llvalue = "LLVMConstPtrToInt"
+external const_inttoptr : llvalue -> lltype -> llvalue = "LLVMConstIntToPtr"
+external const_bitcast : llvalue -> lltype -> llvalue = "LLVMConstBitCast"
+external const_select : llvalue -> llvalue -> llvalue -> llvalue
+                      = "LLVMConstSelect"
+external const_extractelement : llvalue -> llvalue -> llvalue
+                              = "LLVMConstExtractElement"
+external const_insertelement : llvalue -> llvalue -> llvalue -> llvalue
+                             = "LLVMConstInsertElement"
+external const_shufflevector : llvalue -> llvalue -> llvalue -> llvalue
+                             = "LLVMConstShuffleVector"
 
 (*--... Operations on global variables, functions, and aliases (globals) ...--*)
 external is_declaration : llvalue -> bool = "llvm_is_declaration"
-external linkage : llvalue -> linkage = "llvm_linkage"
-external set_linkage : linkage -> llvalue -> unit = "llvm_set_linkage"
+external linkage : llvalue -> Linkage.t = "llvm_linkage"
+external set_linkage : Linkage.t -> llvalue -> unit = "llvm_set_linkage"
 external section : llvalue -> string = "llvm_section"
 external set_section : string -> llvalue -> unit = "llvm_set_section"
-external visibility : llvalue -> visibility = "llvm_visibility"
-external set_visibility : visibility -> llvalue -> unit = "llvm_set_visibility"
+external visibility : llvalue -> Visibility.t = "llvm_visibility"
+external set_visibility : Visibility.t -> llvalue -> unit = "llvm_set_visibility"
 external alignment : llvalue -> int = "llvm_alignment"
 external set_alignment : int -> llvalue -> unit = "llvm_set_alignment"
+external is_global_constant : llvalue -> bool = "llvm_is_global_constant"
+external set_global_constant : bool -> llvalue -> unit
+                             = "llvm_set_global_constant"
 
 (*--... Operations on global variables .....................................--*)
 external declare_global : lltype -> string -> llmodule -> llvalue
                         = "llvm_declare_global"
 external define_global : string -> llvalue -> llmodule -> llvalue
                        = "llvm_define_global"
+external lookup_global : string -> llmodule -> llvalue option
+                       = "llvm_lookup_global"
 external delete_global : llvalue -> unit = "llvm_delete_global"
+external has_initializer : llvalue -> bool = "llvm_has_initializer"
 external global_initializer : llvalue -> llvalue = "LLVMGetInitializer"
 external set_initializer : llvalue -> llvalue -> unit = "llvm_set_initializer"
 external remove_initializer : llvalue -> unit = "llvm_remove_initializer"
@@ -236,6 +303,8 @@ external declare_function : string -> lltype -> llmodule -> llvalue
                           = "llvm_declare_function"
 external define_function : string -> lltype -> llmodule -> llvalue
                          = "llvm_define_function"
+external lookup_function : string -> llmodule -> llvalue option
+                         = "llvm_lookup_function"
 external delete_function : llvalue -> unit = "llvm_delete_function"
 external params : llvalue -> llvalue array = "llvm_params"
 external param : llvalue -> int -> llvalue = "llvm_param"
@@ -243,6 +312,8 @@ external is_intrinsic : llvalue -> bool = "llvm_is_intrinsic"
 external function_call_conv : llvalue -> int = "llvm_function_call_conv"
 external set_function_call_conv : int -> llvalue -> unit
                                 = "llvm_set_function_call_conv"
+external collector : llvalue -> string option = "llvm_collector"
+external set_collector : string option -> llvalue -> unit = "llvm_set_collector"
 
 (* TODO: param attrs *)
 
@@ -257,8 +328,21 @@ external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue"
 external value_is_block : llvalue -> bool = "llvm_value_is_block"
 external block_of_value : llvalue -> llbasicblock = "LLVMValueAsBasicBlock"
 
+(*--... Operations on call sites ...........................................--*)
+external instruction_call_conv: llvalue -> int
+                              = "llvm_instruction_call_conv"
+external set_instruction_call_conv: int -> llvalue -> unit
+                                  = "llvm_set_instruction_call_conv"
+
+(*--... Operations on phi nodes ............................................--*)
+external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
+                      = "llvm_add_incoming"
+external incoming : llvalue -> (llvalue * llbasicblock) list = "llvm_incoming"
+
 
 (*===-- Instruction builders ----------------------------------------------===*)
+external builder: unit-> llbuilder
+                = "llvm_builder"
 external builder_before : llvalue -> llbuilder = "llvm_builder_before"
 external builder_at_end : llbasicblock -> llbuilder = "llvm_builder_at_end"
 external position_before : llvalue -> llbuilder -> unit = "llvm_position_before"
@@ -359,13 +443,14 @@ external build_bitcast : llvalue -> lltype -> string -> llbuilder -> llvalue
                        = "llvm_build_bitcast"
 
 (*--... Comparisons ........................................................--*)
-external build_icmp : int_predicate -> llvalue -> llvalue -> string ->
+external build_icmp : Icmp.t -> llvalue -> llvalue -> string ->
                       llbuilder -> llvalue = "llvm_build_icmp"
-external build_fcmp : real_predicate -> llvalue -> llvalue -> string ->
+external build_fcmp : Fcmp.t -> llvalue -> llvalue -> string ->
                       llbuilder -> llvalue = "llvm_build_fcmp"
 
 (*--... Miscellaneous instructions .........................................--*)
-external build_phi : lltype -> string -> llbuilder -> llvalue = "llvm_build_phi"
+external build_phi : (llvalue * llbasicblock) list -> string -> llbuilder ->
+                     llvalue = "llvm_build_phi"
 external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue
                     = "llvm_build_call"
 external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder ->
@@ -380,6 +465,42 @@ external build_shufflevector : llvalue -> llvalue -> llvalue -> string ->
                                llbuilder -> llvalue = "llvm_build_shufflevector"
 
 
+(*===-- Module providers --------------------------------------------------===*)
+
+module ModuleProvider = struct
+  external create : llmodule -> llmoduleprovider
+                  = "LLVMCreateModuleProviderForExistingModule"
+  external dispose : llmoduleprovider -> unit = "llvm_dispose_module_provider"
+end
+  
+
+(*===-- Memory buffers ----------------------------------------------------===*)
+
+module MemoryBuffer = struct
+  external of_file : string -> llmemorybuffer = "llvm_memorybuffer_of_file"
+  external of_stdin : unit -> llmemorybuffer = "llvm_memorybuffer_of_stdin"
+  external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose"
+end
+
+
+(*===-- Pass Manager ------------------------------------------------------===*)
+
+module PassManager = struct
+  type 'a t
+  type any = [ `Module | `Function ]
+  external create : unit -> [ `Module ] t = "llvm_passmanager_create"
+  external create_function : llmoduleprovider -> [ `Function ] t
+                           = "LLVMCreateFunctionPassManager"
+  external run_module : llmodule -> [ `Module ] t -> bool
+                      = "llvm_passmanager_run_module"
+  external initialize : [ `Function ] t -> bool = "llvm_passmanager_initialize"
+  external run_function : llvalue -> [ `Function ] t -> bool
+                        = "llvm_passmanager_run_function"
+  external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize"
+  external dispose : [< any ] t -> unit = "llvm_passmanager_dispose"
+end
+
+
 (*===-- Non-Externs -------------------------------------------------------===*)
 (* These functions are built using the externals, so must be declared late.   *)
 
@@ -394,29 +515,30 @@ let concat2 sep arr =
   !s
 
 let rec string_of_lltype ty =
+  (* FIXME: stop infinite recursion! :) *)
   match classify_type ty with
-    Integer_type -> "i" ^ string_of_int (integer_bitwidth ty)
-  | Pointer_type -> (string_of_lltype (element_type ty)) ^ "*"
-  | Struct_type ->
+    TypeKind.Integer -> "i" ^ string_of_int (integer_bitwidth ty)
+  | TypeKind.Pointer -> (string_of_lltype (element_type ty)) ^ "*"
+  | TypeKind.Struct ->
       let s = "{ " ^ (concat2 ", " (
                 Array.map string_of_lltype (element_types ty)
               )) ^ " }" in
       if is_packed ty
         then "<" ^ s ^ ">"
         else s
-  | Array_type -> "["   ^ (string_of_int (array_length ty)) ^
-                  " x " ^ (string_of_lltype (element_type ty)) ^ "]"
-  | Vector_type -> "<"   ^ (string_of_int (vector_size ty)) ^
-                   " x " ^ (string_of_lltype (element_type ty)) ^ ">"
-  | Opaque_type -> "opaque"
-  | Function_type -> string_of_lltype (return_type ty) ^
-                     " (" ^ (concat2 ", " (
-                       Array.map string_of_lltype (param_types ty)
-                     )) ^ ")"
-  | Label_type -> "label"
-  | Ppc_fp128_type -> "ppc_fp128"
-  | Fp128_type -> "fp128"
-  | X86fp80_type -> "x86_fp80"
-  | Double_type -> "double"
-  | Float_type -> "float"
-  | Void_type -> "void"
+  | TypeKind.Array -> "["   ^ (string_of_int (array_length ty)) ^
+                      " x " ^ (string_of_lltype (element_type ty)) ^ "]"
+  | TypeKind.Vector -> "<"   ^ (string_of_int (vector_size ty)) ^
+                       " x " ^ (string_of_lltype (element_type ty)) ^ ">"
+  | TypeKind.Opaque -> "opaque"
+  | TypeKind.Function -> string_of_lltype (return_type ty) ^
+                         " (" ^ (concat2 ", " (
+                           Array.map string_of_lltype (param_types ty)
+                         )) ^ ")"
+  | TypeKind.Label -> "label"
+  | TypeKind.Ppc_fp128 -> "ppc_fp128"
+  | TypeKind.Fp128 -> "fp128"
+  | TypeKind.X86fp80 -> "x86_fp80"
+  | TypeKind.Double -> "double"
+  | TypeKind.Float -> "float"
+  | TypeKind.Void -> "void"