Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Standalone View
llvm/bindings/ocaml/target/target_ocaml.c
/*===-- target_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\ | /*===-- target_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\ | ||||
|* *| | |* *| | ||||
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| | |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| | ||||
|* Exceptions. *| | |* Exceptions. *| | ||||
|* See https://llvm.org/LICENSE.txt for license information. *| | |* See https://llvm.org/LICENSE.txt for license information. *| | ||||
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| | |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| | ||||
|* *| | |* *| | ||||
|*===----------------------------------------------------------------------===*| | |*===----------------------------------------------------------------------===*| | ||||
|* *| | |* *| | ||||
|* This file glues LLVM's OCaml interface to its C interface. These functions *| | |* This file glues LLVM's OCaml interface to its C interface. These functions *| | ||||
|* are by and large transparent wrappers to the corresponding C functions. *| | |* are by and large transparent wrappers to the corresponding C functions. *| | ||||
|* *| | |* *| | ||||
|* Note that these functions intentionally take liberties with the CAMLparamX *| | |||||
|* macros, since most of the parameters are not GC heap objects. *| | |||||
|* *| | |||||
\*===----------------------------------------------------------------------===*/ | \*===----------------------------------------------------------------------===*/ | ||||
#include "llvm-c/Core.h" | #include "llvm-c/Core.h" | ||||
#include "llvm-c/Target.h" | #include "llvm-c/Target.h" | ||||
#include "llvm-c/TargetMachine.h" | #include "llvm-c/TargetMachine.h" | ||||
#include "caml/alloc.h" | #include "caml/alloc.h" | ||||
#include "caml/fail.h" | #include "caml/fail.h" | ||||
#include "caml/memory.h" | #include "caml/memory.h" | ||||
Show All 18 Lines | static struct custom_operations llvm_data_layout_ops = { | ||||
custom_compare_default, | custom_compare_default, | ||||
custom_hash_default, | custom_hash_default, | ||||
custom_serialize_default, | custom_serialize_default, | ||||
custom_deserialize_default, | custom_deserialize_default, | ||||
custom_compare_ext_default}; | custom_compare_ext_default}; | ||||
value llvm_alloc_data_layout(LLVMTargetDataRef DataLayout) { | value llvm_alloc_data_layout(LLVMTargetDataRef DataLayout) { | ||||
value V = | value V = | ||||
alloc_custom(&llvm_data_layout_ops, sizeof(LLVMTargetDataRef), 0, 1); | caml_alloc_custom(&llvm_data_layout_ops, sizeof(LLVMTargetDataRef), 0, 1); | ||||
DataLayout_val(V) = DataLayout; | DataLayout_val(V) = DataLayout; | ||||
return V; | return V; | ||||
} | } | ||||
/* string -> DataLayout.t */ | /* string -> DataLayout.t */ | ||||
value llvm_datalayout_of_string(value StringRep) { | value llvm_datalayout_of_string(value StringRep) { | ||||
return llvm_alloc_data_layout(LLVMCreateTargetData(String_val(StringRep))); | CAMLparam1(StringRep); | ||||
CAMLreturn( | |||||
llvm_alloc_data_layout(LLVMCreateTargetData(String_val(StringRep)))); | |||||
jberdine: left over | |||||
} | } | ||||
/* DataLayout.t -> string */ | /* DataLayout.t -> string */ | ||||
value llvm_datalayout_as_string(value TD) { | value llvm_datalayout_as_string(value TD) { | ||||
CAMLparam1(TD); | |||||
CAMLlocal1(Copy); | |||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
char *StringRep = LLVMCopyStringRepOfTargetData(DataLayout_val(TD)); | char *StringRep = LLVMCopyStringRepOfTargetData(DataLayout_val(TD)); | ||||
value Copy = copy_string(StringRep); | Copy = caml_copy_string(StringRep); | ||||
LLVMDisposeMessage(StringRep); | LLVMDisposeMessage(StringRep); | ||||
return Copy; | CAMLreturn(Copy); | ||||
} | } | ||||
/* DataLayout.t -> Endian.t */ | /* DataLayout.t -> Endian.t */ | ||||
value llvm_datalayout_byte_order(value DL) { | value llvm_datalayout_byte_order(value DL) { | ||||
return Val_int(LLVMByteOrder(DataLayout_val(DL))); | CAMLparam1(DL); | ||||
CAMLreturn(Val_int(LLVMByteOrder(DataLayout_val(DL)))); | |||||
} | } | ||||
/* DataLayout.t -> int */ | /* DataLayout.t -> int */ | ||||
value llvm_datalayout_pointer_size(value DL) { | value llvm_datalayout_pointer_size(value DL) { | ||||
return Val_int(LLVMPointerSize(DataLayout_val(DL))); | CAMLparam1(DL); | ||||
CAMLreturn(Val_int(LLVMPointerSize(DataLayout_val(DL)))); | |||||
} | } | ||||
/* Llvm.llcontext -> DataLayout.t -> Llvm.lltype */ | /* Llvm.llcontext -> DataLayout.t -> Llvm.lltype */ | ||||
LLVMTypeRef llvm_datalayout_intptr_type(LLVMContextRef C, value DL) { | value llvm_datalayout_intptr_type(value C, value DL) { | ||||
return LLVMIntPtrTypeInContext(C, DataLayout_val(DL)); | CAMLparam2(C, DL); | ||||
LLVMTypeRef Type = | |||||
LLVMIntPtrTypeInContext(Context_val(C), DataLayout_val(DL)); | |||||
CAMLreturn(to_val(Type)); | |||||
} | } | ||||
/* int -> DataLayout.t -> int */ | /* int -> DataLayout.t -> int */ | ||||
value llvm_datalayout_qualified_pointer_size(value AS, value DL) { | value llvm_datalayout_qualified_pointer_size(value AS, value DL) { | ||||
return Val_int(LLVMPointerSizeForAS(DataLayout_val(DL), Int_val(AS))); | CAMLparam2(AS, DL); | ||||
CAMLreturn(Val_int(LLVMPointerSizeForAS(DataLayout_val(DL), Int_val(AS)))); | |||||
} | } | ||||
/* Llvm.llcontext -> int -> DataLayout.t -> Llvm.lltype */ | /* Llvm.llcontext -> int -> DataLayout.t -> Llvm.lltype */ | ||||
LLVMTypeRef llvm_datalayout_qualified_intptr_type(LLVMContextRef C, value AS, | value llvm_datalayout_qualified_intptr_type(value C, value AS, value DL) { | ||||
value DL) { | CAMLparam3(C, AS, DL); | ||||
return LLVMIntPtrTypeForASInContext(C, DataLayout_val(DL), Int_val(AS)); | LLVMTypeRef Type = LLVMIntPtrTypeForASInContext( | ||||
Context_val(C), DataLayout_val(DL), Int_val(AS)); | |||||
CAMLreturn(to_val(Type)); | |||||
} | } | ||||
/* Llvm.lltype -> DataLayout.t -> Int64.t */ | /* Llvm.lltype -> DataLayout.t -> Int64.t */ | ||||
value llvm_datalayout_size_in_bits(LLVMTypeRef Ty, value DL) { | value llvm_datalayout_size_in_bits(value Ty, value DL) { | ||||
return caml_copy_int64(LLVMSizeOfTypeInBits(DataLayout_val(DL), Ty)); | CAMLparam2(Ty, DL); | ||||
CAMLreturn( | |||||
caml_copy_int64(LLVMSizeOfTypeInBits(DataLayout_val(DL), Type_val(Ty)))); | |||||
} | } | ||||
/* Llvm.lltype -> DataLayout.t -> Int64.t */ | /* Llvm.lltype -> DataLayout.t -> Int64.t */ | ||||
value llvm_datalayout_store_size(LLVMTypeRef Ty, value DL) { | value llvm_datalayout_store_size(value Ty, value DL) { | ||||
return caml_copy_int64(LLVMStoreSizeOfType(DataLayout_val(DL), Ty)); | CAMLparam2(Ty, DL); | ||||
CAMLreturn( | |||||
caml_copy_int64(LLVMStoreSizeOfType(DataLayout_val(DL), Type_val(Ty)))); | |||||
} | } | ||||
/* Llvm.lltype -> DataLayout.t -> Int64.t */ | /* Llvm.lltype -> DataLayout.t -> Int64.t */ | ||||
value llvm_datalayout_abi_size(LLVMTypeRef Ty, value DL) { | value llvm_datalayout_abi_size(value Ty, value DL) { | ||||
return caml_copy_int64(LLVMABISizeOfType(DataLayout_val(DL), Ty)); | CAMLparam2(Ty, DL); | ||||
CAMLreturn( | |||||
caml_copy_int64(LLVMABISizeOfType(DataLayout_val(DL), Type_val(Ty)))); | |||||
} | } | ||||
/* Llvm.lltype -> DataLayout.t -> int */ | /* Llvm.lltype -> DataLayout.t -> int */ | ||||
value llvm_datalayout_abi_align(LLVMTypeRef Ty, value DL) { | value llvm_datalayout_abi_align(value Ty, value DL) { | ||||
return Val_int(LLVMABIAlignmentOfType(DataLayout_val(DL), Ty)); | CAMLparam2(Ty, DL); | ||||
CAMLreturn(Val_int(LLVMABIAlignmentOfType(DataLayout_val(DL), Type_val(Ty)))); | |||||
} | } | ||||
/* Llvm.lltype -> DataLayout.t -> int */ | /* Llvm.lltype -> DataLayout.t -> int */ | ||||
value llvm_datalayout_stack_align(LLVMTypeRef Ty, value DL) { | value llvm_datalayout_stack_align(value Ty, value DL) { | ||||
return Val_int(LLVMCallFrameAlignmentOfType(DataLayout_val(DL), Ty)); | CAMLparam2(Ty, DL); | ||||
CAMLreturn( | |||||
Val_int(LLVMCallFrameAlignmentOfType(DataLayout_val(DL), Type_val(Ty)))); | |||||
} | } | ||||
/* Llvm.lltype -> DataLayout.t -> int */ | /* Llvm.lltype -> DataLayout.t -> int */ | ||||
value llvm_datalayout_preferred_align(LLVMTypeRef Ty, value DL) { | value llvm_datalayout_preferred_align(value Ty, value DL) { | ||||
return Val_int(LLVMPreferredAlignmentOfType(DataLayout_val(DL), Ty)); | CAMLparam2(Ty, DL); | ||||
CAMLreturn( | |||||
Val_int(LLVMPreferredAlignmentOfType(DataLayout_val(DL), Type_val(Ty)))); | |||||
} | } | ||||
/* Llvm.llvalue -> DataLayout.t -> int */ | /* Llvm.llvalue -> DataLayout.t -> int */ | ||||
value llvm_datalayout_preferred_align_of_global(LLVMValueRef GlobalVar, | value llvm_datalayout_preferred_align_of_global(value GlobalVar, value DL) { | ||||
value DL) { | CAMLparam2(GlobalVar, DL); | ||||
return Val_int(LLVMPreferredAlignmentOfGlobal(DataLayout_val(DL), GlobalVar)); | CAMLreturn(Val_int(LLVMPreferredAlignmentOfGlobal(DataLayout_val(DL), | ||||
Value_val(GlobalVar)))); | |||||
} | } | ||||
/* Llvm.lltype -> Int64.t -> DataLayout.t -> int */ | /* Llvm.lltype -> Int64.t -> DataLayout.t -> int */ | ||||
value llvm_datalayout_element_at_offset(LLVMTypeRef Ty, value Offset, | value llvm_datalayout_element_at_offset(value Ty, value Offset, value DL) { | ||||
value DL) { | CAMLparam3(Ty, Offset, DL); | ||||
return Val_int( | CAMLreturn(Val_int(LLVMElementAtOffset(DataLayout_val(DL), Type_val(Ty), | ||||
LLVMElementAtOffset(DataLayout_val(DL), Ty, Int64_val(Offset))); | Int64_val(Offset)))); | ||||
} | } | ||||
/* Llvm.lltype -> int -> DataLayout.t -> Int64.t */ | /* Llvm.lltype -> int -> DataLayout.t -> Int64.t */ | ||||
value llvm_datalayout_offset_of_element(LLVMTypeRef Ty, value Index, value DL) { | value llvm_datalayout_offset_of_element(value Ty, value Index, value DL) { | ||||
return caml_copy_int64( | CAMLparam3(Ty, Index, DL); | ||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
This root is necessary. DataLayout.t is an OCaml custom block, not a pointer with the low bit set. Int64.t is also boxed. So, this function allocates on the OCaml heap and the GC needs to know that DL is live. alan: This root is necessary. `DataLayout.t` is an OCaml custom block, not a pointer with the low bit… | |||||
Not Done ReplyInline ActionsI understand that DL is a custom block, but its value is only used before the allocation in caml_copy_int64. This is the same before and after this diff, or am I overlooking something? jberdine: I understand that `DL` is a custom block, but its value is only used before the allocation in… | |||||
DL is a parameter, so it needs to be live when the function ends. Otherwise, a caller could pass a DataLayout.t value, and that value could be invalidated by the GC during the function call. alan: `DL` is a parameter, so it needs to be live when the function ends. Otherwise, a caller could… | |||||
Not Done ReplyInline ActionsI'm sorry but I still don't understand. Suppose the GC runs when caml_copy_int64 allocates, and happens to move the value DL points to. Then note that DL is no longer needed since it is used only to compute the argument of LLVMOffsetOfElement and in particular is dead after the allocation in caml_copy_int64. Also, if the caller of llvm_datalayout_offset_of_element needs what it passed as the DL argument, then it will be live and a root in the caller, and the GC will update the caller's pointer when moving the block pointed to by DL. So I don't see the issue, but I am not sure I understand the point you are making. Do you see what I mean? jberdine: I'm sorry but I still don't understand. Suppose the GC runs when `caml_copy_int64` allocates… | |||||
You're right, I made a mistake. I didn't consider that if the caller still needed to keep DL around, the caller stack frame would already have DL as a root, so this function doesn't need to register it as a root. Thank you for reviewing my code and pointing this out. alan: You're right, I made a mistake. I didn't consider that if the caller still needed to keep `DL`… | |||||
LLVMOffsetOfElement(DataLayout_val(DL), Ty, Int_val(Index))); | CAMLreturn(caml_copy_int64( | ||||
LLVMOffsetOfElement(DataLayout_val(DL), Type_val(Ty), Int_val(Index)))); | |||||
} | } | ||||
/*===---- Target ----------------------------------------------------------===*/ | /*===---- Target ----------------------------------------------------------===*/ | ||||
#define Target_val(v) ((LLVMTargetRef)from_val(v)) | |||||
/* unit -> string */ | /* unit -> string */ | ||||
value llvm_target_default_triple(value Unit) { | value llvm_target_default_triple(value Unit) { | ||||
CAMLparam1(Unit); | |||||
CAMLlocal1(TripleStr); | |||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
char *TripleCStr = LLVMGetDefaultTargetTriple(); | char *TripleCStr = LLVMGetDefaultTargetTriple(); | ||||
value TripleStr = caml_copy_string(TripleCStr); | TripleStr = caml_copy_string(TripleCStr); | ||||
LLVMDisposeMessage(TripleCStr); | LLVMDisposeMessage(TripleCStr); | ||||
CAMLreturn(TripleStr); | |||||
return TripleStr; | |||||
} | } | ||||
/* unit -> Target.t option */ | /* unit -> Target.t option */ | ||||
value llvm_target_first(value Unit) { | value llvm_target_first(value Unit) { | ||||
return ptr_to_option(LLVMGetFirstTarget()); | CAMLparam1(Unit); | ||||
CAMLreturn(ptr_to_option(LLVMGetFirstTarget())); | |||||
} | } | ||||
/* Target.t -> Target.t option */ | /* Target.t -> Target.t option */ | ||||
value llvm_target_succ(LLVMTargetRef Target) { | value llvm_target_succ(value Target) { | ||||
return ptr_to_option(LLVMGetNextTarget(Target)); | CAMLparam1(Target); | ||||
CAMLreturn(ptr_to_option(LLVMGetNextTarget(Target_val(Target)))); | |||||
} | } | ||||
/* string -> Target.t option */ | /* string -> Target.t option */ | ||||
value llvm_target_by_name(value Name) { | value llvm_target_by_name(value Name) { | ||||
return ptr_to_option(LLVMGetTargetFromName(String_val(Name))); | CAMLparam1(Name); | ||||
CAMLreturn(ptr_to_option(LLVMGetTargetFromName(String_val(Name)))); | |||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
} | } | ||||
/* string -> Target.t */ | /* string -> Target.t */ | ||||
LLVMTargetRef llvm_target_by_triple(value Triple) { | value llvm_target_by_triple(value Triple) { | ||||
CAMLparam1(Triple); | |||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
LLVMTargetRef T; | LLVMTargetRef T; | ||||
char *Error; | char *Error; | ||||
if (LLVMGetTargetFromTriple(String_val(Triple), &T, &Error)) | if (LLVMGetTargetFromTriple(String_val(Triple), &T, &Error)) | ||||
llvm_raise(*caml_named_value("Llvm_target.Error"), Error); | llvm_raise(*caml_named_value("Llvm_target.Error"), Error); | ||||
return T; | CAMLreturn(to_val(T)); | ||||
} | } | ||||
/* Target.t -> string */ | /* Target.t -> string */ | ||||
value llvm_target_name(LLVMTargetRef Target) { | value llvm_target_name(value Target) { | ||||
return caml_copy_string(LLVMGetTargetName(Target)); | CAMLparam1(Target); | ||||
CAMLreturn(caml_copy_string(LLVMGetTargetName(Target_val(Target)))); | |||||
} | } | ||||
/* Target.t -> string */ | /* Target.t -> string */ | ||||
value llvm_target_description(LLVMTargetRef Target) { | value llvm_target_description(value Target) { | ||||
return caml_copy_string(LLVMGetTargetDescription(Target)); | CAMLparam1(Target); | ||||
CAMLreturn(caml_copy_string(LLVMGetTargetDescription(Target_val(Target)))); | |||||
} | } | ||||
/* Target.t -> bool */ | /* Target.t -> bool */ | ||||
value llvm_target_has_jit(LLVMTargetRef Target) { | value llvm_target_has_jit(value Target) { | ||||
return Val_bool(LLVMTargetHasJIT(Target)); | CAMLparam1(Target); | ||||
CAMLreturn(Val_bool(LLVMTargetHasJIT(Target_val(Target)))); | |||||
} | } | ||||
/* Target.t -> bool */ | /* Target.t -> bool */ | ||||
value llvm_target_has_target_machine(LLVMTargetRef Target) { | value llvm_target_has_target_machine(value Target) { | ||||
return Val_bool(LLVMTargetHasTargetMachine(Target)); | CAMLparam1(Target); | ||||
CAMLreturn(Val_bool(LLVMTargetHasTargetMachine(Target_val(Target)))); | |||||
} | } | ||||
/* Target.t -> bool */ | /* Target.t -> bool */ | ||||
value llvm_target_has_asm_backend(LLVMTargetRef Target) { | value llvm_target_has_asm_backend(value Target) { | ||||
return Val_bool(LLVMTargetHasAsmBackend(Target)); | CAMLparam1(Target); | ||||
CAMLreturn(Val_bool(LLVMTargetHasAsmBackend(Target_val(Target)))); | |||||
} | } | ||||
/*===---- Target Machine --------------------------------------------------===*/ | /*===---- Target Machine --------------------------------------------------===*/ | ||||
#define TargetMachine_val(v) (*(LLVMTargetMachineRef *)(Data_custom_val(v))) | #define TargetMachine_val(v) (*(LLVMTargetMachineRef *)(Data_custom_val(v))) | ||||
static void llvm_finalize_target_machine(value Machine) { | static void llvm_finalize_target_machine(value Machine) { | ||||
LLVMDisposeTargetMachine(TargetMachine_val(Machine)); | LLVMDisposeTargetMachine(TargetMachine_val(Machine)); | ||||
} | } | ||||
static struct custom_operations llvm_target_machine_ops = { | static struct custom_operations llvm_target_machine_ops = { | ||||
(char *)"Llvm_target.TargetMachine.t", | (char *)"Llvm_target.TargetMachine.t", | ||||
llvm_finalize_target_machine, | llvm_finalize_target_machine, | ||||
custom_compare_default, | custom_compare_default, | ||||
custom_hash_default, | custom_hash_default, | ||||
custom_serialize_default, | custom_serialize_default, | ||||
custom_deserialize_default, | custom_deserialize_default, | ||||
custom_compare_ext_default}; | custom_compare_ext_default}; | ||||
static value llvm_alloc_targetmachine(LLVMTargetMachineRef Machine) { | static value llvm_alloc_targetmachine(LLVMTargetMachineRef Machine) { | ||||
value V = alloc_custom(&llvm_target_machine_ops, sizeof(LLVMTargetMachineRef), | value V = caml_alloc_custom(&llvm_target_machine_ops, | ||||
0, 1); | sizeof(LLVMTargetMachineRef), 0, 1); | ||||
TargetMachine_val(V) = Machine; | TargetMachine_val(V) = Machine; | ||||
return V; | return V; | ||||
} | } | ||||
/* triple:string -> ?cpu:string -> ?features:string | /* triple:string -> ?cpu:string -> ?features:string | ||||
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t | ?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t | ||||
?code_model:CodeModel.t -> Target.t -> TargetMachine.t */ | ?code_model:CodeModel.t -> Target.t -> TargetMachine.t */ | ||||
value llvm_create_targetmachine_native(value Triple, value CPU, value Features, | value llvm_create_targetmachine_native(value Triple, value CPU, value Features, | ||||
value OptLevel, value RelocMode, | value OptLevel, value RelocMode, | ||||
value CodeModel, LLVMTargetRef Target) { | value CodeModel, value Target) { | ||||
CAMLparam5(Triple, CPU, Features, OptLevel, RelocMode); | |||||
CAMLxparam2(CodeModel, Target); | |||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
LLVMTargetMachineRef Machine; | LLVMTargetMachineRef Machine; | ||||
const char *CPUStr = "", *FeaturesStr = ""; | const char *CPUStr = "", *FeaturesStr = ""; | ||||
LLVMCodeGenOptLevel OptLevelEnum = LLVMCodeGenLevelDefault; | LLVMCodeGenOptLevel OptLevelEnum = LLVMCodeGenLevelDefault; | ||||
LLVMRelocMode RelocModeEnum = LLVMRelocDefault; | LLVMRelocMode RelocModeEnum = LLVMRelocDefault; | ||||
LLVMCodeModel CodeModelEnum = LLVMCodeModelDefault; | LLVMCodeModel CodeModelEnum = LLVMCodeModelDefault; | ||||
if (CPU != Val_int(0)) | if (CPU != Val_int(0)) | ||||
CPUStr = String_val(Field(CPU, 0)); | CPUStr = String_val(Field(CPU, 0)); | ||||
if (Features != Val_int(0)) | if (Features != Val_int(0)) | ||||
FeaturesStr = String_val(Field(Features, 0)); | FeaturesStr = String_val(Field(Features, 0)); | ||||
if (OptLevel != Val_int(0)) | if (OptLevel != Val_int(0)) | ||||
OptLevelEnum = Int_val(Field(OptLevel, 0)); | OptLevelEnum = Int_val(Field(OptLevel, 0)); | ||||
if (RelocMode != Val_int(0)) | if (RelocMode != Val_int(0)) | ||||
RelocModeEnum = Int_val(Field(RelocMode, 0)); | RelocModeEnum = Int_val(Field(RelocMode, 0)); | ||||
if (CodeModel != Val_int(0)) | if (CodeModel != Val_int(0)) | ||||
CodeModelEnum = Int_val(Field(CodeModel, 0)); | CodeModelEnum = Int_val(Field(CodeModel, 0)); | ||||
Machine = | Machine = LLVMCreateTargetMachine(Target_val(Target), String_val(Triple), | ||||
LLVMCreateTargetMachine(Target, String_val(Triple), CPUStr, FeaturesStr, | CPUStr, FeaturesStr, OptLevelEnum, | ||||
OptLevelEnum, RelocModeEnum, CodeModelEnum); | RelocModeEnum, CodeModelEnum); | ||||
return llvm_alloc_targetmachine(Machine); | CAMLreturn(llvm_alloc_targetmachine(Machine)); | ||||
} | } | ||||
value llvm_create_targetmachine_bytecode(value *argv, int argn) { | value llvm_create_targetmachine_bytecode(value *argv, int argn) { | ||||
return llvm_create_targetmachine_native(argv[0], argv[1], argv[2], argv[3], | return llvm_create_targetmachine_native(argv[0], argv[1], argv[2], argv[3], | ||||
argv[4], argv[5], | argv[4], argv[5], argv[6]); | ||||
(LLVMTargetRef)argv[6]); | |||||
} | } | ||||
/* TargetMachine.t -> Target.t */ | /* TargetMachine.t -> Target.t */ | ||||
LLVMTargetRef llvm_targetmachine_target(value Machine) { | value llvm_targetmachine_target(value Machine) { | ||||
return LLVMGetTargetMachineTarget(TargetMachine_val(Machine)); | CAMLparam1(Machine); | ||||
CAMLreturn(to_val(LLVMGetTargetMachineTarget(TargetMachine_val(Machine)))); | |||||
} | } | ||||
/* TargetMachine.t -> string */ | /* TargetMachine.t -> string */ | ||||
value llvm_targetmachine_triple(value Machine) { | value llvm_targetmachine_triple(value Machine) { | ||||
return llvm_string_of_message( | CAMLparam1(Machine); | ||||
LLVMGetTargetMachineTriple(TargetMachine_val(Machine))); | CAMLreturn(llvm_string_of_message( | ||||
LLVMGetTargetMachineTriple(TargetMachine_val(Machine)))); | |||||
} | } | ||||
/* TargetMachine.t -> string */ | /* TargetMachine.t -> string */ | ||||
value llvm_targetmachine_cpu(value Machine) { | value llvm_targetmachine_cpu(value Machine) { | ||||
return llvm_string_of_message( | CAMLparam1(Machine); | ||||
LLVMGetTargetMachineCPU(TargetMachine_val(Machine))); | CAMLreturn(llvm_string_of_message( | ||||
LLVMGetTargetMachineCPU(TargetMachine_val(Machine)))); | |||||
} | } | ||||
/* TargetMachine.t -> string */ | /* TargetMachine.t -> string */ | ||||
value llvm_targetmachine_features(value Machine) { | value llvm_targetmachine_features(value Machine) { | ||||
return llvm_string_of_message( | CAMLparam1(Machine); | ||||
LLVMGetTargetMachineFeatureString(TargetMachine_val(Machine))); | CAMLreturn(llvm_string_of_message( | ||||
LLVMGetTargetMachineFeatureString(TargetMachine_val(Machine)))); | |||||
} | } | ||||
/* TargetMachine.t -> DataLayout.t */ | /* TargetMachine.t -> DataLayout.t */ | ||||
value llvm_targetmachine_data_layout(value Machine) { | value llvm_targetmachine_data_layout(value Machine) { | ||||
return llvm_alloc_data_layout( | CAMLparam1(Machine); | ||||
LLVMCreateTargetDataLayout(TargetMachine_val(Machine))); | CAMLreturn(llvm_alloc_data_layout( | ||||
LLVMCreateTargetDataLayout(TargetMachine_val(Machine)))); | |||||
} | } | ||||
/* bool -> TargetMachine.t -> unit */ | /* bool -> TargetMachine.t -> unit */ | ||||
value llvm_targetmachine_set_verbose_asm(value Verb, value Machine) { | value llvm_targetmachine_set_verbose_asm(value Verb, value Machine) { | ||||
CAMLparam2(Verb, Machine); | |||||
LLVMSetTargetMachineAsmVerbosity(TargetMachine_val(Machine), Bool_val(Verb)); | LLVMSetTargetMachineAsmVerbosity(TargetMachine_val(Machine), Bool_val(Verb)); | ||||
return Val_unit; | CAMLreturn(Val_unit); | ||||
} | } | ||||
/* Llvm.llmodule -> CodeGenFileType.t -> string -> TargetMachine.t -> unit */ | /* Llvm.llmodule -> CodeGenFileType.t -> string -> TargetMachine.t -> unit */ | ||||
value llvm_targetmachine_emit_to_file(LLVMModuleRef Module, value FileType, | value llvm_targetmachine_emit_to_file(value Module, value FileType, | ||||
value FileName, value Machine) { | value FileName, value Machine) { | ||||
CAMLparam4(Module, FileType, FileName, Machine); | |||||
Not Done ReplyInline Actionsleft over jberdine: left over | |||||
char *ErrorMessage; | char *ErrorMessage; | ||||
if (LLVMTargetMachineEmitToFile(TargetMachine_val(Machine), Module, | if (LLVMTargetMachineEmitToFile( | ||||
(char *)String_val(FileName), | TargetMachine_val(Machine), Module_val(Module), | ||||
Int_val(FileType), &ErrorMessage)) { | (char *)String_val(FileName), Int_val(FileType), &ErrorMessage)) { | ||||
llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage); | llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage); | ||||
} | } | ||||
return Val_unit; | CAMLreturn(Val_unit); | ||||
} | } | ||||
/* Llvm.llmodule -> CodeGenFileType.t -> TargetMachine.t -> | /* Llvm.llmodule -> CodeGenFileType.t -> TargetMachine.t -> | ||||
Llvm.llmemorybuffer */ | Llvm.llmemorybuffer */ | ||||
LLVMMemoryBufferRef | value llvm_targetmachine_emit_to_memory_buffer(value Module, value FileType, | ||||
llvm_targetmachine_emit_to_memory_buffer(LLVMModuleRef Module, value FileType, | |||||
value Machine) { | value Machine) { | ||||
CAMLparam3(Module, FileType, Machine); | |||||
char *ErrorMessage; | char *ErrorMessage; | ||||
LLVMMemoryBufferRef Buffer; | LLVMMemoryBufferRef Buffer; | ||||
if (LLVMTargetMachineEmitToMemoryBuffer(TargetMachine_val(Machine), Module, | if (LLVMTargetMachineEmitToMemoryBuffer(TargetMachine_val(Machine), | ||||
Int_val(FileType), &ErrorMessage, | Module_val(Module), Int_val(FileType), | ||||
&Buffer)) { | &ErrorMessage, &Buffer)) { | ||||
llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage); | llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage); | ||||
} | } | ||||
return Buffer; | CAMLreturn(to_val(Buffer)); | ||||
} | } | ||||
/* TargetMachine.t -> Llvm.PassManager.t -> unit */ | /* TargetMachine.t -> Llvm.PassManager.t -> unit */ | ||||
value llvm_targetmachine_add_analysis_passes(LLVMPassManagerRef PM, | value llvm_targetmachine_add_analysis_passes(value PM, value Machine) { | ||||
value Machine) { | CAMLparam2(PM, Machine); | ||||
LLVMAddAnalysisPasses(TargetMachine_val(Machine), PM); | LLVMAddAnalysisPasses(TargetMachine_val(Machine), PassManager_val(PM)); | ||||
return Val_unit; | CAMLreturn(Val_unit); | ||||
} | } |
left over