-(*===-- llvm/llvm.ml - LLVM Ocaml Interface --------------------------------===*
+(*===-- llvm/llvm.ml - LLVM OCaml Interface -------------------------------===*
*
* The LLVM Compiler Infrastructure
*
type lluse
type llbasicblock
type llbuilder
+type llattrkind
+type llattribute
type llmemorybuffer
+type llmdkind
+
+exception FeatureDisabled of string
+
+let () = Callback.register_exception "Llvm.FeatureDisabled" (FeatureDisabled "")
module TypeKind = struct
type t =
| Pointer
| Vector
| Metadata
+ | X86_mmx
+ | Token
end
module Linkage = struct
| Available_externally
| Link_once
| Link_once_odr
+ | Link_once_odr_auto_hide
| Weak
| Weak_odr
| Appending
| Ghost
| Common
| Linker_private
+ | Linker_private_weak
end
module Visibility = struct
| Protected
end
+module DLLStorageClass = struct
+ type t =
+ | Default
+ | DLLImport
+ | DLLExport
+end
+
module CallConv = struct
let c = 0
let fast = 8
let x86_fastcall = 65
end
+module AttrRepr = struct
+ type t =
+ | Enum of llattrkind * int64
+ | String of string * string
+end
+
+module AttrIndex = struct
+ type t =
+ | Function
+ | Return
+ | Param of int
+
+ let to_int index =
+ match index with
+ | Function -> -1
+ | Return -> 0
+ | Param(n) -> 1 + n
+end
+
module Attribute = struct
type t =
| Zext
| AtomicRMW
| Resume
| LandingPad
- | Unwind
+ | AddrSpaceCast
+ | CleanupRet
+ | CatchRet
+ | CatchPad
+ | CleanupPad
+ | CatchSwitch
+end
+
+module LandingPadClauseTy = struct
+ type t =
+ | Catch
+ | Filter
+end
+
+module ThreadLocalMode = struct
+ type t =
+ | None
+ | GeneralDynamic
+ | LocalDynamic
+ | InitialExec
+ | LocalExec
+end
+
+module AtomicOrdering = struct
+ type t =
+ | NotAtomic
+ | Unordered
+ | Monotonic
+ | Invalid
+ | Acquire
+ | Release
+ | AcqiureRelease
+ | SequentiallyConsistent
+end
+
+module AtomicRMWBinOp = struct
+ type t =
+ | Xchg
+ | Add
+ | Sub
+ | And
+ | Nand
+ | Or
+ | Xor
+ | Max
+ | Min
+ | UMax
+ | UMin
end
module ValueKind = struct
| BlockAddress
| ConstantAggregateZero
| ConstantArray
+ | ConstantDataArray
+ | ConstantDataVector
| ConstantExpr
| ConstantFP
| ConstantInt
| ConstantVector
| Function
| GlobalAlias
+ | GlobalIFunc
| GlobalVariable
| UndefValue
| Instruction of Opcode.t
end
+module DiagnosticSeverity = struct
+ type t =
+ | Error
+ | Warning
+ | Remark
+ | Note
+end
+
exception IoError of string
-external register_exns : exn -> unit = "llvm_register_core_exns"
-let _ = register_exns (IoError "")
+let () = Callback.register_exception "Llvm.IoError" (IoError "")
+
+external install_fatal_error_handler : (string -> unit) -> unit
+ = "llvm_install_fatal_error_handler"
+external reset_fatal_error_handler : unit -> unit
+ = "llvm_reset_fatal_error_handler"
+external enable_pretty_stacktrace : unit -> unit
+ = "llvm_enable_pretty_stacktrace"
+external parse_command_line_options : ?overview:string -> string array -> unit
+ = "llvm_parse_command_line_options"
type ('a, 'b) llpos =
| At_end of 'a
| At_start of 'a
| After of 'b
+
+(*===-- Context error handling --------------------------------------------===*)
+module Diagnostic = struct
+ type t
+
+ external description : t -> string = "llvm_get_diagnostic_description"
+ external severity : t -> DiagnosticSeverity.t
+ = "llvm_get_diagnostic_severity"
+end
+
+external set_diagnostic_handler
+ : llcontext -> (Diagnostic.t -> unit) option -> unit
+ = "llvm_set_diagnostic_handler"
+
(*===-- Contexts ----------------------------------------------------------===*)
external create_context : unit -> llcontext = "llvm_create_context"
external dispose_context : llcontext -> unit = "llvm_dispose_context"
external global_context : unit -> llcontext = "llvm_global_context"
-external mdkind_id : llcontext -> string -> int = "llvm_mdkind_id"
+external mdkind_id : llcontext -> string -> llmdkind = "llvm_mdkind_id"
+
+(*===-- Attributes --------------------------------------------------------===*)
+exception UnknownAttribute of string
+
+let () = Callback.register_exception "Llvm.UnknownAttribute"
+ (UnknownAttribute "")
+
+external enum_attr_kind : string -> llattrkind = "llvm_enum_attr_kind"
+external llvm_create_enum_attr : llcontext -> llattrkind -> int64 ->
+ llattribute
+ = "llvm_create_enum_attr_by_kind"
+external is_enum_attr : llattribute -> bool = "llvm_is_enum_attr"
+external get_enum_attr_kind : llattribute -> llattrkind
+ = "llvm_get_enum_attr_kind"
+external get_enum_attr_value : llattribute -> int64
+ = "llvm_get_enum_attr_value"
+external llvm_create_string_attr : llcontext -> string -> string ->
+ llattribute
+ = "llvm_create_string_attr"
+external is_string_attr : llattribute -> bool = "llvm_is_string_attr"
+external get_string_attr_kind : llattribute -> string
+ = "llvm_get_string_attr_kind"
+external get_string_attr_value : llattribute -> string
+ = "llvm_get_string_attr_value"
+
+let create_enum_attr context name value =
+ llvm_create_enum_attr context (enum_attr_kind name) value
+let create_string_attr context kind value =
+ llvm_create_string_attr context kind value
+
+let attr_of_repr context repr =
+ match repr with
+ | AttrRepr.Enum(kind, value) -> llvm_create_enum_attr context kind value
+ | AttrRepr.String(key, value) -> llvm_create_string_attr context key value
+
+let repr_of_attr attr =
+ if is_enum_attr attr then
+ AttrRepr.Enum(get_enum_attr_kind attr, get_enum_attr_value attr)
+ else if is_string_attr attr then
+ AttrRepr.String(get_string_attr_kind attr, get_string_attr_value attr)
+ else assert false
(*===-- Modules -----------------------------------------------------------===*)
external create_module : llcontext -> string -> llmodule = "llvm_create_module"
external set_data_layout: string -> llmodule -> unit
= "llvm_set_data_layout"
external dump_module : llmodule -> unit = "llvm_dump_module"
+external print_module : string -> llmodule -> unit = "llvm_print_module"
+external string_of_llmodule : llmodule -> string = "llvm_string_of_llmodule"
external set_module_inline_asm : llmodule -> string -> unit
= "llvm_set_module_inline_asm"
external module_context : llmodule -> llcontext = "LLVMGetModuleContext"
external classify_type : lltype -> TypeKind.t = "llvm_classify_type"
external type_context : lltype -> llcontext = "llvm_type_context"
external type_is_sized : lltype -> bool = "llvm_type_is_sized"
+external dump_type : lltype -> unit = "llvm_dump_type"
+external string_of_lltype : lltype -> string = "llvm_string_of_lltype"
(*--... Operations on integer types ........................................--*)
external i1_type : llcontext -> lltype = "llvm_i1_type"
= "llvm_struct_element_types"
external is_packed : lltype -> bool = "llvm_is_packed"
external is_opaque : lltype -> bool = "llvm_is_opaque"
+external is_literal : lltype -> bool = "llvm_is_literal"
(*--... Operations on pointer, vector, and array types .....................--*)
+
+external subtypes : lltype -> lltype array = "llvm_subtypes"
external array_type : lltype -> int -> lltype = "llvm_array_type"
external pointer_type : lltype -> lltype = "llvm_pointer_type"
external qualified_pointer_type : lltype -> int -> lltype
(*--... Operations on other types ..........................................--*)
external void_type : llcontext -> lltype = "llvm_void_type"
external label_type : llcontext -> lltype = "llvm_label_type"
+external x86_mmx_type : llcontext -> lltype = "llvm_x86_mmx_type"
external type_by_name : llmodule -> string -> lltype option = "llvm_type_by_name"
external classify_value : llvalue -> ValueKind.t = "llvm_classify_value"
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"
+external string_of_llvalue : llvalue -> string = "llvm_string_of_llvalue"
external replace_all_uses_with : llvalue -> llvalue -> unit
= "llvm_replace_all_uses_with"
(*--... Operations on users ................................................--*)
external operand : llvalue -> int -> llvalue = "llvm_operand"
+external operand_use : llvalue -> int -> lluse = "llvm_operand_use"
external set_operand : llvalue -> int -> llvalue -> unit = "llvm_set_operand"
external num_operands : llvalue -> int = "llvm_num_operands"
(*--... Operations on instructions .........................................--*)
external has_metadata : llvalue -> bool = "llvm_has_metadata"
-external metadata : llvalue -> int -> llvalue option = "llvm_metadata"
-external set_metadata : llvalue -> int -> llvalue -> unit = "llvm_set_metadata"
-external clear_metadata : llvalue -> int -> unit = "llvm_clear_metadata"
+external metadata : llvalue -> llmdkind -> llvalue option = "llvm_metadata"
+external set_metadata : llvalue -> llmdkind -> llvalue -> unit = "llvm_set_metadata"
+external clear_metadata : llvalue -> llmdkind -> unit = "llvm_clear_metadata"
(*--... Operations on metadata .......,.....................................--*)
external mdstring : llcontext -> string -> llvalue = "llvm_mdstring"
external mdnode : llcontext -> llvalue array -> llvalue = "llvm_mdnode"
+external mdnull : llcontext -> llvalue = "llvm_mdnull"
external get_mdstring : llvalue -> string option = "llvm_get_mdstring"
-external get_named_metadata : llmodule -> string -> llvalue array = "llvm_get_namedmd"
+external get_mdnode_operands : llvalue -> llvalue array
+ = "llvm_get_mdnode_operands"
+external get_named_metadata : llmodule -> string -> llvalue array
+ = "llvm_get_namedmd"
+external add_named_metadata_operand : llmodule -> string -> llvalue -> unit
+ = "llvm_append_namedmd"
(*--... Operations on scalar constants .....................................--*)
external const_int : lltype -> int -> llvalue = "llvm_const_int"
external const_int_of_string : lltype -> string -> int -> llvalue
= "llvm_const_int_of_string"
external const_float : lltype -> float -> llvalue = "llvm_const_float"
+external float_of_const : llvalue -> float option
+ = "llvm_float_of_const"
external const_float_of_string : lltype -> string -> llvalue
= "llvm_const_float_of_string"
external const_packed_struct : llcontext -> llvalue array -> llvalue
= "llvm_const_packed_struct"
external const_vector : llvalue array -> llvalue = "llvm_const_vector"
+external string_of_const : llvalue -> string option = "llvm_string_of_const"
+external const_element : llvalue -> int -> llvalue = "llvm_const_element"
(*--... Constant expressions ...............................................--*)
external align_of : lltype -> llvalue = "LLVMAlignOf"
= "LLVMConstTruncOrBitCast"
external const_pointercast : llvalue -> lltype -> llvalue
= "LLVMConstPointerCast"
-external const_intcast : llvalue -> lltype -> llvalue = "LLVMConstIntCast"
+external const_intcast : llvalue -> lltype -> is_signed:bool -> llvalue
+ = "llvm_const_intcast"
external const_fpcast : llvalue -> lltype -> llvalue = "LLVMConstFPCast"
external const_select : llvalue -> llvalue -> llvalue -> llvalue
= "LLVMConstSelect"
external is_declaration : llvalue -> bool = "llvm_is_declaration"
external linkage : llvalue -> Linkage.t = "llvm_linkage"
external set_linkage : Linkage.t -> llvalue -> unit = "llvm_set_linkage"
+external unnamed_addr : llvalue -> bool = "llvm_unnamed_addr"
+external set_unnamed_addr : bool -> llvalue -> unit = "llvm_set_unnamed_addr"
external section : llvalue -> string = "llvm_section"
external set_section : string -> llvalue -> unit = "llvm_set_section"
external visibility : llvalue -> Visibility.t = "llvm_visibility"
external set_visibility : Visibility.t -> llvalue -> unit = "llvm_set_visibility"
+external dll_storage_class : llvalue -> DLLStorageClass.t = "llvm_dll_storage_class"
+external set_dll_storage_class : DLLStorageClass.t -> llvalue -> unit = "llvm_set_dll_storage_class"
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 remove_initializer : llvalue -> unit = "llvm_remove_initializer"
external is_thread_local : llvalue -> bool = "llvm_is_thread_local"
external set_thread_local : bool -> llvalue -> unit = "llvm_set_thread_local"
+external thread_local_mode : llvalue -> ThreadLocalMode.t
+ = "llvm_thread_local_mode"
+external set_thread_local_mode : ThreadLocalMode.t -> llvalue -> unit
+ = "llvm_set_thread_local_mode"
+external is_externally_initialized : llvalue -> bool
+ = "llvm_is_externally_initialized"
+external set_externally_initialized : bool -> llvalue -> unit
+ = "llvm_set_externally_initialized"
external global_begin : llmodule -> (llmodule, llvalue) llpos
= "llvm_global_begin"
external global_succ : llvalue -> (llmodule, llvalue) llpos
let fold_right_functions f m init =
fold_right_function_range f (function_end m) (At_start m) init
-external llvm_add_function_attr : llvalue -> int32 -> unit
+external llvm_add_function_attr : llvalue -> llattribute -> int -> unit
= "llvm_add_function_attr"
-external llvm_remove_function_attr : llvalue -> int32 -> unit
- = "llvm_remove_function_attr"
-external llvm_function_attr : llvalue -> int32 = "llvm_function_attr"
-
-let pack_attr (attr:Attribute.t) : int32 =
- match attr with
- Attribute.Zext -> Int32.shift_left 1l 0
- | Attribute.Sext -> Int32.shift_left 1l 1
- | Attribute.Noreturn -> Int32.shift_left 1l 2
- | Attribute.Inreg -> Int32.shift_left 1l 3
- | Attribute.Structret -> Int32.shift_left 1l 4
- | Attribute.Nounwind -> Int32.shift_left 1l 5
- | Attribute.Noalias -> Int32.shift_left 1l 6
- | Attribute.Byval -> Int32.shift_left 1l 7
- | Attribute.Nest -> Int32.shift_left 1l 8
- | Attribute.Readnone -> Int32.shift_left 1l 9
- | Attribute.Readonly -> Int32.shift_left 1l 10
- | Attribute.Noinline -> Int32.shift_left 1l 11
- | Attribute.Alwaysinline -> Int32.shift_left 1l 12
- | Attribute.Optsize -> Int32.shift_left 1l 13
- | Attribute.Ssp -> Int32.shift_left 1l 14
- | Attribute.Sspreq -> Int32.shift_left 1l 15
- | Attribute.Alignment n -> Int32.shift_left (Int32.of_int n) 16
- | Attribute.Nocapture -> Int32.shift_left 1l 21
- | Attribute.Noredzone -> Int32.shift_left 1l 22
- | Attribute.Noimplicitfloat -> Int32.shift_left 1l 23
- | Attribute.Naked -> Int32.shift_left 1l 24
- | Attribute.Inlinehint -> Int32.shift_left 1l 25
- | Attribute.Stackalignment n -> Int32.shift_left (Int32.of_int n) 26
- | Attribute.ReturnsTwice -> Int32.shift_left 1l 29
- | Attribute.UWTable -> Int32.shift_left 1l 30
- | Attribute.NonLazyBind -> Int32.shift_left 1l 31
-
-let unpack_attr (a : int32) : Attribute.t list =
- let l = ref [] in
- let check attr =
- Int32.logand (pack_attr attr) a in
- let checkattr attr =
- if (check attr) <> 0l then begin
- l := attr :: !l
- end
- in
- checkattr Attribute.Zext;
- checkattr Attribute.Sext;
- checkattr Attribute.Noreturn;
- checkattr Attribute.Inreg;
- checkattr Attribute.Structret;
- checkattr Attribute.Nounwind;
- checkattr Attribute.Noalias;
- checkattr Attribute.Byval;
- checkattr Attribute.Nest;
- checkattr Attribute.Readnone;
- checkattr Attribute.Readonly;
- checkattr Attribute.Noinline;
- checkattr Attribute.Alwaysinline;
- checkattr Attribute.Optsize;
- checkattr Attribute.Ssp;
- checkattr Attribute.Sspreq;
- let align = Int32.logand (Int32.shift_right_logical a 16) 31l in
- if align <> 0l then
- l := Attribute.Alignment (Int32.to_int align) :: !l;
- checkattr Attribute.Nocapture;
- checkattr Attribute.Noredzone;
- checkattr Attribute.Noimplicitfloat;
- checkattr Attribute.Naked;
- checkattr Attribute.Inlinehint;
- let stackalign = Int32.logand (Int32.shift_right_logical a 26) 7l in
- if stackalign <> 0l then
- l := Attribute.Stackalignment (Int32.to_int stackalign) :: !l;
- checkattr Attribute.ReturnsTwice;
- checkattr Attribute.UWTable;
- checkattr Attribute.NonLazyBind;
- !l;;
-
-let add_function_attr llval attr =
- llvm_add_function_attr llval (pack_attr attr)
-
-let remove_function_attr llval attr =
- llvm_remove_function_attr llval (pack_attr attr)
-
-let function_attr f = unpack_attr (llvm_function_attr f)
+external llvm_function_attrs : llvalue -> int -> llattribute array
+ = "llvm_function_attrs"
+external llvm_remove_enum_function_attr : llvalue -> llattrkind -> int -> unit
+ = "llvm_remove_enum_function_attr"
+external llvm_remove_string_function_attr : llvalue -> string -> int -> unit
+ = "llvm_remove_string_function_attr"
+
+let add_function_attr f a i =
+ llvm_add_function_attr f a (AttrIndex.to_int i)
+let function_attrs f i =
+ llvm_function_attrs f (AttrIndex.to_int i)
+let remove_enum_function_attr f k i =
+ llvm_remove_enum_function_attr f k (AttrIndex.to_int i)
+let remove_string_function_attr f k i =
+ llvm_remove_string_function_attr f k (AttrIndex.to_int i)
(*--... Operations on params ...............................................--*)
external params : llvalue -> llvalue array = "llvm_params"
external param : llvalue -> int -> llvalue = "llvm_param"
-external llvm_param_attr : llvalue -> int32 = "llvm_param_attr"
-let param_attr p = unpack_attr (llvm_param_attr p)
external param_parent : llvalue -> llvalue = "LLVMGetParamParent"
external param_begin : llvalue -> (llvalue, llvalue) llpos = "llvm_param_begin"
external param_succ : llvalue -> (llvalue, llvalue) llpos = "llvm_param_succ"
let fold_right_params f fn init =
fold_right_param_range f init (param_end fn) (At_start fn)
-external llvm_add_param_attr : llvalue -> int32 -> unit
- = "llvm_add_param_attr"
-external llvm_remove_param_attr : llvalue -> int32 -> unit
- = "llvm_remove_param_attr"
-
-let add_param_attr llval attr =
- llvm_add_param_attr llval (pack_attr attr)
-
-let remove_param_attr llval attr =
- llvm_remove_param_attr llval (pack_attr attr)
-
-external set_param_alignment : llvalue -> int -> unit
- = "llvm_set_param_alignment"
-
(*--... Operations on basic blocks .........................................--*)
external value_of_block : llbasicblock -> llvalue = "LLVMBasicBlockAsValue"
external value_is_block : llvalue -> bool = "llvm_value_is_block"
external basic_blocks : llvalue -> llbasicblock array = "llvm_basic_blocks"
external entry_block : llvalue -> llbasicblock = "LLVMGetEntryBasicBlock"
external delete_block : llbasicblock -> unit = "llvm_delete_block"
+external remove_block : llbasicblock -> unit = "llvm_remove_block"
+external move_block_before : llbasicblock -> llbasicblock -> unit
+ = "llvm_move_block_before"
+external move_block_after : llbasicblock -> llbasicblock -> unit
+ = "llvm_move_block_after"
external append_block : llcontext -> string -> llvalue -> llbasicblock
= "llvm_append_block"
external insert_block : llcontext -> string -> llbasicblock -> llbasicblock
external instr_opcode : llvalue -> Opcode.t = "llvm_instr_get_opcode"
external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate"
-
-external icmp_predicate : llvalue -> Icmp.t option = "llvm_instr_icmp_predicate"
+external fcmp_predicate : llvalue -> Fcmp.t option = "llvm_instr_fcmp_predicate"
+external instr_clone : llvalue -> llvalue = "llvm_instr_clone"
let rec iter_instrs_range f i e =
if i = e then () else
external set_instruction_call_conv: int -> llvalue -> unit
= "llvm_set_instruction_call_conv"
-external llvm_add_instruction_param_attr : llvalue -> int -> int32 -> unit
- = "llvm_add_instruction_param_attr"
-external llvm_remove_instruction_param_attr : llvalue -> int -> int32 -> unit
- = "llvm_remove_instruction_param_attr"
+external llvm_add_call_site_attr : llvalue -> llattribute -> int -> unit
+ = "llvm_add_call_site_attr"
+external llvm_call_site_attrs : llvalue -> int -> llattribute array
+ = "llvm_call_site_attrs"
+external llvm_remove_enum_call_site_attr : llvalue -> llattrkind -> int -> unit
+ = "llvm_remove_enum_call_site_attr"
+external llvm_remove_string_call_site_attr : llvalue -> string -> int -> unit
+ = "llvm_remove_string_call_site_attr"
+
+let add_call_site_attr f a i =
+ llvm_add_call_site_attr f a (AttrIndex.to_int i)
+let call_site_attrs f i =
+ llvm_call_site_attrs f (AttrIndex.to_int i)
+let remove_enum_call_site_attr f k i =
+ llvm_remove_enum_call_site_attr f k (AttrIndex.to_int i)
+let remove_string_call_site_attr f k i =
+ llvm_remove_string_call_site_attr f k (AttrIndex.to_int i)
+
+(*--... Operations on call and invoke instructions (only) ..................--*)
+external num_arg_operands : llvalue -> int = "llvm_num_arg_operands"
+external is_tail_call : llvalue -> bool = "llvm_is_tail_call"
+external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call"
+external get_normal_dest : llvalue -> llbasicblock = "LLVMGetNormalDest"
+external get_unwind_dest : llvalue -> llbasicblock = "LLVMGetUnwindDest"
+
+(*--... Operations on load/store instructions (only) .......................--*)
+external is_volatile : llvalue -> bool = "llvm_is_volatile"
+external set_volatile : bool -> llvalue -> unit = "llvm_set_volatile"
+
+(*--... Operations on terminators ..........................................--*)
+
+let is_terminator llv =
+ let open ValueKind in
+ let open Opcode in
+ match classify_value llv with
+ | Instruction (Br | IndirectBr | Invoke | Resume | Ret | Switch | Unreachable)
+ -> true
+ | _ -> false
+
+external successor : llvalue -> int -> llbasicblock = "llvm_successor"
+external set_successor : llvalue -> int -> llbasicblock -> unit
+ = "llvm_set_successor"
+external num_successors : llvalue -> int = "llvm_num_successors"
+
+let successors llv =
+ if not (is_terminator llv) then
+ raise (Invalid_argument "Llvm.successors can only be used on terminators")
+ else
+ Array.init (num_successors llv) (successor llv)
+
+let iter_successors f llv =
+ if not (is_terminator llv) then
+ raise (Invalid_argument "Llvm.iter_successors can only be used on terminators")
+ else
+ for i = 0 to num_successors llv - 1 do
+ f (successor llv i)
+ done
+
+let fold_successors f llv z =
+ if not (is_terminator llv) then
+ raise (Invalid_argument "Llvm.fold_successors can only be used on terminators")
+ else
+ let n = num_successors llv in
+ let rec aux i acc =
+ if i >= n then acc
+ else begin
+ let llb = successor llv i in
+ aux (i+1) (f llb acc)
+ end
+ in aux 0 z
-let add_instruction_param_attr llval i attr =
- llvm_add_instruction_param_attr llval i (pack_attr attr)
-let remove_instruction_param_attr llval i attr =
- llvm_remove_instruction_param_attr llval i (pack_attr attr)
+(*--... Operations on branches .............................................--*)
+external condition : llvalue -> llvalue = "llvm_condition"
+external set_condition : llvalue -> llvalue -> unit
+ = "llvm_set_condition"
+external is_conditional : llvalue -> bool = "llvm_is_conditional"
-(*--... Operations on call instructions (only) .............................--*)
-external is_tail_call : llvalue -> bool = "llvm_is_tail_call"
-external set_tail_call : bool -> llvalue -> unit = "llvm_set_tail_call"
+let get_branch llv =
+ if classify_value llv <> ValueKind.Instruction Opcode.Br then
+ None
+ else if is_conditional llv then
+ Some (`Conditional (condition llv, successor llv 0, successor llv 1))
+ else
+ Some (`Unconditional (successor llv 0))
(*--... Operations on phi nodes ............................................--*)
external add_incoming : (llvalue * llbasicblock) -> llvalue -> unit
= "llvm_build_load"
external build_store : llvalue -> llvalue -> llbuilder -> llvalue
= "llvm_build_store"
+external build_atomicrmw : AtomicRMWBinOp.t -> llvalue -> llvalue ->
+ AtomicOrdering.t -> bool -> string -> llbuilder ->
+ llvalue
+ = "llvm_build_atomicrmw_bytecode"
+ "llvm_build_atomicrmw_native"
external build_gep : llvalue -> llvalue array -> string -> llbuilder -> llvalue
= "llvm_build_gep"
external build_in_bounds_gep : llvalue -> llvalue array -> string ->
(*--... Miscellaneous instructions .........................................--*)
external build_phi : (llvalue * llbasicblock) list -> string -> llbuilder ->
llvalue = "llvm_build_phi"
+external build_empty_phi : lltype -> string -> llbuilder -> llvalue
+ = "llvm_build_empty_phi"
external build_call : llvalue -> llvalue array -> string -> llbuilder -> llvalue
= "llvm_build_call"
external build_select : llvalue -> llvalue -> llvalue -> string -> llbuilder ->
module MemoryBuffer = struct
external of_file : string -> llmemorybuffer = "llvm_memorybuffer_of_file"
external of_stdin : unit -> llmemorybuffer = "llvm_memorybuffer_of_stdin"
+ external of_string : ?name:string -> string -> llmemorybuffer
+ = "llvm_memorybuffer_of_string"
+ external as_string : llmemorybuffer -> string = "llvm_memorybuffer_as_string"
external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose"
end
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. *)
-
-let concat2 sep arr =
- let s = ref "" in
- if 0 < Array.length arr then begin
- s := !s ^ arr.(0);
- for i = 1 to (Array.length arr) - 1 do
- s := !s ^ sep ^ arr.(i)
- done
- end;
- !s
-
-let rec string_of_lltype ty =
- (* FIXME: stop infinite recursion! :) *)
- match classify_type ty with
- TypeKind.Integer -> "i" ^ string_of_int (integer_bitwidth ty)
- | TypeKind.Pointer ->
- (let ety = element_type ty in
- match classify_type ety with
- | TypeKind.Struct ->
- (match struct_name ety with
- | None -> (string_of_lltype ety)
- | Some s -> s) ^ "*"
- | _ -> (string_of_lltype (element_type ty)) ^ "*")
- | TypeKind.Struct ->
- let s = "{ " ^ (concat2 ", " (
- Array.map string_of_lltype (struct_element_types ty)
- )) ^ " }" in
- if is_packed ty
- then "<" ^ s ^ ">"
- else s
- | 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.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.Half -> "half"
- | TypeKind.Void -> "void"
- | TypeKind.Metadata -> "metadata"