[OCaml] De-duplicate llvm_raise and llvm_string_of_message.
[oota-llvm.git] / bindings / ocaml / executionengine / executionengine_ocaml.c
index 4af771123c0c096229f7045bd3441928c421871e..c647d23133c3be504b942163212eba0ed4616a7b 100644 (file)
@@ -1,4 +1,4 @@
-/*===-- executionengine_ocaml.c - LLVM Ocaml Glue ---------------*- C++ -*-===*\
+/*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
 |*                                                                            *|
 |*                     The LLVM Compiler Infrastructure                       *|
 |*                                                                            *|
@@ -7,7 +7,7 @@
 |*                                                                            *|
 |*===----------------------------------------------------------------------===*|
 |*                                                                            *|
-|* 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.    *|
 |*                                                                            *|
 |* Note that these functions intentionally take liberties with the CAMLparamX *|
 |*                                                                            *|
 \*===----------------------------------------------------------------------===*/
 
+#include <string.h>
+#include <assert.h>
 #include "llvm-c/ExecutionEngine.h"
+#include "llvm-c/Target.h"
 #include "caml/alloc.h"
 #include "caml/custom.h"
 #include "caml/fail.h"
 #include "caml/memory.h"
-#include <string.h>
-#include <assert.h>
-
-
-/* Can't use the recommended caml_named_value mechanism for backwards
-   compatibility reasons. This is largely equivalent. */
-static value llvm_ee_error_exn;
-
-CAMLprim value llvm_register_ee_exns(value Error) {
-  llvm_ee_error_exn = Field(Error, 0);
-  register_global_root(&llvm_ee_error_exn);
-  return Val_unit;
-}
-
-static void llvm_raise(value Prototype, char *Message) {
-  CAMLparam1(Prototype);
-  CAMLlocal1(CamlMessage);
-  
-  CamlMessage = copy_string(Message);
-  LLVMDisposeMessage(Message);
-  
-  raise_with_arg(Prototype, CamlMessage);
-  abort(); /* NOTREACHED */
-#ifdef CAMLnoreturn
-  CAMLnoreturn; /* Silences warnings, but is missing in some versions. */
-#endif
-}
+#include "caml/callback.h"
 
+void llvm_raise(value Prototype, char *Message);
 
 /*--... Operations on generic values .......................................--*/
 
@@ -58,12 +36,13 @@ static void llvm_finalize_generic_value(value GenVal) {
 }
 
 static struct custom_operations generic_value_ops = {
-  (char *) "LLVMGenericValue",
+  (char *) "Llvm_executionengine.GenericValue.t",
   llvm_finalize_generic_value,
   custom_compare_default,
   custom_hash_default,
   custom_serialize_default,
-  custom_deserialize_default
+  custom_deserialize_default,
+  custom_compare_ext_default
 };
 
 static value alloc_generic_value(LLVMGenericValueRef Ref) {
@@ -80,7 +59,7 @@ CAMLprim value llvm_genericvalue_of_float(LLVMTypeRef Ty, value N) {
 }
 
 /* 'a -> t */
-CAMLprim value llvm_genericvalue_of_value(value V) {
+CAMLprim value llvm_genericvalue_of_pointer(value V) {
   CAMLparam1(V);
   CAMLreturn(alloc_generic_value(LLVMCreateGenericValueOfPointer(Op_val(V))));
 }
@@ -119,7 +98,7 @@ CAMLprim value llvm_genericvalue_as_float(LLVMTypeRef Ty, value GenVal) {
 }
 
 /* t -> 'a */
-CAMLprim value llvm_genericvalue_as_value(value GenVal) {
+CAMLprim value llvm_genericvalue_as_pointer(value GenVal) {
   return Val_op(LLVMGenericValueToPointer(Genericvalue_val(GenVal)));
 }
 
@@ -157,55 +136,84 @@ CAMLprim value llvm_genericvalue_as_nativeint(value GenVal) {
 
 /*--... Operations on execution engines ....................................--*/
 
-/* llmoduleprovider -> ExecutionEngine.t */
-CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleProviderRef MP) {
+/* unit -> bool */
+CAMLprim value llvm_initialize_native_target(value Unit) {
+  LLVMLinkInInterpreter();
+  LLVMLinkInMCJIT();
+
+  return Val_bool(!LLVMInitializeNativeTarget() &&
+                  !LLVMInitializeNativeAsmParser() &&
+                  !LLVMInitializeNativeAsmPrinter());
+}
+
+/* llmodule -> ExecutionEngine.t */
+CAMLprim LLVMExecutionEngineRef llvm_ee_create(LLVMModuleRef M) {
   LLVMExecutionEngineRef Interp;
   char *Error;
-  if (LLVMCreateExecutionEngine(&Interp, MP, &Error))
-    llvm_raise(llvm_ee_error_exn, Error);
+  if (LLVMCreateExecutionEngineForModule(&Interp, M, &Error))
+    llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
   return Interp;
 }
 
-/* llmoduleprovider -> ExecutionEngine.t */
+/* llmodule -> ExecutionEngine.t */
 CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_interpreter(LLVMModuleProviderRef MP) {
+llvm_ee_create_interpreter(LLVMModuleRef M) {
   LLVMExecutionEngineRef Interp;
   char *Error;
-  if (LLVMCreateInterpreter(&Interp, MP, &Error))
-    llvm_raise(llvm_ee_error_exn, Error);
+  if (LLVMCreateInterpreterForModule(&Interp, M, &Error))
+    llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
   return Interp;
 }
 
-/* llmoduleprovider -> ExecutionEngine.t */
+/* llmodule -> int -> ExecutionEngine.t */
 CAMLprim LLVMExecutionEngineRef
-llvm_ee_create_jit(LLVMModuleProviderRef MP) {
+llvm_ee_create_jit(LLVMModuleRef M, value OptLevel) {
   LLVMExecutionEngineRef JIT;
   char *Error;
-  if (LLVMCreateJITCompiler(&JIT, MP, &Error))
-    llvm_raise(llvm_ee_error_exn, Error);
+  if (LLVMCreateJITCompilerForModule(&JIT, M, Int_val(OptLevel), &Error))
+    llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
   return JIT;
 }
 
+/* llmodule -> llcompileroption -> ExecutionEngine.t */
+CAMLprim LLVMExecutionEngineRef
+llvm_ee_create_mcjit(LLVMModuleRef M, value OptRecord) {
+  LLVMExecutionEngineRef MCJIT;
+  char *Error;
+  struct LLVMMCJITCompilerOptions Options;
+
+  LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
+  Options.OptLevel = Int_val(Field(OptRecord, 0));
+  Options.CodeModel = Int_val(Field(OptRecord, 1));
+  Options.NoFramePointerElim = Int_val(Field(OptRecord, 2));
+  Options.EnableFastISel = Int_val(Field(OptRecord, 3));
+  Options.MCJMM = NULL;
+
+  if (LLVMCreateMCJITCompilerForModule(&MCJIT, M, &Options,
+                                      sizeof(Options), &Error))
+    llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
+  return MCJIT;
+}
+
 /* ExecutionEngine.t -> unit */
 CAMLprim value llvm_ee_dispose(LLVMExecutionEngineRef EE) {
   LLVMDisposeExecutionEngine(EE);
   return Val_unit;
 }
 
-/* llmoduleprovider -> ExecutionEngine.t -> unit */
-CAMLprim value llvm_ee_add_mp(LLVMModuleProviderRef MP,
-                              LLVMExecutionEngineRef EE) {
-  LLVMAddModuleProvider(EE, MP);
+/* llmodule -> ExecutionEngine.t -> unit */
+CAMLprim value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
+  LLVMAddModule(EE, M);
   return Val_unit;
 }
 
-/* llmoduleprovider -> ExecutionEngine.t -> llmodule */
-CAMLprim LLVMModuleRef llvm_ee_remove_mp(LLVMModuleProviderRef MP,
-                                         LLVMExecutionEngineRef EE) {
+/* llmodule -> ExecutionEngine.t -> llmodule */
+CAMLprim LLVMModuleRef llvm_ee_remove_module(LLVMModuleRef M,
+                                             LLVMExecutionEngineRef EE) {
   LLVMModuleRef RemovedModule;
   char *Error;
-  if (LLVMRemoveModuleProvider(EE, MP, &RemovedModule, &Error))
-    llvm_raise(llvm_ee_error_exn, Error);
+  if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
+    llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
   return RemovedModule;
 }
 
@@ -216,7 +224,7 @@ CAMLprim value llvm_ee_find_function(value Name, LLVMExecutionEngineRef EE) {
   LLVMValueRef Found;
   if (LLVMFindFunction(EE, String_val(Name), &Found))
     CAMLreturn(Val_unit);
-  Option = alloc(1, 1);
+  Option = alloc(1, 0);
   Field(Option, 0) = Val_op(Found);
   CAMLreturn(Option);
 }
@@ -227,14 +235,14 @@ CAMLprim value llvm_ee_run_function(LLVMValueRef F, value Args,
   unsigned NumArgs;
   LLVMGenericValueRef Result, *GVArgs;
   unsigned I;
-  
+
   NumArgs = Wosize_val(Args);
   GVArgs = (LLVMGenericValueRef*) malloc(NumArgs * sizeof(LLVMGenericValueRef));
   for (I = 0; I != NumArgs; ++I)
     GVArgs[I] = Genericvalue_val(Field(Args, I));
-  
+
   Result = LLVMRunFunction(EE, F, NumArgs, GVArgs);
-  
+
   free(GVArgs);
   return alloc_generic_value(Result);
 }
@@ -260,21 +268,21 @@ CAMLprim value llvm_ee_run_function_as_main(LLVMValueRef F,
   int I, NumArgs, NumEnv, EnvSize, Result;
   const char **CArgs, **CEnv;
   char *CEnvBuf, *Pos;
-  
+
   NumArgs = Wosize_val(Args);
   NumEnv = Wosize_val(Env);
-  
+
   /* Build the environment. */
   CArgs = (const char **) malloc(NumArgs * sizeof(char*));
   for (I = 0; I != NumArgs; ++I)
     CArgs[I] = String_val(Field(Args, I));
-  
+
   /* Compute the size of the environment string buffer. */
   for (I = 0, EnvSize = 0; I != NumEnv; ++I) {
     EnvSize += strlen(String_val(Field(Field(Env, I), 0))) + 1;
     EnvSize += strlen(String_val(Field(Field(Env, I), 1))) + 1;
   }
-  
+
   /* Build the environment. */
   CEnv = (const char **) malloc((NumEnv + 1) * sizeof(char*));
   CEnvBuf = (char*) malloc(EnvSize);
@@ -284,7 +292,7 @@ CAMLprim value llvm_ee_run_function_as_main(LLVMValueRef F,
          *Value = String_val(Field(Field(Env, I), 1));
     int NameLen  = strlen(Name),
         ValueLen = strlen(Value);
-    
+
     CEnv[I] = Pos;
     memcpy(Pos, Name, NameLen);
     Pos += NameLen;
@@ -294,13 +302,13 @@ CAMLprim value llvm_ee_run_function_as_main(LLVMValueRef F,
     *Pos++ = '\0';
   }
   CEnv[NumEnv] = NULL;
-  
+
   Result = LLVMRunFunctionAsMain(EE, F, NumArgs, CArgs, CEnv);
-  
+
   free(CArgs);
   free(CEnv);
   free(CEnvBuf);
-  
+
   CAMLreturn(Val_int(Result));
 }
 
@@ -311,3 +319,18 @@ CAMLprim value llvm_ee_free_machine_code(LLVMValueRef F,
   return Val_unit;
 }
 
+extern value llvm_alloc_data_layout(LLVMTargetDataRef TargetData);
+
+/* ExecutionEngine.t -> Llvm_target.DataLayout.t */
+CAMLprim value llvm_ee_get_data_layout(LLVMExecutionEngineRef EE) {
+  value DataLayout;
+  LLVMTargetDataRef OrigDataLayout;
+  char* TargetDataCStr;
+
+  OrigDataLayout = LLVMGetExecutionEngineTargetData(EE);
+  TargetDataCStr = LLVMCopyStringRepOfTargetData(OrigDataLayout);
+  DataLayout = llvm_alloc_data_layout(LLVMCreateTargetData(TargetDataCStr));
+  LLVMDisposeMessage(TargetDataCStr);
+
+  return DataLayout;
+}