Summary: Add a vendored copy of the LLVM OCaml bindings. Source: https://github.com/llvm/llvm-project/tree/release/11.x/llvm/bindings/ocaml Reviewed By: jvillard Differential Revision: D27188303 fbshipit-source-id: d6b30c006master
parent
b3b6e0e48a
commit
823cd76f3c
@ -0,0 +1,11 @@
|
|||||||
|
add_subdirectory(llvm)
|
||||||
|
add_subdirectory(all_backends)
|
||||||
|
add_subdirectory(analysis)
|
||||||
|
add_subdirectory(backends)
|
||||||
|
add_subdirectory(bitreader)
|
||||||
|
add_subdirectory(bitwriter)
|
||||||
|
add_subdirectory(irreader)
|
||||||
|
add_subdirectory(linker)
|
||||||
|
add_subdirectory(target)
|
||||||
|
add_subdirectory(transforms)
|
||||||
|
add_subdirectory(executionengine)
|
@ -0,0 +1,29 @@
|
|||||||
|
This directory contains LLVM bindings for the OCaml programming language
|
||||||
|
(http://ocaml.org).
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* OCaml 4.00.0+.
|
||||||
|
* ctypes 0.4+.
|
||||||
|
* oUnit 2+ (only required for tests).
|
||||||
|
* CMake (to build LLVM).
|
||||||
|
|
||||||
|
Building the bindings
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
If all dependencies are present, the bindings will be built and installed
|
||||||
|
as a part of the default CMake configuration, with no further action.
|
||||||
|
They will only work with the specific OCaml compiler detected during the build.
|
||||||
|
|
||||||
|
The bindings can also be built out-of-tree, i.e. targeting a preinstalled
|
||||||
|
LLVM. To do this, configure the LLVM build tree as follows:
|
||||||
|
|
||||||
|
$ cmake -DLLVM_OCAML_OUT_OF_TREE=TRUE \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=[OCaml install prefix] \
|
||||||
|
[... any other options]
|
||||||
|
|
||||||
|
then build and install it as:
|
||||||
|
|
||||||
|
$ make ocaml_all
|
||||||
|
$ cmake -P bindings/ocaml/cmake_install.cmake
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_all_backends
|
||||||
|
OCAML llvm_all_backends
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C all_backends_ocaml
|
||||||
|
LLVM ${LLVM_TARGETS_TO_BUILD})
|
@ -0,0 +1,32 @@
|
|||||||
|
/*===-- all_backends_ocaml.c - LLVM OCaml Glue ------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Target.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
#include "caml/custom.h"
|
||||||
|
|
||||||
|
/* unit -> unit */
|
||||||
|
CAMLprim value llvm_initialize_all(value Unit) {
|
||||||
|
LLVMInitializeAllTargetInfos();
|
||||||
|
LLVMInitializeAllTargets();
|
||||||
|
LLVMInitializeAllTargetMCs();
|
||||||
|
LLVMInitializeAllAsmPrinters();
|
||||||
|
LLVMInitializeAllAsmParsers();
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
(*===-- llvm_all_backends.ml - LLVM OCaml Interface -----------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external initialize : unit -> unit = "llvm_initialize_all"
|
@ -0,0 +1,10 @@
|
|||||||
|
(*===-- llvm_all_backends.mli - LLVM OCaml Interface ----------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Initialize all the backends targets *)
|
||||||
|
val initialize : unit -> unit
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_analysis
|
||||||
|
OCAML llvm_analysis
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C analysis_ocaml
|
||||||
|
LLVM analysis)
|
@ -0,0 +1,72 @@
|
|||||||
|
/*===-- analysis_ocaml.c - LLVM OCaml Glue ----------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Analysis.h"
|
||||||
|
#include "llvm-c/Core.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
|
||||||
|
/* Llvm.llmodule -> string option */
|
||||||
|
CAMLprim value llvm_verify_module(LLVMModuleRef M) {
|
||||||
|
CAMLparam0();
|
||||||
|
CAMLlocal2(String, Option);
|
||||||
|
|
||||||
|
char *Message;
|
||||||
|
int Result = LLVMVerifyModule(M, LLVMReturnStatusAction, &Message);
|
||||||
|
|
||||||
|
if (0 == Result) {
|
||||||
|
Option = Val_int(0);
|
||||||
|
} else {
|
||||||
|
Option = alloc(1, 0);
|
||||||
|
String = copy_string(Message);
|
||||||
|
Store_field(Option, 0, String);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMDisposeMessage(Message);
|
||||||
|
|
||||||
|
CAMLreturn(Option);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llvalue -> bool */
|
||||||
|
CAMLprim value llvm_verify_function(LLVMValueRef Fn) {
|
||||||
|
return Val_bool(LLVMVerifyFunction(Fn, LLVMReturnStatusAction) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llmodule -> unit */
|
||||||
|
CAMLprim value llvm_assert_valid_module(LLVMModuleRef M) {
|
||||||
|
LLVMVerifyModule(M, LLVMAbortProcessAction, 0);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llvalue -> unit */
|
||||||
|
CAMLprim value llvm_assert_valid_function(LLVMValueRef Fn) {
|
||||||
|
LLVMVerifyFunction(Fn, LLVMAbortProcessAction);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llvalue -> unit */
|
||||||
|
CAMLprim value llvm_view_function_cfg(LLVMValueRef Fn) {
|
||||||
|
LLVMViewFunctionCFG(Fn);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llvalue -> unit */
|
||||||
|
CAMLprim value llvm_view_function_cfg_only(LLVMValueRef Fn) {
|
||||||
|
LLVMViewFunctionCFGOnly(Fn);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
(*===-- llvm_analysis.ml - LLVM OCaml Interface ---------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
|
||||||
|
external verify_module : Llvm.llmodule -> string option = "llvm_verify_module"
|
||||||
|
|
||||||
|
external verify_function : Llvm.llvalue -> bool = "llvm_verify_function"
|
||||||
|
|
||||||
|
external assert_valid_module : Llvm.llmodule -> unit
|
||||||
|
= "llvm_assert_valid_module"
|
||||||
|
|
||||||
|
external assert_valid_function : Llvm.llvalue -> unit
|
||||||
|
= "llvm_assert_valid_function"
|
||||||
|
external view_function_cfg : Llvm.llvalue -> unit = "llvm_view_function_cfg"
|
||||||
|
external view_function_cfg_only : Llvm.llvalue -> unit
|
||||||
|
= "llvm_view_function_cfg_only"
|
@ -0,0 +1,45 @@
|
|||||||
|
(*===-- llvm_analysis.mli - LLVM OCaml Interface --------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Intermediate representation analysis.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM IR analyses, the classes in
|
||||||
|
the Analysis library. *)
|
||||||
|
|
||||||
|
(** [verify_module m] returns [None] if the module [m] is valid, and
|
||||||
|
[Some reason] if it is invalid. [reason] is a string containing a
|
||||||
|
human-readable validation report. See [llvm::verifyModule]. *)
|
||||||
|
external verify_module : Llvm.llmodule -> string option = "llvm_verify_module"
|
||||||
|
|
||||||
|
(** [verify_function f] returns [None] if the function [f] is valid, and
|
||||||
|
[Some reason] if it is invalid. [reason] is a string containing a
|
||||||
|
human-readable validation report. See [llvm::verifyFunction]. *)
|
||||||
|
external verify_function : Llvm.llvalue -> bool = "llvm_verify_function"
|
||||||
|
|
||||||
|
(** [verify_module m] returns if the module [m] is valid, but prints a
|
||||||
|
validation report to [stderr] and aborts the program if it is invalid. See
|
||||||
|
[llvm::verifyModule]. *)
|
||||||
|
external assert_valid_module : Llvm.llmodule -> unit
|
||||||
|
= "llvm_assert_valid_module"
|
||||||
|
|
||||||
|
(** [verify_function f] returns if the function [f] is valid, but prints a
|
||||||
|
validation report to [stderr] and aborts the program if it is invalid. See
|
||||||
|
[llvm::verifyFunction]. *)
|
||||||
|
external assert_valid_function : Llvm.llvalue -> unit
|
||||||
|
= "llvm_assert_valid_function"
|
||||||
|
|
||||||
|
(** [view_function_cfg f] opens up a ghostscript window displaying the CFG of
|
||||||
|
the current function with the code for each basic block inside.
|
||||||
|
See [llvm::Function::viewCFG]. *)
|
||||||
|
external view_function_cfg : Llvm.llvalue -> unit = "llvm_view_function_cfg"
|
||||||
|
|
||||||
|
(** [view_function_cfg_only f] works just like [view_function_cfg], but does not
|
||||||
|
include the contents of basic blocks into the nodes.
|
||||||
|
See [llvm::Function::viewCFGOnly]. *)
|
||||||
|
external view_function_cfg_only : Llvm.llvalue -> unit
|
||||||
|
= "llvm_view_function_cfg_only"
|
@ -0,0 +1,27 @@
|
|||||||
|
foreach(TARGET ${LLVM_TARGETS_TO_BUILD})
|
||||||
|
set(OCAML_LLVM_TARGET ${TARGET})
|
||||||
|
|
||||||
|
foreach( ext ml mli )
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/llvm_backend.${ext}.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/llvm_${TARGET}.${ext}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/backend_ocaml.c"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_ocaml.c")
|
||||||
|
|
||||||
|
add_ocaml_library(llvm_${TARGET}
|
||||||
|
OCAML llvm_${TARGET}
|
||||||
|
C ${TARGET}_ocaml
|
||||||
|
CFLAGS -DTARGET=${TARGET}
|
||||||
|
LLVM ${TARGET}
|
||||||
|
NOCOPY)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/META.llvm_backend.in"
|
||||||
|
"${LLVM_LIBRARY_DIR}/ocaml/META.llvm_${TARGET}")
|
||||||
|
|
||||||
|
install(FILES "${LLVM_LIBRARY_DIR}/ocaml/META.llvm_${TARGET}"
|
||||||
|
DESTINATION "${LLVM_OCAML_INSTALL_PATH}")
|
||||||
|
endforeach()
|
@ -0,0 +1,7 @@
|
|||||||
|
name = "llvm_@TARGET@"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "@TARGET@ Backend for LLVM"
|
||||||
|
requires = "llvm"
|
||||||
|
archive(byte) = "llvm_@TARGET@.cma"
|
||||||
|
archive(native) = "llvm_@TARGET@.cmxa"
|
||||||
|
directory = "llvm"
|
@ -0,0 +1,38 @@
|
|||||||
|
/*===-- backend_ocaml.c - LLVM OCaml Glue -----------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Target.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
|
||||||
|
/* TODO: Figure out how to call these only for targets which support them.
|
||||||
|
* LLVMInitialize ## target ## AsmPrinter();
|
||||||
|
* LLVMInitialize ## target ## AsmParser();
|
||||||
|
* LLVMInitialize ## target ## Disassembler();
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INITIALIZER1(target) \
|
||||||
|
CAMLprim value llvm_initialize_ ## target(value Unit) { \
|
||||||
|
LLVMInitialize ## target ## TargetInfo(); \
|
||||||
|
LLVMInitialize ## target ## Target(); \
|
||||||
|
LLVMInitialize ## target ## TargetMC(); \
|
||||||
|
return Val_unit; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INITIALIZER(target) INITIALIZER1(target)
|
||||||
|
|
||||||
|
INITIALIZER(TARGET)
|
@ -0,0 +1,9 @@
|
|||||||
|
(*===-- llvm_backend.ml.in - LLVM OCaml Interface -------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external initialize : unit -> unit = "llvm_initialize_@TARGET@"
|
@ -0,0 +1,18 @@
|
|||||||
|
(*===-- llvm_backend.mli.in - LLVM OCaml Interface ------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** @TARGET@ Initialization.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for initialization of
|
||||||
|
the @TARGET@ LLVM target. By referencing this module, you will cause
|
||||||
|
OCaml to load or link in the LLVM libraries corresponding to the target.
|
||||||
|
By calling [initialize], you will register components of this target
|
||||||
|
in the target registry, which is necessary in order to emit assembly,
|
||||||
|
object files, and so on. *)
|
||||||
|
|
||||||
|
external initialize : unit -> unit = "llvm_initialize_@TARGET@"
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_bitreader
|
||||||
|
OCAML llvm_bitreader
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C bitreader_ocaml
|
||||||
|
LLVM bitreader)
|
@ -0,0 +1,42 @@
|
|||||||
|
/*===-- bitwriter_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||||
|
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/BitReader.h"
|
||||||
|
#include "llvm-c/Core.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
#include "caml/callback.h"
|
||||||
|
|
||||||
|
void llvm_raise(value Prototype, char *Message);
|
||||||
|
|
||||||
|
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||||
|
CAMLprim LLVMModuleRef llvm_get_module(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
|
||||||
|
LLVMModuleRef M;
|
||||||
|
|
||||||
|
if (LLVMGetBitcodeModuleInContext2(C, MemBuf, &M))
|
||||||
|
llvm_raise(*caml_named_value("Llvm_bitreader.Error"), LLVMCreateMessage(""));
|
||||||
|
|
||||||
|
return M;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||||
|
CAMLprim LLVMModuleRef llvm_parse_bitcode(LLVMContextRef C, LLVMMemoryBufferRef MemBuf) {
|
||||||
|
LLVMModuleRef M;
|
||||||
|
|
||||||
|
if (LLVMParseBitcodeInContext2(C, MemBuf, &M))
|
||||||
|
llvm_raise(*caml_named_value("Llvm_bitreader.Error"), LLVMCreateMessage(""));
|
||||||
|
|
||||||
|
return M;
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
(*===-- llvm_bitreader.ml - LLVM OCaml Interface --------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
let () = Callback.register_exception "Llvm_bitreader.Error" (Error "")
|
||||||
|
|
||||||
|
external get_module
|
||||||
|
: Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
= "llvm_get_module"
|
||||||
|
external parse_bitcode
|
||||||
|
: Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
= "llvm_parse_bitcode"
|
@ -0,0 +1,26 @@
|
|||||||
|
(*===-- llvm_bitreader.mli - LLVM OCaml Interface -------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Bitcode reader.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for the LLVM bitcode reader, the
|
||||||
|
classes in the Bitreader library. *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** [get_module context mb] reads the bitcode for a new module [m] from the
|
||||||
|
memory buffer [mb] in the context [context]. Returns [m] if successful, or
|
||||||
|
raises [Error msg] otherwise, where [msg] is a description of the error
|
||||||
|
encountered. See the function [llvm::getBitcodeModule]. *)
|
||||||
|
val get_module : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
|
||||||
|
(** [parse_bitcode context mb] parses the bitcode for a new module [m] from the
|
||||||
|
memory buffer [mb] in the context [context]. Returns [m] if successful, or
|
||||||
|
raises [Error msg] otherwise, where [msg] is a description of the error
|
||||||
|
encountered. See the function [llvm::ParseBitcodeFile]. *)
|
||||||
|
val parse_bitcode : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_bitwriter
|
||||||
|
OCAML llvm_bitwriter
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C bitwriter_ocaml
|
||||||
|
LLVM bitwriter)
|
@ -0,0 +1,48 @@
|
|||||||
|
/*===-- bitwriter_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/BitWriter.h"
|
||||||
|
#include "llvm-c/Core.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
|
||||||
|
/* Llvm.llmodule -> string -> bool */
|
||||||
|
CAMLprim value llvm_write_bitcode_file(LLVMModuleRef M, value Path) {
|
||||||
|
int Result = LLVMWriteBitcodeToFile(M, String_val(Path));
|
||||||
|
return Val_bool(Result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool */
|
||||||
|
CAMLprim value llvm_write_bitcode_to_fd(value U, LLVMModuleRef M, value FD) {
|
||||||
|
int Unbuffered;
|
||||||
|
int Result;
|
||||||
|
|
||||||
|
if (U == Val_int(0)) {
|
||||||
|
Unbuffered = 0;
|
||||||
|
} else {
|
||||||
|
Unbuffered = Bool_val(Field(U, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = LLVMWriteBitcodeToFD(M, Int_val(FD), 0, Unbuffered);
|
||||||
|
return Val_bool(Result == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llmodule -> Llvm.llmemorybuffer */
|
||||||
|
CAMLprim LLVMMemoryBufferRef llvm_write_bitcode_to_memory_buffer(LLVMModuleRef M) {
|
||||||
|
return LLVMWriteBitcodeToMemoryBuffer(M);
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
(*===-- llvm_bitwriter.ml - LLVM OCaml Interface --------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===
|
||||||
|
*
|
||||||
|
* This interface provides an OCaml API for the LLVM intermediate
|
||||||
|
* representation, the classes in the VMCore library.
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external write_bitcode_file
|
||||||
|
: Llvm.llmodule -> string -> bool
|
||||||
|
= "llvm_write_bitcode_file"
|
||||||
|
|
||||||
|
external write_bitcode_to_fd
|
||||||
|
: ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool
|
||||||
|
= "llvm_write_bitcode_to_fd"
|
||||||
|
|
||||||
|
external write_bitcode_to_memory_buffer
|
||||||
|
: Llvm.llmodule -> Llvm.llmemorybuffer
|
||||||
|
= "llvm_write_bitcode_to_memory_buffer"
|
||||||
|
|
||||||
|
let output_bitcode ?unbuffered channel m =
|
||||||
|
write_bitcode_to_fd ?unbuffered m (Unix.descr_of_out_channel channel)
|
@ -0,0 +1,36 @@
|
|||||||
|
(*===-- llvm_bitwriter.mli - LLVM OCaml Interface -------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Bitcode writer.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for the LLVM bitcode writer, the
|
||||||
|
classes in the Bitwriter library. *)
|
||||||
|
|
||||||
|
(** [write_bitcode_file m path] writes the bitcode for module [m] to the file at
|
||||||
|
[path]. Returns [true] if successful, [false] otherwise. *)
|
||||||
|
external write_bitcode_file
|
||||||
|
: Llvm.llmodule -> string -> bool
|
||||||
|
= "llvm_write_bitcode_file"
|
||||||
|
|
||||||
|
(** [write_bitcode_to_fd ~unbuffered fd m] writes the bitcode for module
|
||||||
|
[m] to the channel [c]. If [unbuffered] is [true], after every write the fd
|
||||||
|
will be flushed. Returns [true] if successful, [false] otherwise. *)
|
||||||
|
external write_bitcode_to_fd
|
||||||
|
: ?unbuffered:bool -> Llvm.llmodule -> Unix.file_descr -> bool
|
||||||
|
= "llvm_write_bitcode_to_fd"
|
||||||
|
|
||||||
|
(** [write_bitcode_to_memory_buffer m] returns a memory buffer containing
|
||||||
|
the bitcode for module [m]. *)
|
||||||
|
external write_bitcode_to_memory_buffer
|
||||||
|
: Llvm.llmodule -> Llvm.llmemorybuffer
|
||||||
|
= "llvm_write_bitcode_to_memory_buffer"
|
||||||
|
|
||||||
|
(** [output_bitcode ~unbuffered c m] writes the bitcode for module [m]
|
||||||
|
to the channel [c]. If [unbuffered] is [true], after every write the fd
|
||||||
|
will be flushed. Returns [true] if successful, [false] otherwise. *)
|
||||||
|
val output_bitcode : ?unbuffered:bool -> out_channel -> Llvm.llmodule -> bool
|
@ -0,0 +1,6 @@
|
|||||||
|
add_ocaml_library(llvm_executionengine
|
||||||
|
OCAML llvm_executionengine
|
||||||
|
OCAMLDEP llvm llvm_target
|
||||||
|
C executionengine_ocaml
|
||||||
|
LLVM executionengine mcjit native
|
||||||
|
PKG ctypes)
|
@ -0,0 +1,127 @@
|
|||||||
|
/*===-- executionengine_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "llvm-c/Core.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 "caml/callback.h"
|
||||||
|
|
||||||
|
void llvm_raise(value Prototype, char *Message);
|
||||||
|
|
||||||
|
/* unit -> bool */
|
||||||
|
CAMLprim value llvm_ee_initialize(value Unit) {
|
||||||
|
LLVMLinkInMCJIT();
|
||||||
|
|
||||||
|
return Val_bool(!LLVMInitializeNativeTarget() &&
|
||||||
|
!LLVMInitializeNativeAsmParser() &&
|
||||||
|
!LLVMInitializeNativeAsmPrinter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* llmodule -> llcompileroption -> ExecutionEngine.t */
|
||||||
|
CAMLprim LLVMExecutionEngineRef llvm_ee_create(value OptRecordOpt, LLVMModuleRef M) {
|
||||||
|
value OptRecord;
|
||||||
|
LLVMExecutionEngineRef MCJIT;
|
||||||
|
char *Error;
|
||||||
|
struct LLVMMCJITCompilerOptions Options;
|
||||||
|
|
||||||
|
LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
|
||||||
|
if (OptRecordOpt != Val_int(0)) {
|
||||||
|
OptRecord = Field(OptRecordOpt, 0);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* llmodule -> ExecutionEngine.t -> unit */
|
||||||
|
CAMLprim value llvm_ee_add_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
|
||||||
|
LLVMAddModule(EE, M);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* llmodule -> ExecutionEngine.t -> llmodule */
|
||||||
|
CAMLprim value llvm_ee_remove_module(LLVMModuleRef M, LLVMExecutionEngineRef EE) {
|
||||||
|
LLVMModuleRef RemovedModule;
|
||||||
|
char *Error;
|
||||||
|
if (LLVMRemoveModule(EE, M, &RemovedModule, &Error))
|
||||||
|
llvm_raise(*caml_named_value("Llvm_executionengine.Error"), Error);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ExecutionEngine.t -> unit */
|
||||||
|
CAMLprim value llvm_ee_run_static_ctors(LLVMExecutionEngineRef EE) {
|
||||||
|
LLVMRunStaticConstructors(EE);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ExecutionEngine.t -> unit */
|
||||||
|
CAMLprim value llvm_ee_run_static_dtors(LLVMExecutionEngineRef EE) {
|
||||||
|
LLVMRunStaticDestructors(EE);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llvalue -> int64 -> llexecutionengine -> unit */
|
||||||
|
CAMLprim value llvm_ee_add_global_mapping(LLVMValueRef Global, value Ptr,
|
||||||
|
LLVMExecutionEngineRef EE) {
|
||||||
|
LLVMAddGlobalMapping(EE, Global, (void*) (Int64_val(Ptr)));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value llvm_ee_get_global_value_address(value Name,
|
||||||
|
LLVMExecutionEngineRef EE) {
|
||||||
|
return caml_copy_int64((int64_t) LLVMGetGlobalValueAddress(EE, String_val(Name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value llvm_ee_get_function_address(value Name,
|
||||||
|
LLVMExecutionEngineRef EE) {
|
||||||
|
return caml_copy_int64((int64_t) LLVMGetFunctionAddress(EE, String_val(Name)));
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
(*===-- llvm_executionengine.ml - LLVM OCaml Interface --------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
let () = Callback.register_exception "Llvm_executionengine.Error" (Error "")
|
||||||
|
|
||||||
|
external initialize : unit -> bool
|
||||||
|
= "llvm_ee_initialize"
|
||||||
|
|
||||||
|
type llexecutionengine
|
||||||
|
|
||||||
|
type llcompileroptions = {
|
||||||
|
opt_level: int;
|
||||||
|
code_model: Llvm_target.CodeModel.t;
|
||||||
|
no_framepointer_elim: bool;
|
||||||
|
enable_fast_isel: bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
let default_compiler_options = {
|
||||||
|
opt_level = 0;
|
||||||
|
code_model = Llvm_target.CodeModel.JITDefault;
|
||||||
|
no_framepointer_elim = false;
|
||||||
|
enable_fast_isel = false }
|
||||||
|
|
||||||
|
external create : ?options:llcompileroptions -> Llvm.llmodule -> llexecutionengine
|
||||||
|
= "llvm_ee_create"
|
||||||
|
external dispose : llexecutionengine -> unit
|
||||||
|
= "llvm_ee_dispose"
|
||||||
|
external add_module : Llvm.llmodule -> llexecutionengine -> unit
|
||||||
|
= "llvm_ee_add_module"
|
||||||
|
external remove_module : Llvm.llmodule -> llexecutionengine -> unit
|
||||||
|
= "llvm_ee_remove_module"
|
||||||
|
external run_static_ctors : llexecutionengine -> unit
|
||||||
|
= "llvm_ee_run_static_ctors"
|
||||||
|
external run_static_dtors : llexecutionengine -> unit
|
||||||
|
= "llvm_ee_run_static_dtors"
|
||||||
|
external data_layout : llexecutionengine -> Llvm_target.DataLayout.t
|
||||||
|
= "llvm_ee_get_data_layout"
|
||||||
|
external add_global_mapping_ : Llvm.llvalue -> nativeint -> llexecutionengine -> unit
|
||||||
|
= "llvm_ee_add_global_mapping"
|
||||||
|
external get_global_value_address_ : string -> llexecutionengine -> nativeint
|
||||||
|
= "llvm_ee_get_global_value_address"
|
||||||
|
external get_function_address_ : string -> llexecutionengine -> nativeint
|
||||||
|
= "llvm_ee_get_function_address"
|
||||||
|
|
||||||
|
let add_global_mapping llval ptr ee =
|
||||||
|
add_global_mapping_ llval (Ctypes.raw_address_of_ptr (Ctypes.to_voidp ptr)) ee
|
||||||
|
|
||||||
|
let get_global_value_address name typ ee =
|
||||||
|
let vptr = get_global_value_address_ name ee in
|
||||||
|
if Nativeint.to_int vptr <> 0 then
|
||||||
|
let open Ctypes in !@ (coerce (ptr void) (ptr typ) (ptr_of_raw_address vptr))
|
||||||
|
else
|
||||||
|
raise (Error ("Value " ^ name ^ " not found"))
|
||||||
|
|
||||||
|
let get_function_address name typ ee =
|
||||||
|
let fptr = get_function_address_ name ee in
|
||||||
|
if Nativeint.to_int fptr <> 0 then
|
||||||
|
let open Ctypes in coerce (ptr void) typ (ptr_of_raw_address fptr)
|
||||||
|
else
|
||||||
|
raise (Error ("Function " ^ name ^ " not found"))
|
||||||
|
|
||||||
|
(* The following are not bound. Patches are welcome.
|
||||||
|
target_machine : llexecutionengine -> Llvm_target.TargetMachine.t
|
||||||
|
*)
|
@ -0,0 +1,92 @@
|
|||||||
|
(*===-- llvm_executionengine.mli - LLVM OCaml Interface -------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** JIT Interpreter.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM execution engine (JIT/
|
||||||
|
interpreter), the classes in the [ExecutionEngine] library. *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** [initialize ()] initializes the backend corresponding to the host.
|
||||||
|
Returns [true] if initialization is successful; [false] indicates
|
||||||
|
that there is no such backend or it is unable to emit object code
|
||||||
|
via MCJIT. *)
|
||||||
|
val initialize : unit -> bool
|
||||||
|
|
||||||
|
(** An execution engine is either a JIT compiler or an interpreter, capable of
|
||||||
|
directly loading an LLVM module and executing its functions without first
|
||||||
|
invoking a static compiler and generating a native executable. *)
|
||||||
|
type llexecutionengine
|
||||||
|
|
||||||
|
(** MCJIT compiler options. See [llvm::TargetOptions]. *)
|
||||||
|
type llcompileroptions = {
|
||||||
|
opt_level: int;
|
||||||
|
code_model: Llvm_target.CodeModel.t;
|
||||||
|
no_framepointer_elim: bool;
|
||||||
|
enable_fast_isel: bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
(** Default MCJIT compiler options:
|
||||||
|
[{ opt_level = 0; code_model = CodeModel.JIT_default;
|
||||||
|
no_framepointer_elim = false; enable_fast_isel = false }] *)
|
||||||
|
val default_compiler_options : llcompileroptions
|
||||||
|
|
||||||
|
(** [create m optlevel] creates a new MCJIT just-in-time compiler, taking
|
||||||
|
ownership of the module [m] if successful with the desired optimization
|
||||||
|
level [optlevel]. Raises [Error msg] if an error occurrs. The execution
|
||||||
|
engine is not garbage collected and must be destroyed with [dispose ee].
|
||||||
|
|
||||||
|
Run {!initialize} before using this function.
|
||||||
|
|
||||||
|
See the function [llvm::EngineBuilder::create]. *)
|
||||||
|
val create : ?options:llcompileroptions -> Llvm.llmodule -> llexecutionengine
|
||||||
|
|
||||||
|
(** [dispose ee] releases the memory used by the execution engine and must be
|
||||||
|
invoked to avoid memory leaks. *)
|
||||||
|
val dispose : llexecutionengine -> unit
|
||||||
|
|
||||||
|
(** [add_module m ee] adds the module [m] to the execution engine [ee]. *)
|
||||||
|
val add_module : Llvm.llmodule -> llexecutionengine -> unit
|
||||||
|
|
||||||
|
(** [remove_module m ee] removes the module [m] from the execution engine
|
||||||
|
[ee]. Raises [Error msg] if an error occurs. *)
|
||||||
|
val remove_module : Llvm.llmodule -> llexecutionengine -> unit
|
||||||
|
|
||||||
|
(** [run_static_ctors ee] executes the static constructors of each module in
|
||||||
|
the execution engine [ee]. *)
|
||||||
|
val run_static_ctors : llexecutionengine -> unit
|
||||||
|
|
||||||
|
(** [run_static_dtors ee] executes the static destructors of each module in
|
||||||
|
the execution engine [ee]. *)
|
||||||
|
val run_static_dtors : llexecutionengine -> unit
|
||||||
|
|
||||||
|
(** [data_layout ee] is the data layout of the execution engine [ee]. *)
|
||||||
|
val data_layout : llexecutionengine -> Llvm_target.DataLayout.t
|
||||||
|
|
||||||
|
(** [add_global_mapping gv ptr ee] tells the execution engine [ee] that
|
||||||
|
the global [gv] is at the specified location [ptr], which must outlive
|
||||||
|
[gv] and [ee].
|
||||||
|
All uses of [gv] in the compiled code will refer to [ptr]. *)
|
||||||
|
val add_global_mapping : Llvm.llvalue -> 'a Ctypes.ptr -> llexecutionengine -> unit
|
||||||
|
|
||||||
|
(** [get_global_value_address id typ ee] returns a pointer to the
|
||||||
|
identifier [id] as type [typ], which will be a pointer type for a
|
||||||
|
value, and which will be live as long as [id] and [ee]
|
||||||
|
are. Caution: this function finalizes, i.e. forces code
|
||||||
|
generation, all loaded modules. Further modifications to the
|
||||||
|
modules will not have any effect. *)
|
||||||
|
val get_global_value_address : string -> 'a Ctypes.typ -> llexecutionengine -> 'a
|
||||||
|
|
||||||
|
(** [get_function_address fn typ ee] returns a pointer to the function
|
||||||
|
[fn] as type [typ], which will be a pointer type for a function
|
||||||
|
(e.g. [(int -> int) typ]), and which will be live as long as [fn]
|
||||||
|
and [ee] are. Caution: this function finalizes, i.e. forces code
|
||||||
|
generation, all loaded modules. Further modifications to the
|
||||||
|
modules will not have any effect. *)
|
||||||
|
val get_function_address : string -> 'a Ctypes.typ -> llexecutionengine -> 'a
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_irreader
|
||||||
|
OCAML llvm_irreader
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C irreader_ocaml
|
||||||
|
LLVM irreader)
|
@ -0,0 +1,35 @@
|
|||||||
|
/*===-- irreader_ocaml.c - LLVM OCaml Glue ----------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* This file glues LLVM's OCaml interface to its C interface. These functions *|
|
||||||
|
|* are by and large transparent wrappers to the corresponding C functions. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/IRReader.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
#include "caml/callback.h"
|
||||||
|
|
||||||
|
void llvm_raise(value Prototype, char *Message);
|
||||||
|
|
||||||
|
/* Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule */
|
||||||
|
CAMLprim value llvm_parse_ir(LLVMContextRef C,
|
||||||
|
LLVMMemoryBufferRef MemBuf) {
|
||||||
|
CAMLparam0();
|
||||||
|
CAMLlocal2(Variant, MessageVal);
|
||||||
|
LLVMModuleRef M;
|
||||||
|
char *Message;
|
||||||
|
|
||||||
|
if (LLVMParseIRInContext(C, MemBuf, &M, &Message))
|
||||||
|
llvm_raise(*caml_named_value("Llvm_irreader.Error"), Message);
|
||||||
|
|
||||||
|
CAMLreturn((value) M);
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
(*===-- llvm_irreader.ml - LLVM OCaml Interface ---------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
let _ = Callback.register_exception "Llvm_irreader.Error" (Error "")
|
||||||
|
|
||||||
|
external parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
||||||
|
= "llvm_parse_ir"
|
@ -0,0 +1,20 @@
|
|||||||
|
(*===-- llvm_irreader.mli - LLVM OCaml Interface --------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** IR reader.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for the LLVM assembly reader, the
|
||||||
|
classes in the IRReader library. *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** [parse_ir context mb] parses the IR for a new module [m] from the
|
||||||
|
memory buffer [mb] in the context [context]. Returns [m] if successful, or
|
||||||
|
raises [Error msg] otherwise, where [msg] is a description of the error
|
||||||
|
encountered. See the function [llvm::ParseIR]. *)
|
||||||
|
val parse_ir : Llvm.llcontext -> Llvm.llmemorybuffer -> Llvm.llmodule
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_linker
|
||||||
|
OCAML llvm_linker
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C linker_ocaml
|
||||||
|
LLVM linker)
|
@ -0,0 +1,33 @@
|
|||||||
|
/*===-- linker_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Core.h"
|
||||||
|
#include "llvm-c/Linker.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/callback.h"
|
||||||
|
|
||||||
|
void llvm_raise(value Prototype, char *Message);
|
||||||
|
|
||||||
|
/* llmodule -> llmodule -> unit */
|
||||||
|
CAMLprim value llvm_link_modules(LLVMModuleRef Dst, LLVMModuleRef Src) {
|
||||||
|
if (LLVMLinkModules2(Dst, Src))
|
||||||
|
llvm_raise(*caml_named_value("Llvm_linker.Error"), LLVMCreateMessage("Linking failed"));
|
||||||
|
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
(*===-- llvm_linker.ml - LLVM OCaml Interface ------------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
let () = Callback.register_exception "Llvm_linker.Error" (Error "")
|
||||||
|
|
||||||
|
external link_modules' : Llvm.llmodule -> Llvm.llmodule -> unit
|
||||||
|
= "llvm_link_modules"
|
@ -0,0 +1,18 @@
|
|||||||
|
(*===-- llvm_linker.mli - LLVM OCaml Interface -----------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Linker.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM bitcode linker,
|
||||||
|
the classes in the Linker library. *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** [link_modules' dst src] links [src] into [dst], raising [Error]
|
||||||
|
if the linking fails. The src module is destroyed. *)
|
||||||
|
val link_modules' : Llvm.llmodule -> Llvm.llmodule -> unit
|
@ -0,0 +1,11 @@
|
|||||||
|
add_ocaml_library(llvm
|
||||||
|
OCAML llvm
|
||||||
|
C llvm_ocaml
|
||||||
|
LLVM core support)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/META.llvm.in"
|
||||||
|
"${LLVM_LIBRARY_DIR}/ocaml/META.llvm")
|
||||||
|
|
||||||
|
install(FILES "${LLVM_LIBRARY_DIR}/ocaml/META.llvm"
|
||||||
|
DESTINATION "${LLVM_OCAML_INSTALL_PATH}")
|
@ -0,0 +1,110 @@
|
|||||||
|
name = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "LLVM OCaml bindings"
|
||||||
|
archive(byte) = "llvm.cma"
|
||||||
|
archive(native) = "llvm.cmxa"
|
||||||
|
directory = "llvm"
|
||||||
|
|
||||||
|
package "analysis" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Intermediate representation analysis for LLVM"
|
||||||
|
archive(byte) = "llvm_analysis.cma"
|
||||||
|
archive(native) = "llvm_analysis.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "bitreader" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Bitcode reader for LLVM"
|
||||||
|
archive(byte) = "llvm_bitreader.cma"
|
||||||
|
archive(native) = "llvm_bitreader.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "bitwriter" (
|
||||||
|
requires = "llvm,unix"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Bitcode writer for LLVM"
|
||||||
|
archive(byte) = "llvm_bitwriter.cma"
|
||||||
|
archive(native) = "llvm_bitwriter.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "executionengine" (
|
||||||
|
requires = "llvm,llvm.target,ctypes.foreign"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "JIT and Interpreter for LLVM"
|
||||||
|
archive(byte) = "llvm_executionengine.cma"
|
||||||
|
archive(native) = "llvm_executionengine.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "ipo" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "IPO Transforms for LLVM"
|
||||||
|
archive(byte) = "llvm_ipo.cma"
|
||||||
|
archive(native) = "llvm_ipo.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "irreader" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "IR assembly reader for LLVM"
|
||||||
|
archive(byte) = "llvm_irreader.cma"
|
||||||
|
archive(native) = "llvm_irreader.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "scalar_opts" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Scalar Transforms for LLVM"
|
||||||
|
archive(byte) = "llvm_scalar_opts.cma"
|
||||||
|
archive(native) = "llvm_scalar_opts.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "transform_utils" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Transform utilities for LLVM"
|
||||||
|
archive(byte) = "llvm_transform_utils.cma"
|
||||||
|
archive(native) = "llvm_transform_utils.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "vectorize" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Vector Transforms for LLVM"
|
||||||
|
archive(byte) = "llvm_vectorize.cma"
|
||||||
|
archive(native) = "llvm_vectorize.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "passmgr_builder" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Pass Manager Builder for LLVM"
|
||||||
|
archive(byte) = "llvm_passmgr_builder.cma"
|
||||||
|
archive(native) = "llvm_passmgr_builder.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "target" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Target Information for LLVM"
|
||||||
|
archive(byte) = "llvm_target.cma"
|
||||||
|
archive(native) = "llvm_target.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "linker" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "Intermediate Representation Linker for LLVM"
|
||||||
|
archive(byte) = "llvm_linker.cma"
|
||||||
|
archive(native) = "llvm_linker.cmxa"
|
||||||
|
)
|
||||||
|
|
||||||
|
package "all_backends" (
|
||||||
|
requires = "llvm"
|
||||||
|
version = "@PACKAGE_VERSION@"
|
||||||
|
description = "All backends for LLVM"
|
||||||
|
archive(byte) = "llvm_all_backends.cma"
|
||||||
|
archive(native) = "llvm_all_backends.cmxa"
|
||||||
|
)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_target
|
||||||
|
OCAML llvm_target
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C target_ocaml
|
||||||
|
LLVM target)
|
@ -0,0 +1,135 @@
|
|||||||
|
(*===-- llvm_target.ml - LLVM OCaml Interface ------------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
module Endian = struct
|
||||||
|
type t =
|
||||||
|
| Big
|
||||||
|
| Little
|
||||||
|
end
|
||||||
|
|
||||||
|
module CodeGenOptLevel = struct
|
||||||
|
type t =
|
||||||
|
| None
|
||||||
|
| Less
|
||||||
|
| Default
|
||||||
|
| Aggressive
|
||||||
|
end
|
||||||
|
|
||||||
|
module RelocMode = struct
|
||||||
|
type t =
|
||||||
|
| Default
|
||||||
|
| Static
|
||||||
|
| PIC
|
||||||
|
| DynamicNoPIC
|
||||||
|
end
|
||||||
|
|
||||||
|
module CodeModel = struct
|
||||||
|
type t =
|
||||||
|
| Default
|
||||||
|
| JITDefault
|
||||||
|
| Small
|
||||||
|
| Kernel
|
||||||
|
| Medium
|
||||||
|
| Large
|
||||||
|
end
|
||||||
|
|
||||||
|
module CodeGenFileType = struct
|
||||||
|
type t =
|
||||||
|
| AssemblyFile
|
||||||
|
| ObjectFile
|
||||||
|
end
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
let () = Callback.register_exception "Llvm_target.Error" (Error "")
|
||||||
|
|
||||||
|
module DataLayout = struct
|
||||||
|
type t
|
||||||
|
|
||||||
|
external of_string : string -> t = "llvm_datalayout_of_string"
|
||||||
|
external as_string : t -> string = "llvm_datalayout_as_string"
|
||||||
|
external byte_order : t -> Endian.t = "llvm_datalayout_byte_order"
|
||||||
|
external pointer_size : t -> int = "llvm_datalayout_pointer_size"
|
||||||
|
external intptr_type : Llvm.llcontext -> t -> Llvm.lltype
|
||||||
|
= "llvm_datalayout_intptr_type"
|
||||||
|
external qualified_pointer_size : int -> t -> int
|
||||||
|
= "llvm_datalayout_qualified_pointer_size"
|
||||||
|
external qualified_intptr_type : Llvm.llcontext -> int -> t -> Llvm.lltype
|
||||||
|
= "llvm_datalayout_qualified_intptr_type"
|
||||||
|
external size_in_bits : Llvm.lltype -> t -> Int64.t
|
||||||
|
= "llvm_datalayout_size_in_bits"
|
||||||
|
external store_size : Llvm.lltype -> t -> Int64.t
|
||||||
|
= "llvm_datalayout_store_size"
|
||||||
|
external abi_size : Llvm.lltype -> t -> Int64.t
|
||||||
|
= "llvm_datalayout_abi_size"
|
||||||
|
external abi_align : Llvm.lltype -> t -> int
|
||||||
|
= "llvm_datalayout_abi_align"
|
||||||
|
external stack_align : Llvm.lltype -> t -> int
|
||||||
|
= "llvm_datalayout_stack_align"
|
||||||
|
external preferred_align : Llvm.lltype -> t -> int
|
||||||
|
= "llvm_datalayout_preferred_align"
|
||||||
|
external preferred_align_of_global : Llvm.llvalue -> t -> int
|
||||||
|
= "llvm_datalayout_preferred_align_of_global"
|
||||||
|
external element_at_offset : Llvm.lltype -> Int64.t -> t -> int
|
||||||
|
= "llvm_datalayout_element_at_offset"
|
||||||
|
external offset_of_element : Llvm.lltype -> int -> t -> Int64.t
|
||||||
|
= "llvm_datalayout_offset_of_element"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Target = struct
|
||||||
|
type t
|
||||||
|
|
||||||
|
external default_triple : unit -> string = "llvm_target_default_triple"
|
||||||
|
external first : unit -> t option = "llvm_target_first"
|
||||||
|
external succ : t -> t option = "llvm_target_succ"
|
||||||
|
external by_name : string -> t option = "llvm_target_by_name"
|
||||||
|
external by_triple : string -> t = "llvm_target_by_triple"
|
||||||
|
external name : t -> string = "llvm_target_name"
|
||||||
|
external description : t -> string = "llvm_target_description"
|
||||||
|
external has_jit : t -> bool = "llvm_target_has_jit"
|
||||||
|
external has_target_machine : t -> bool = "llvm_target_has_target_machine"
|
||||||
|
external has_asm_backend : t -> bool = "llvm_target_has_asm_backend"
|
||||||
|
|
||||||
|
let all () =
|
||||||
|
let rec step elem lst =
|
||||||
|
match elem with
|
||||||
|
| Some target -> step (succ target) (target :: lst)
|
||||||
|
| None -> lst
|
||||||
|
in
|
||||||
|
step (first ()) []
|
||||||
|
end
|
||||||
|
|
||||||
|
module TargetMachine = struct
|
||||||
|
type t
|
||||||
|
|
||||||
|
external create : triple:string -> ?cpu:string -> ?features:string ->
|
||||||
|
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t ->
|
||||||
|
?code_model:CodeModel.t -> Target.t -> t
|
||||||
|
= "llvm_create_targetmachine_bytecode"
|
||||||
|
"llvm_create_targetmachine_native"
|
||||||
|
external target : t -> Target.t
|
||||||
|
= "llvm_targetmachine_target"
|
||||||
|
external triple : t -> string
|
||||||
|
= "llvm_targetmachine_triple"
|
||||||
|
external cpu : t -> string
|
||||||
|
= "llvm_targetmachine_cpu"
|
||||||
|
external features : t -> string
|
||||||
|
= "llvm_targetmachine_features"
|
||||||
|
external data_layout : t -> DataLayout.t
|
||||||
|
= "llvm_targetmachine_data_layout"
|
||||||
|
external add_analysis_passes : [< Llvm.PassManager.any ] Llvm.PassManager.t -> t -> unit
|
||||||
|
= "llvm_targetmachine_add_analysis_passes"
|
||||||
|
external set_verbose_asm : bool -> t -> unit
|
||||||
|
= "llvm_targetmachine_set_verbose_asm"
|
||||||
|
external emit_to_file : Llvm.llmodule -> CodeGenFileType.t -> string ->
|
||||||
|
t -> unit
|
||||||
|
= "llvm_targetmachine_emit_to_file"
|
||||||
|
external emit_to_memory_buffer : Llvm.llmodule -> CodeGenFileType.t ->
|
||||||
|
t -> Llvm.llmemorybuffer
|
||||||
|
= "llvm_targetmachine_emit_to_memory_buffer"
|
||||||
|
end
|
@ -0,0 +1,219 @@
|
|||||||
|
(*===-- llvm_target.mli - LLVM OCaml Interface -----------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Target Information.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM target information,
|
||||||
|
the classes in the Target library. *)
|
||||||
|
|
||||||
|
module Endian : sig
|
||||||
|
type t =
|
||||||
|
| Big
|
||||||
|
| Little
|
||||||
|
end
|
||||||
|
|
||||||
|
module CodeGenOptLevel : sig
|
||||||
|
type t =
|
||||||
|
| None
|
||||||
|
| Less
|
||||||
|
| Default
|
||||||
|
| Aggressive
|
||||||
|
end
|
||||||
|
|
||||||
|
module RelocMode : sig
|
||||||
|
type t =
|
||||||
|
| Default
|
||||||
|
| Static
|
||||||
|
| PIC
|
||||||
|
| DynamicNoPIC
|
||||||
|
end
|
||||||
|
|
||||||
|
module CodeModel : sig
|
||||||
|
type t =
|
||||||
|
| Default
|
||||||
|
| JITDefault
|
||||||
|
| Small
|
||||||
|
| Kernel
|
||||||
|
| Medium
|
||||||
|
| Large
|
||||||
|
end
|
||||||
|
|
||||||
|
module CodeGenFileType : sig
|
||||||
|
type t =
|
||||||
|
| AssemblyFile
|
||||||
|
| ObjectFile
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {6 Exceptions} *)
|
||||||
|
|
||||||
|
exception Error of string
|
||||||
|
|
||||||
|
(** {6 Data Layout} *)
|
||||||
|
|
||||||
|
module DataLayout : sig
|
||||||
|
type t
|
||||||
|
|
||||||
|
(** [of_string rep] parses the data layout string representation [rep].
|
||||||
|
See the constructor [llvm::DataLayout::DataLayout]. *)
|
||||||
|
val of_string : string -> t
|
||||||
|
|
||||||
|
(** [as_string dl] is the string representation of the data layout [dl].
|
||||||
|
See the method [llvm::DataLayout::getStringRepresentation]. *)
|
||||||
|
val as_string : t -> string
|
||||||
|
|
||||||
|
(** Returns the byte order of a target, either [Endian.Big] or
|
||||||
|
[Endian.Little].
|
||||||
|
See the method [llvm::DataLayout::isLittleEndian]. *)
|
||||||
|
val byte_order : t -> Endian.t
|
||||||
|
|
||||||
|
(** Returns the pointer size in bytes for a target.
|
||||||
|
See the method [llvm::DataLayout::getPointerSize]. *)
|
||||||
|
val pointer_size : t -> int
|
||||||
|
|
||||||
|
(** Returns the integer type that is the same size as a pointer on a target.
|
||||||
|
See the method [llvm::DataLayout::getIntPtrType]. *)
|
||||||
|
val intptr_type : Llvm.llcontext -> t -> Llvm.lltype
|
||||||
|
|
||||||
|
(** Returns the pointer size in bytes for a target in a given address space.
|
||||||
|
See the method [llvm::DataLayout::getPointerSize]. *)
|
||||||
|
val qualified_pointer_size : int -> t -> int
|
||||||
|
|
||||||
|
(** Returns the integer type that is the same size as a pointer on a target
|
||||||
|
in a given address space.
|
||||||
|
See the method [llvm::DataLayout::getIntPtrType]. *)
|
||||||
|
val qualified_intptr_type : Llvm.llcontext -> int -> t -> Llvm.lltype
|
||||||
|
|
||||||
|
(** Computes the size of a type in bits for a target.
|
||||||
|
See the method [llvm::DataLayout::getTypeSizeInBits]. *)
|
||||||
|
val size_in_bits : Llvm.lltype -> t -> Int64.t
|
||||||
|
|
||||||
|
(** Computes the storage size of a type in bytes for a target.
|
||||||
|
See the method [llvm::DataLayout::getTypeStoreSize]. *)
|
||||||
|
val store_size : Llvm.lltype -> t -> Int64.t
|
||||||
|
|
||||||
|
(** Computes the ABI size of a type in bytes for a target.
|
||||||
|
See the method [llvm::DataLayout::getTypeAllocSize]. *)
|
||||||
|
val abi_size : Llvm.lltype -> t -> Int64.t
|
||||||
|
|
||||||
|
(** Computes the ABI alignment of a type in bytes for a target.
|
||||||
|
See the method [llvm::DataLayout::getTypeABISize]. *)
|
||||||
|
val abi_align : Llvm.lltype -> t -> int
|
||||||
|
|
||||||
|
(** Computes the call frame alignment of a type in bytes for a target.
|
||||||
|
See the method [llvm::DataLayout::getTypeABISize]. *)
|
||||||
|
val stack_align : Llvm.lltype -> t -> int
|
||||||
|
|
||||||
|
(** Computes the preferred alignment of a type in bytes for a target.
|
||||||
|
See the method [llvm::DataLayout::getTypeABISize]. *)
|
||||||
|
val preferred_align : Llvm.lltype -> t -> int
|
||||||
|
|
||||||
|
(** Computes the preferred alignment of a global variable in bytes for
|
||||||
|
a target. See the method [llvm::DataLayout::getPreferredAlignment]. *)
|
||||||
|
val preferred_align_of_global : Llvm.llvalue -> t -> int
|
||||||
|
|
||||||
|
(** Computes the structure element that contains the byte offset for a target.
|
||||||
|
See the method [llvm::StructLayout::getElementContainingOffset]. *)
|
||||||
|
val element_at_offset : Llvm.lltype -> Int64.t -> t -> int
|
||||||
|
|
||||||
|
(** Computes the byte offset of the indexed struct element for a target.
|
||||||
|
See the method [llvm::StructLayout::getElementContainingOffset]. *)
|
||||||
|
val offset_of_element : Llvm.lltype -> int -> t -> Int64.t
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {6 Target} *)
|
||||||
|
|
||||||
|
module Target : sig
|
||||||
|
type t
|
||||||
|
|
||||||
|
(** [default_triple ()] returns the default target triple for current
|
||||||
|
platform. *)
|
||||||
|
val default_triple : unit -> string
|
||||||
|
|
||||||
|
(** [first ()] returns the first target in the registered targets
|
||||||
|
list, or [None]. *)
|
||||||
|
val first : unit -> t option
|
||||||
|
|
||||||
|
(** [succ t] returns the next target after [t], or [None]
|
||||||
|
if [t] was the last target. *)
|
||||||
|
val succ : t -> t option
|
||||||
|
|
||||||
|
(** [all ()] returns a list of known targets. *)
|
||||||
|
val all : unit -> t list
|
||||||
|
|
||||||
|
(** [by_name name] returns [Some t] if a target [t] named [name] is
|
||||||
|
registered, or [None] otherwise. *)
|
||||||
|
val by_name : string -> t option
|
||||||
|
|
||||||
|
(** [by_triple triple] returns a target for a triple [triple], or raises
|
||||||
|
[Error] if [triple] does not correspond to a registered target. *)
|
||||||
|
val by_triple : string -> t
|
||||||
|
|
||||||
|
(** Returns the name of a target. See [llvm::Target::getName]. *)
|
||||||
|
val name : t -> string
|
||||||
|
|
||||||
|
(** Returns the description of a target.
|
||||||
|
See [llvm::Target::getDescription]. *)
|
||||||
|
val description : t -> string
|
||||||
|
|
||||||
|
(** Returns [true] if the target has a JIT. *)
|
||||||
|
val has_jit : t -> bool
|
||||||
|
|
||||||
|
(** Returns [true] if the target has a target machine associated. *)
|
||||||
|
val has_target_machine : t -> bool
|
||||||
|
|
||||||
|
(** Returns [true] if the target has an ASM backend (required for
|
||||||
|
emitting output). *)
|
||||||
|
val has_asm_backend : t -> bool
|
||||||
|
end
|
||||||
|
|
||||||
|
(** {6 Target Machine} *)
|
||||||
|
|
||||||
|
module TargetMachine : sig
|
||||||
|
type t
|
||||||
|
|
||||||
|
(** Creates a new target machine.
|
||||||
|
See [llvm::Target::createTargetMachine]. *)
|
||||||
|
val create : triple:string -> ?cpu:string -> ?features:string ->
|
||||||
|
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t ->
|
||||||
|
?code_model:CodeModel.t -> Target.t -> t
|
||||||
|
|
||||||
|
(** Returns the Target used in a TargetMachine *)
|
||||||
|
val target : t -> Target.t
|
||||||
|
|
||||||
|
(** Returns the triple used while creating this target machine. See
|
||||||
|
[llvm::TargetMachine::getTriple]. *)
|
||||||
|
val triple : t -> string
|
||||||
|
|
||||||
|
(** Returns the CPU used while creating this target machine. See
|
||||||
|
[llvm::TargetMachine::getCPU]. *)
|
||||||
|
val cpu : t -> string
|
||||||
|
|
||||||
|
(** Returns the data layout of this target machine. *)
|
||||||
|
val data_layout : t -> DataLayout.t
|
||||||
|
|
||||||
|
(** Returns the feature string used while creating this target machine. See
|
||||||
|
[llvm::TargetMachine::getFeatureString]. *)
|
||||||
|
val features : t -> string
|
||||||
|
|
||||||
|
(** Adds the target-specific analysis passes to the pass manager.
|
||||||
|
See [llvm::TargetMachine::addAnalysisPasses]. *)
|
||||||
|
val add_analysis_passes : [< Llvm.PassManager.any ] Llvm.PassManager.t -> t -> unit
|
||||||
|
|
||||||
|
(** Sets the assembly verbosity of this target machine.
|
||||||
|
See [llvm::TargetMachine::setAsmVerbosity]. *)
|
||||||
|
val set_verbose_asm : bool -> t -> unit
|
||||||
|
|
||||||
|
(** Emits assembly or object data for the given module to the given
|
||||||
|
file or raise [Error]. *)
|
||||||
|
val emit_to_file : Llvm.llmodule -> CodeGenFileType.t -> string -> t -> unit
|
||||||
|
|
||||||
|
(** Emits assembly or object data for the given module to a fresh memory
|
||||||
|
buffer or raise [Error]. *)
|
||||||
|
val emit_to_memory_buffer : Llvm.llmodule -> CodeGenFileType.t -> t ->
|
||||||
|
Llvm.llmemorybuffer
|
||||||
|
end
|
@ -0,0 +1,347 @@
|
|||||||
|
/*===-- target_ocaml.c - LLVM OCaml Glue ------------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Core.h"
|
||||||
|
#include "llvm-c/Target.h"
|
||||||
|
#include "llvm-c/TargetMachine.h"
|
||||||
|
#include "caml/alloc.h"
|
||||||
|
#include "caml/fail.h"
|
||||||
|
#include "caml/memory.h"
|
||||||
|
#include "caml/custom.h"
|
||||||
|
#include "caml/callback.h"
|
||||||
|
|
||||||
|
void llvm_raise(value Prototype, char *Message);
|
||||||
|
value llvm_string_of_message(char* Message);
|
||||||
|
|
||||||
|
/*===---- Data Layout -----------------------------------------------------===*/
|
||||||
|
|
||||||
|
#define DataLayout_val(v) (*(LLVMTargetDataRef *)(Data_custom_val(v)))
|
||||||
|
|
||||||
|
static void llvm_finalize_data_layout(value DataLayout) {
|
||||||
|
LLVMDisposeTargetData(DataLayout_val(DataLayout));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct custom_operations llvm_data_layout_ops = {
|
||||||
|
(char *) "Llvm_target.DataLayout.t",
|
||||||
|
llvm_finalize_data_layout,
|
||||||
|
custom_compare_default,
|
||||||
|
custom_hash_default,
|
||||||
|
custom_serialize_default,
|
||||||
|
custom_deserialize_default,
|
||||||
|
custom_compare_ext_default
|
||||||
|
};
|
||||||
|
|
||||||
|
value llvm_alloc_data_layout(LLVMTargetDataRef DataLayout) {
|
||||||
|
value V = alloc_custom(&llvm_data_layout_ops, sizeof(LLVMTargetDataRef),
|
||||||
|
0, 1);
|
||||||
|
DataLayout_val(V) = DataLayout;
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* string -> DataLayout.t */
|
||||||
|
CAMLprim value llvm_datalayout_of_string(value StringRep) {
|
||||||
|
return llvm_alloc_data_layout(LLVMCreateTargetData(String_val(StringRep)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DataLayout.t -> string */
|
||||||
|
CAMLprim value llvm_datalayout_as_string(value TD) {
|
||||||
|
char *StringRep = LLVMCopyStringRepOfTargetData(DataLayout_val(TD));
|
||||||
|
value Copy = copy_string(StringRep);
|
||||||
|
LLVMDisposeMessage(StringRep);
|
||||||
|
return Copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DataLayout.t -> Endian.t */
|
||||||
|
CAMLprim value llvm_datalayout_byte_order(value DL) {
|
||||||
|
return Val_int(LLVMByteOrder(DataLayout_val(DL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_pointer_size(value DL) {
|
||||||
|
return Val_int(LLVMPointerSize(DataLayout_val(DL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llcontext -> DataLayout.t -> Llvm.lltype */
|
||||||
|
CAMLprim LLVMTypeRef llvm_datalayout_intptr_type(LLVMContextRef C, value DL) {
|
||||||
|
return LLVMIntPtrTypeInContext(C, DataLayout_val(DL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int -> DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_qualified_pointer_size(value AS, value DL) {
|
||||||
|
return Val_int(LLVMPointerSizeForAS(DataLayout_val(DL), Int_val(AS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llcontext -> int -> DataLayout.t -> Llvm.lltype */
|
||||||
|
CAMLprim LLVMTypeRef llvm_datalayout_qualified_intptr_type(LLVMContextRef C,
|
||||||
|
value AS,
|
||||||
|
value DL) {
|
||||||
|
return LLVMIntPtrTypeForASInContext(C, DataLayout_val(DL), Int_val(AS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> DataLayout.t -> Int64.t */
|
||||||
|
CAMLprim value llvm_datalayout_size_in_bits(LLVMTypeRef Ty, value DL) {
|
||||||
|
return caml_copy_int64(LLVMSizeOfTypeInBits(DataLayout_val(DL), Ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> DataLayout.t -> Int64.t */
|
||||||
|
CAMLprim value llvm_datalayout_store_size(LLVMTypeRef Ty, value DL) {
|
||||||
|
return caml_copy_int64(LLVMStoreSizeOfType(DataLayout_val(DL), Ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> DataLayout.t -> Int64.t */
|
||||||
|
CAMLprim value llvm_datalayout_abi_size(LLVMTypeRef Ty, value DL) {
|
||||||
|
return caml_copy_int64(LLVMABISizeOfType(DataLayout_val(DL), Ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_abi_align(LLVMTypeRef Ty, value DL) {
|
||||||
|
return Val_int(LLVMABIAlignmentOfType(DataLayout_val(DL), Ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_stack_align(LLVMTypeRef Ty, value DL) {
|
||||||
|
return Val_int(LLVMCallFrameAlignmentOfType(DataLayout_val(DL), Ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_preferred_align(LLVMTypeRef Ty, value DL) {
|
||||||
|
return Val_int(LLVMPreferredAlignmentOfType(DataLayout_val(DL), Ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llvalue -> DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_preferred_align_of_global(LLVMValueRef GlobalVar,
|
||||||
|
value DL) {
|
||||||
|
return Val_int(LLVMPreferredAlignmentOfGlobal(DataLayout_val(DL), GlobalVar));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> Int64.t -> DataLayout.t -> int */
|
||||||
|
CAMLprim value llvm_datalayout_element_at_offset(LLVMTypeRef Ty, value Offset,
|
||||||
|
value DL) {
|
||||||
|
return Val_int(LLVMElementAtOffset(DataLayout_val(DL), Ty,
|
||||||
|
Int64_val(Offset)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.lltype -> int -> DataLayout.t -> Int64.t */
|
||||||
|
CAMLprim value llvm_datalayout_offset_of_element(LLVMTypeRef Ty, value Index,
|
||||||
|
value DL) {
|
||||||
|
return caml_copy_int64(LLVMOffsetOfElement(DataLayout_val(DL), Ty,
|
||||||
|
Int_val(Index)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===---- Target ----------------------------------------------------------===*/
|
||||||
|
|
||||||
|
static value llvm_target_option(LLVMTargetRef Target) {
|
||||||
|
if(Target != NULL) {
|
||||||
|
value Result = caml_alloc_small(1, 0);
|
||||||
|
Store_field(Result, 0, (value) Target);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Val_int(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unit -> string */
|
||||||
|
CAMLprim value llvm_target_default_triple(value Unit) {
|
||||||
|
char *TripleCStr = LLVMGetDefaultTargetTriple();
|
||||||
|
value TripleStr = caml_copy_string(TripleCStr);
|
||||||
|
LLVMDisposeMessage(TripleCStr);
|
||||||
|
|
||||||
|
return TripleStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unit -> Target.t option */
|
||||||
|
CAMLprim value llvm_target_first(value Unit) {
|
||||||
|
return llvm_target_option(LLVMGetFirstTarget());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target.t -> Target.t option */
|
||||||
|
CAMLprim value llvm_target_succ(LLVMTargetRef Target) {
|
||||||
|
return llvm_target_option(LLVMGetNextTarget(Target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* string -> Target.t option */
|
||||||
|
CAMLprim value llvm_target_by_name(value Name) {
|
||||||
|
return llvm_target_option(LLVMGetTargetFromName(String_val(Name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* string -> Target.t */
|
||||||
|
CAMLprim LLVMTargetRef llvm_target_by_triple(value Triple) {
|
||||||
|
LLVMTargetRef T;
|
||||||
|
char *Error;
|
||||||
|
|
||||||
|
if(LLVMGetTargetFromTriple(String_val(Triple), &T, &Error))
|
||||||
|
llvm_raise(*caml_named_value("Llvm_target.Error"), Error);
|
||||||
|
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target.t -> string */
|
||||||
|
CAMLprim value llvm_target_name(LLVMTargetRef Target) {
|
||||||
|
return caml_copy_string(LLVMGetTargetName(Target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target.t -> string */
|
||||||
|
CAMLprim value llvm_target_description(LLVMTargetRef Target) {
|
||||||
|
return caml_copy_string(LLVMGetTargetDescription(Target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target.t -> bool */
|
||||||
|
CAMLprim value llvm_target_has_jit(LLVMTargetRef Target) {
|
||||||
|
return Val_bool(LLVMTargetHasJIT(Target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target.t -> bool */
|
||||||
|
CAMLprim value llvm_target_has_target_machine(LLVMTargetRef Target) {
|
||||||
|
return Val_bool(LLVMTargetHasTargetMachine(Target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Target.t -> bool */
|
||||||
|
CAMLprim value llvm_target_has_asm_backend(LLVMTargetRef Target) {
|
||||||
|
return Val_bool(LLVMTargetHasAsmBackend(Target));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===---- Target Machine --------------------------------------------------===*/
|
||||||
|
|
||||||
|
#define TargetMachine_val(v) (*(LLVMTargetMachineRef *)(Data_custom_val(v)))
|
||||||
|
|
||||||
|
static void llvm_finalize_target_machine(value Machine) {
|
||||||
|
LLVMDisposeTargetMachine(TargetMachine_val(Machine));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct custom_operations llvm_target_machine_ops = {
|
||||||
|
(char *) "Llvm_target.TargetMachine.t",
|
||||||
|
llvm_finalize_target_machine,
|
||||||
|
custom_compare_default,
|
||||||
|
custom_hash_default,
|
||||||
|
custom_serialize_default,
|
||||||
|
custom_deserialize_default,
|
||||||
|
custom_compare_ext_default
|
||||||
|
};
|
||||||
|
|
||||||
|
static value llvm_alloc_targetmachine(LLVMTargetMachineRef Machine) {
|
||||||
|
value V = alloc_custom(&llvm_target_machine_ops, sizeof(LLVMTargetMachineRef),
|
||||||
|
0, 1);
|
||||||
|
TargetMachine_val(V) = Machine;
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* triple:string -> ?cpu:string -> ?features:string
|
||||||
|
?level:CodeGenOptLevel.t -> ?reloc_mode:RelocMode.t
|
||||||
|
?code_model:CodeModel.t -> Target.t -> TargetMachine.t */
|
||||||
|
CAMLprim value llvm_create_targetmachine_native(value Triple, value CPU,
|
||||||
|
value Features, value OptLevel, value RelocMode,
|
||||||
|
value CodeModel, LLVMTargetRef Target) {
|
||||||
|
LLVMTargetMachineRef Machine;
|
||||||
|
const char *CPUStr = "", *FeaturesStr = "";
|
||||||
|
LLVMCodeGenOptLevel OptLevelEnum = LLVMCodeGenLevelDefault;
|
||||||
|
LLVMRelocMode RelocModeEnum = LLVMRelocDefault;
|
||||||
|
LLVMCodeModel CodeModelEnum = LLVMCodeModelDefault;
|
||||||
|
|
||||||
|
if(CPU != Val_int(0))
|
||||||
|
CPUStr = String_val(Field(CPU, 0));
|
||||||
|
if(Features != Val_int(0))
|
||||||
|
FeaturesStr = String_val(Field(Features, 0));
|
||||||
|
if(OptLevel != Val_int(0))
|
||||||
|
OptLevelEnum = Int_val(Field(OptLevel, 0));
|
||||||
|
if(RelocMode != Val_int(0))
|
||||||
|
RelocModeEnum = Int_val(Field(RelocMode, 0));
|
||||||
|
if(CodeModel != Val_int(0))
|
||||||
|
CodeModelEnum = Int_val(Field(CodeModel, 0));
|
||||||
|
|
||||||
|
Machine = LLVMCreateTargetMachine(Target, String_val(Triple), CPUStr,
|
||||||
|
FeaturesStr, OptLevelEnum, RelocModeEnum, CodeModelEnum);
|
||||||
|
|
||||||
|
return llvm_alloc_targetmachine(Machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value llvm_create_targetmachine_bytecode(value *argv, int argn) {
|
||||||
|
return llvm_create_targetmachine_native(argv[0], argv[1], argv[2], argv[3],
|
||||||
|
argv[4], argv[5], (LLVMTargetRef) argv[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TargetMachine.t -> Target.t */
|
||||||
|
CAMLprim LLVMTargetRef llvm_targetmachine_target(value Machine) {
|
||||||
|
return LLVMGetTargetMachineTarget(TargetMachine_val(Machine));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TargetMachine.t -> string */
|
||||||
|
CAMLprim value llvm_targetmachine_triple(value Machine) {
|
||||||
|
return llvm_string_of_message(LLVMGetTargetMachineTriple(
|
||||||
|
TargetMachine_val(Machine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TargetMachine.t -> string */
|
||||||
|
CAMLprim value llvm_targetmachine_cpu(value Machine) {
|
||||||
|
return llvm_string_of_message(LLVMGetTargetMachineCPU(
|
||||||
|
TargetMachine_val(Machine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TargetMachine.t -> string */
|
||||||
|
CAMLprim value llvm_targetmachine_features(value Machine) {
|
||||||
|
return llvm_string_of_message(LLVMGetTargetMachineFeatureString(
|
||||||
|
TargetMachine_val(Machine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TargetMachine.t -> DataLayout.t */
|
||||||
|
CAMLprim value llvm_targetmachine_data_layout(value Machine) {
|
||||||
|
return llvm_alloc_data_layout(LLVMCreateTargetDataLayout(
|
||||||
|
TargetMachine_val(Machine)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bool -> TargetMachine.t -> unit */
|
||||||
|
CAMLprim value llvm_targetmachine_set_verbose_asm(value Verb, value Machine) {
|
||||||
|
LLVMSetTargetMachineAsmVerbosity(TargetMachine_val(Machine), Bool_val(Verb));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llmodule -> CodeGenFileType.t -> string -> TargetMachine.t -> unit */
|
||||||
|
CAMLprim value llvm_targetmachine_emit_to_file(LLVMModuleRef Module,
|
||||||
|
value FileType, value FileName, value Machine) {
|
||||||
|
char *ErrorMessage;
|
||||||
|
|
||||||
|
if(LLVMTargetMachineEmitToFile(TargetMachine_val(Machine), Module,
|
||||||
|
String_val(FileName), Int_val(FileType),
|
||||||
|
&ErrorMessage)) {
|
||||||
|
llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Llvm.llmodule -> CodeGenFileType.t -> TargetMachine.t ->
|
||||||
|
Llvm.llmemorybuffer */
|
||||||
|
CAMLprim LLVMMemoryBufferRef llvm_targetmachine_emit_to_memory_buffer(
|
||||||
|
LLVMModuleRef Module, value FileType,
|
||||||
|
value Machine) {
|
||||||
|
char *ErrorMessage;
|
||||||
|
LLVMMemoryBufferRef Buffer;
|
||||||
|
|
||||||
|
if(LLVMTargetMachineEmitToMemoryBuffer(TargetMachine_val(Machine), Module,
|
||||||
|
Int_val(FileType), &ErrorMessage,
|
||||||
|
&Buffer)) {
|
||||||
|
llvm_raise(*caml_named_value("Llvm_target.Error"), ErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TargetMachine.t -> Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_targetmachine_add_analysis_passes(LLVMPassManagerRef PM,
|
||||||
|
value Machine) {
|
||||||
|
LLVMAddAnalysisPasses(TargetMachine_val(Machine), PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
add_subdirectory(ipo)
|
||||||
|
add_subdirectory(passmgr_builder)
|
||||||
|
add_subdirectory(scalar_opts)
|
||||||
|
add_subdirectory(utils)
|
||||||
|
add_subdirectory(vectorize)
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_ipo
|
||||||
|
OCAML llvm_ipo
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C ipo_ocaml
|
||||||
|
LLVM ipo)
|
@ -0,0 +1,110 @@
|
|||||||
|
/*===-- ipo_ocaml.c - LLVM OCaml Glue ---------------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Transforms/IPO.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/misc.h"
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_argument_promotion(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddArgumentPromotionPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_constant_merge(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddConstantMergePass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_merge_functions(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddMergeFunctionsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_dead_arg_elimination(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddDeadArgEliminationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_function_attrs(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddFunctionAttrsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_function_inlining(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddFunctionInliningPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_always_inliner(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddAlwaysInlinerPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_global_dce(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddGlobalDCEPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_global_optimizer(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddGlobalOptimizerPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_ip_constant_propagation(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddIPConstantPropagationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_prune_eh(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddPruneEHPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_ipsccp(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddIPSCCPPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> all_but_main:bool -> unit */
|
||||||
|
CAMLprim value llvm_add_internalize(LLVMPassManagerRef PM, value AllButMain) {
|
||||||
|
LLVMAddInternalizePass(PM, Bool_val(AllButMain));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_strip_dead_prototypes(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddStripDeadPrototypesPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [`Module] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_strip_symbols(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddStripSymbolsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
(*===-- llvm_ipo.ml - LLVM OCaml Interface --------------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external add_argument_promotion
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_argument_promotion"
|
||||||
|
external add_constant_merge
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_constant_merge"
|
||||||
|
external add_merge_functions
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_merge_functions"
|
||||||
|
external add_dead_arg_elimination
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_dead_arg_elimination"
|
||||||
|
external add_function_attrs
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_function_attrs"
|
||||||
|
external add_function_inlining
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_function_inlining"
|
||||||
|
external add_always_inliner
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_always_inliner"
|
||||||
|
external add_global_dce
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_global_dce"
|
||||||
|
external add_global_optimizer
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_global_optimizer"
|
||||||
|
external add_ipc_propagation
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_ip_constant_propagation"
|
||||||
|
external add_prune_eh
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_prune_eh"
|
||||||
|
external add_ipsccp
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_ipsccp"
|
||||||
|
external add_internalize
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> all_but_main:bool -> unit
|
||||||
|
= "llvm_add_internalize"
|
||||||
|
external add_strip_dead_prototypes
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_strip_dead_prototypes"
|
||||||
|
external add_strip_symbols
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_strip_symbols"
|
@ -0,0 +1,87 @@
|
|||||||
|
(*===-- llvm_ipo.mli - LLVM OCaml Interface -------------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** IPO Transforms.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM interprocedural optimizations, the
|
||||||
|
classes in the [LLVMIPO] library. *)
|
||||||
|
|
||||||
|
(** See the [llvm::createAddArgumentPromotionPass] function. *)
|
||||||
|
external add_argument_promotion
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_argument_promotion"
|
||||||
|
|
||||||
|
(** See the [llvm::createConstantMergePass] function. *)
|
||||||
|
external add_constant_merge
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_constant_merge"
|
||||||
|
|
||||||
|
(** See the [llvm::createMergeFunctionsPass] function. *)
|
||||||
|
external add_merge_functions
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_merge_functions"
|
||||||
|
|
||||||
|
(** See the [llvm::createDeadArgEliminationPass] function. *)
|
||||||
|
external add_dead_arg_elimination
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_dead_arg_elimination"
|
||||||
|
|
||||||
|
(** See the [llvm::createFunctionAttrsPass] function. *)
|
||||||
|
external add_function_attrs
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_function_attrs"
|
||||||
|
|
||||||
|
(** See the [llvm::createFunctionInliningPass] function. *)
|
||||||
|
external add_function_inlining
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_function_inlining"
|
||||||
|
|
||||||
|
(** See the [llvm::createAlwaysInlinerPass] function. *)
|
||||||
|
external add_always_inliner
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_always_inliner"
|
||||||
|
|
||||||
|
(** See the [llvm::createGlobalDCEPass] function. *)
|
||||||
|
external add_global_dce
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_global_dce"
|
||||||
|
|
||||||
|
(** See the [llvm::createGlobalOptimizerPass] function. *)
|
||||||
|
external add_global_optimizer
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_global_optimizer"
|
||||||
|
|
||||||
|
(** See the [llvm::createIPConstantPropagationPass] function. *)
|
||||||
|
external add_ipc_propagation
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_ip_constant_propagation"
|
||||||
|
|
||||||
|
(** See the [llvm::createPruneEHPass] function. *)
|
||||||
|
external add_prune_eh
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_prune_eh"
|
||||||
|
|
||||||
|
(** See the [llvm::createIPSCCPPass] function. *)
|
||||||
|
external add_ipsccp
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_ipsccp"
|
||||||
|
|
||||||
|
(** See the [llvm::createInternalizePass] function. *)
|
||||||
|
external add_internalize
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> all_but_main:bool -> unit
|
||||||
|
= "llvm_add_internalize"
|
||||||
|
|
||||||
|
(** See the [llvm::createStripDeadPrototypesPass] function. *)
|
||||||
|
external add_strip_dead_prototypes
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_strip_dead_prototypes"
|
||||||
|
|
||||||
|
(** See the [llvm::createStripSymbolsPass] function. *)
|
||||||
|
external add_strip_symbols
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_strip_symbols"
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_passmgr_builder
|
||||||
|
OCAML llvm_passmgr_builder
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C passmgr_builder_ocaml
|
||||||
|
LLVM ipo)
|
@ -0,0 +1,31 @@
|
|||||||
|
(*===-- llvm_passmgr_builder.ml - LLVM OCaml Interface --------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
type t
|
||||||
|
|
||||||
|
external create : unit -> t
|
||||||
|
= "llvm_pmbuilder_create"
|
||||||
|
external set_opt_level : int -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_opt_level"
|
||||||
|
external set_size_level : int -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_size_level"
|
||||||
|
external set_disable_unit_at_a_time : bool -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_disable_unit_at_a_time"
|
||||||
|
external set_disable_unroll_loops : bool -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_disable_unroll_loops"
|
||||||
|
external use_inliner_with_threshold : int -> t -> unit
|
||||||
|
= "llvm_pmbuilder_use_inliner_with_threshold"
|
||||||
|
external populate_function_pass_manager
|
||||||
|
: [ `Function ] Llvm.PassManager.t -> t -> unit
|
||||||
|
= "llvm_pmbuilder_populate_function_pass_manager"
|
||||||
|
external populate_module_pass_manager
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> t -> unit
|
||||||
|
= "llvm_pmbuilder_populate_module_pass_manager"
|
||||||
|
external populate_lto_pass_manager
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> internalize:bool -> run_inliner:bool -> t -> unit
|
||||||
|
= "llvm_pmbuilder_populate_lto_pass_manager"
|
@ -0,0 +1,53 @@
|
|||||||
|
(*===-- llvm_passmgr_builder.mli - LLVM OCaml Interface -------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Pass Manager Builder.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM pass manager builder
|
||||||
|
from the [LLVMCore] library. *)
|
||||||
|
|
||||||
|
type t
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder] function. *)
|
||||||
|
external create : unit -> t
|
||||||
|
= "llvm_pmbuilder_create"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::OptLevel] function. *)
|
||||||
|
external set_opt_level : int -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_opt_level"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::SizeLevel] function. *)
|
||||||
|
external set_size_level : int -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_size_level"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::DisableUnitAtATime] function. *)
|
||||||
|
external set_disable_unit_at_a_time : bool -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_disable_unit_at_a_time"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::DisableUnrollLoops] function. *)
|
||||||
|
external set_disable_unroll_loops : bool -> t -> unit
|
||||||
|
= "llvm_pmbuilder_set_disable_unroll_loops"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::Inliner] function. *)
|
||||||
|
external use_inliner_with_threshold : int -> t -> unit
|
||||||
|
= "llvm_pmbuilder_use_inliner_with_threshold"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::populateFunctionPassManager] function. *)
|
||||||
|
external populate_function_pass_manager
|
||||||
|
: [ `Function ] Llvm.PassManager.t -> t -> unit
|
||||||
|
= "llvm_pmbuilder_populate_function_pass_manager"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::populateModulePassManager] function. *)
|
||||||
|
external populate_module_pass_manager
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> t -> unit
|
||||||
|
= "llvm_pmbuilder_populate_module_pass_manager"
|
||||||
|
|
||||||
|
(** See the [llvm::PassManagerBuilder::populateLTOPassManager] function. *)
|
||||||
|
external populate_lto_pass_manager
|
||||||
|
: [ `Module ] Llvm.PassManager.t -> internalize:bool -> run_inliner:bool -> t -> unit
|
||||||
|
= "llvm_pmbuilder_populate_lto_pass_manager"
|
@ -0,0 +1,111 @@
|
|||||||
|
/*===-- passmgr_builder_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Transforms/PassManagerBuilder.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/custom.h"
|
||||||
|
#include "caml/misc.h"
|
||||||
|
|
||||||
|
#define PMBuilder_val(v) (*(LLVMPassManagerBuilderRef *)(Data_custom_val(v)))
|
||||||
|
|
||||||
|
static void llvm_finalize_pmbuilder(value PMB) {
|
||||||
|
LLVMPassManagerBuilderDispose(PMBuilder_val(PMB));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct custom_operations pmbuilder_ops = {
|
||||||
|
(char *) "Llvm_passmgr_builder.t",
|
||||||
|
llvm_finalize_pmbuilder,
|
||||||
|
custom_compare_default,
|
||||||
|
custom_hash_default,
|
||||||
|
custom_serialize_default,
|
||||||
|
custom_deserialize_default,
|
||||||
|
custom_compare_ext_default
|
||||||
|
};
|
||||||
|
|
||||||
|
static value alloc_pmbuilder(LLVMPassManagerBuilderRef Ref) {
|
||||||
|
value Val = alloc_custom(&pmbuilder_ops,
|
||||||
|
sizeof(LLVMPassManagerBuilderRef), 0, 1);
|
||||||
|
PMBuilder_val(Val) = Ref;
|
||||||
|
return Val;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_create(value Unit) {
|
||||||
|
return alloc_pmbuilder(LLVMPassManagerBuilderCreate());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_set_opt_level(value OptLevel, value PMB) {
|
||||||
|
LLVMPassManagerBuilderSetOptLevel(PMBuilder_val(PMB), Int_val(OptLevel));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_set_size_level(value SizeLevel, value PMB) {
|
||||||
|
LLVMPassManagerBuilderSetSizeLevel(PMBuilder_val(PMB), Int_val(SizeLevel));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_use_inliner_with_threshold(
|
||||||
|
value Threshold, value PMB) {
|
||||||
|
LLVMPassManagerBuilderSetOptLevel(PMBuilder_val(PMB), Int_val(Threshold));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bool -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_set_disable_unit_at_a_time(
|
||||||
|
value DisableUnitAtATime, value PMB) {
|
||||||
|
LLVMPassManagerBuilderSetDisableUnitAtATime(
|
||||||
|
PMBuilder_val(PMB), Bool_val(DisableUnitAtATime));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bool -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_set_disable_unroll_loops(
|
||||||
|
value DisableUnroll, value PMB) {
|
||||||
|
LLVMPassManagerBuilderSetDisableUnrollLoops(
|
||||||
|
PMBuilder_val(PMB), Bool_val(DisableUnroll));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [ `Function ] Llvm.PassManager.t -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_populate_function_pass_manager(
|
||||||
|
LLVMPassManagerRef PM, value PMB) {
|
||||||
|
LLVMPassManagerBuilderPopulateFunctionPassManager(
|
||||||
|
PMBuilder_val(PMB), PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [ `Module ] Llvm.PassManager.t -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_populate_module_pass_manager(
|
||||||
|
LLVMPassManagerRef PM, value PMB) {
|
||||||
|
LLVMPassManagerBuilderPopulateModulePassManager(
|
||||||
|
PMBuilder_val(PMB), PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [ `Module ] Llvm.PassManager.t ->
|
||||||
|
internalize:bool -> run_inliner:bool -> t -> unit */
|
||||||
|
CAMLprim value llvm_pmbuilder_populate_lto_pass_manager(
|
||||||
|
LLVMPassManagerRef PM, value Internalize, value RunInliner,
|
||||||
|
value PMB) {
|
||||||
|
LLVMPassManagerBuilderPopulateLTOPassManager(
|
||||||
|
PMBuilder_val(PMB), PM,
|
||||||
|
Bool_val(Internalize), Bool_val(RunInliner));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_scalar_opts
|
||||||
|
OCAML llvm_scalar_opts
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C scalar_opts_ocaml
|
||||||
|
LLVM scalaropts)
|
@ -0,0 +1,131 @@
|
|||||||
|
(*===-- llvm_scalar_opts.ml - LLVM OCaml Interface ------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external add_aggressive_dce
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_aggressive_dce"
|
||||||
|
external add_dce
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_dce"
|
||||||
|
external add_alignment_from_assumptions
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_alignment_from_assumptions"
|
||||||
|
external add_cfg_simplification
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_cfg_simplification"
|
||||||
|
external add_dead_store_elimination
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_dead_store_elimination"
|
||||||
|
external add_scalarizer
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalarizer"
|
||||||
|
external add_merged_load_store_motion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_merged_load_store_motion"
|
||||||
|
external add_gvn
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_gvn"
|
||||||
|
external add_ind_var_simplification
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_ind_var_simplify"
|
||||||
|
external add_instruction_combination
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_instruction_combining"
|
||||||
|
external add_jump_threading
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_jump_threading"
|
||||||
|
external add_licm
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_licm"
|
||||||
|
external add_loop_deletion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_deletion"
|
||||||
|
external add_loop_idiom
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_idiom"
|
||||||
|
external add_loop_rotation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_rotate"
|
||||||
|
external add_loop_reroll
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_reroll"
|
||||||
|
external add_loop_unroll
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_unroll"
|
||||||
|
external add_loop_unswitch
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_unswitch"
|
||||||
|
external add_memcpy_opt
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_memcpy_opt"
|
||||||
|
external add_partially_inline_lib_calls
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_partially_inline_lib_calls"
|
||||||
|
external add_lower_atomic
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_atomic"
|
||||||
|
external add_lower_switch
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_switch"
|
||||||
|
external add_memory_to_register_promotion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_promote_memory_to_register"
|
||||||
|
external add_reassociation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_reassociation"
|
||||||
|
external add_sccp
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_sccp"
|
||||||
|
external add_scalar_repl_aggregation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalar_repl_aggregates"
|
||||||
|
external add_scalar_repl_aggregation_ssa
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalar_repl_aggregates_ssa"
|
||||||
|
external add_scalar_repl_aggregation_with_threshold
|
||||||
|
: int -> [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalar_repl_aggregates_with_threshold"
|
||||||
|
external add_lib_call_simplification
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_simplify_lib_calls"
|
||||||
|
external add_tail_call_elimination
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_tail_call_elimination"
|
||||||
|
external add_constant_propagation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_constant_propagation"
|
||||||
|
external add_memory_to_register_demotion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_demote_memory_to_register"
|
||||||
|
external add_verifier
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_verifier"
|
||||||
|
external add_correlated_value_propagation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_correlated_value_propagation"
|
||||||
|
external add_early_cse
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_early_cse"
|
||||||
|
external add_lower_expect_intrinsic
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_expect_intrinsic"
|
||||||
|
external add_lower_constant_intrinsics
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_constant_intrinsics"
|
||||||
|
external add_type_based_alias_analysis
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_type_based_alias_analysis"
|
||||||
|
external add_scoped_no_alias_alias_analysis
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scoped_no_alias_aa"
|
||||||
|
external add_basic_alias_analysis
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_basic_alias_analysis"
|
||||||
|
external add_unify_function_exit_nodes
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_unify_function_exit_nodes"
|
@ -0,0 +1,217 @@
|
|||||||
|
(*===-- llvm_scalar_opts.mli - LLVM OCaml Interface -----------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Scalar Transforms.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM scalar transforms, the
|
||||||
|
classes in the [LLVMScalarOpts] library. *)
|
||||||
|
|
||||||
|
(** See the [llvm::createAggressiveDCEPass] function. *)
|
||||||
|
external add_aggressive_dce
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_aggressive_dce"
|
||||||
|
|
||||||
|
(** See the [llvm::createDCEPass] function. *)
|
||||||
|
external add_dce
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_dce"
|
||||||
|
|
||||||
|
(** See the [llvm::createAlignmentFromAssumptionsPass] function. *)
|
||||||
|
external add_alignment_from_assumptions
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_alignment_from_assumptions"
|
||||||
|
|
||||||
|
(** See the [llvm::createCFGSimplificationPass] function. *)
|
||||||
|
external add_cfg_simplification
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_cfg_simplification"
|
||||||
|
|
||||||
|
(** See [llvm::createDeadStoreEliminationPass] function. *)
|
||||||
|
external add_dead_store_elimination
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_dead_store_elimination"
|
||||||
|
|
||||||
|
(** See [llvm::createScalarizerPass] function. *)
|
||||||
|
external add_scalarizer
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalarizer"
|
||||||
|
|
||||||
|
(** See [llvm::createMergedLoadStoreMotionPass] function. *)
|
||||||
|
external add_merged_load_store_motion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_merged_load_store_motion"
|
||||||
|
|
||||||
|
(** See the [llvm::createGVNPass] function. *)
|
||||||
|
external add_gvn
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_gvn"
|
||||||
|
|
||||||
|
(** See the [llvm::createIndVarSimplifyPass] function. *)
|
||||||
|
external add_ind_var_simplification
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_ind_var_simplify"
|
||||||
|
|
||||||
|
(** See the [llvm::createInstructionCombiningPass] function. *)
|
||||||
|
external add_instruction_combination
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_instruction_combining"
|
||||||
|
|
||||||
|
(** See the [llvm::createJumpThreadingPass] function. *)
|
||||||
|
external add_jump_threading
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_jump_threading"
|
||||||
|
|
||||||
|
(** See the [llvm::createLICMPass] function. *)
|
||||||
|
external add_licm
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_licm"
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopDeletionPass] function. *)
|
||||||
|
external add_loop_deletion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_deletion"
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopIdiomPass] function. *)
|
||||||
|
external add_loop_idiom
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_idiom"
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopRotatePass] function. *)
|
||||||
|
external add_loop_rotation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_rotate"
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopRerollPass] function. *)
|
||||||
|
external add_loop_reroll
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_reroll"
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopUnrollPass] function. *)
|
||||||
|
external add_loop_unroll
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_unroll"
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopUnswitchPass] function. *)
|
||||||
|
external add_loop_unswitch
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_unswitch"
|
||||||
|
|
||||||
|
(** See the [llvm::createMemCpyOptPass] function. *)
|
||||||
|
external add_memcpy_opt
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_memcpy_opt"
|
||||||
|
|
||||||
|
(** See the [llvm::createPartiallyInlineLibCallsPass] function. *)
|
||||||
|
external add_partially_inline_lib_calls
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_partially_inline_lib_calls"
|
||||||
|
|
||||||
|
(** See the [llvm::createLowerAtomicPass] function. *)
|
||||||
|
external add_lower_atomic
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_atomic"
|
||||||
|
|
||||||
|
(** See the [llvm::createLowerSwitchPass] function. *)
|
||||||
|
external add_lower_switch
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_switch"
|
||||||
|
|
||||||
|
(** See the [llvm::createPromoteMemoryToRegisterPass] function. *)
|
||||||
|
external add_memory_to_register_promotion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_promote_memory_to_register"
|
||||||
|
|
||||||
|
(** See the [llvm::createReassociatePass] function. *)
|
||||||
|
external add_reassociation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_reassociation"
|
||||||
|
|
||||||
|
(** See the [llvm::createSCCPPass] function. *)
|
||||||
|
external add_sccp
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_sccp"
|
||||||
|
|
||||||
|
(** See the [llvm::createSROAPass] function. *)
|
||||||
|
external add_scalar_repl_aggregation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalar_repl_aggregates"
|
||||||
|
|
||||||
|
(** See the [llvm::createSROAPass] function. *)
|
||||||
|
external add_scalar_repl_aggregation_ssa
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalar_repl_aggregates_ssa"
|
||||||
|
|
||||||
|
(** See the [llvm::createSROAPass] function. *)
|
||||||
|
external add_scalar_repl_aggregation_with_threshold
|
||||||
|
: int -> [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scalar_repl_aggregates_with_threshold"
|
||||||
|
|
||||||
|
(** See the [llvm::createSimplifyLibCallsPass] function. *)
|
||||||
|
external add_lib_call_simplification
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_simplify_lib_calls"
|
||||||
|
|
||||||
|
(** See the [llvm::createTailCallEliminationPass] function. *)
|
||||||
|
external add_tail_call_elimination
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_tail_call_elimination"
|
||||||
|
|
||||||
|
(** See the [llvm::createConstantPropagationPass] function. *)
|
||||||
|
external add_constant_propagation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_constant_propagation"
|
||||||
|
|
||||||
|
(** See the [llvm::createDemoteMemoryToRegisterPass] function. *)
|
||||||
|
external add_memory_to_register_demotion
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_demote_memory_to_register"
|
||||||
|
|
||||||
|
(** See the [llvm::createVerifierPass] function. *)
|
||||||
|
external add_verifier
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_verifier"
|
||||||
|
|
||||||
|
(** See the [llvm::createCorrelatedValuePropagationPass] function. *)
|
||||||
|
external add_correlated_value_propagation
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_correlated_value_propagation"
|
||||||
|
|
||||||
|
(** See the [llvm::createEarlyCSE] function. *)
|
||||||
|
external add_early_cse
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_early_cse"
|
||||||
|
|
||||||
|
(** See the [llvm::createLowerExpectIntrinsicPass] function. *)
|
||||||
|
external add_lower_expect_intrinsic
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_expect_intrinsic"
|
||||||
|
|
||||||
|
(** See the [llvm::createLowerConstantIntrinsicsPass] function. *)
|
||||||
|
external add_lower_constant_intrinsics
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_lower_constant_intrinsics"
|
||||||
|
|
||||||
|
(** See the [llvm::createTypeBasedAliasAnalysisPass] function. *)
|
||||||
|
external add_type_based_alias_analysis
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_type_based_alias_analysis"
|
||||||
|
|
||||||
|
(** See the [llvm::createScopedNoAliasAAPass] function. *)
|
||||||
|
external add_scoped_no_alias_alias_analysis
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_scoped_no_alias_aa"
|
||||||
|
|
||||||
|
(** See the [llvm::createBasicAliasAnalysisPass] function. *)
|
||||||
|
external add_basic_alias_analysis
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_basic_alias_analysis"
|
||||||
|
|
||||||
|
(** See the [llvm::createUnifyFunctionExitNodesPass] function. *)
|
||||||
|
external add_unify_function_exit_nodes
|
||||||
|
: [< Llvm.PassManager.any ] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_unify_function_exit_nodes"
|
@ -0,0 +1,267 @@
|
|||||||
|
/*===-- scalar_opts_ocaml.c - LLVM OCaml Glue -------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Transforms/Scalar.h"
|
||||||
|
#include "llvm-c/Transforms/Utils.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/misc.h"
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_aggressive_dce(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddAggressiveDCEPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAMLprim value llvm_add_dce(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddDCEPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_alignment_from_assumptions(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddAlignmentFromAssumptionsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_cfg_simplification(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddCFGSimplificationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_dead_store_elimination(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddDeadStoreEliminationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_scalarizer(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddScalarizerPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_merged_load_store_motion(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddMergedLoadStoreMotionPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_gvn(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddGVNPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_ind_var_simplify(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddIndVarSimplifyPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_instruction_combining(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddInstructionCombiningPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_jump_threading(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddJumpThreadingPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_licm(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLICMPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_deletion(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopDeletionPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_idiom(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopIdiomPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_rotate(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopRotatePass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_reroll(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopRerollPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_unroll(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopUnrollPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_unswitch(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopUnswitchPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_memcpy_opt(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddMemCpyOptPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_partially_inline_lib_calls(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddPartiallyInlineLibCallsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_lower_atomic(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLowerAtomicPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_lower_switch(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLowerSwitchPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_promote_memory_to_register(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddPromoteMemoryToRegisterPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_reassociation(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddReassociatePass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_sccp(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddSCCPPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_scalar_repl_aggregates(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddScalarReplAggregatesPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_scalar_repl_aggregates_ssa(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddScalarReplAggregatesPassSSA(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int -> [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_scalar_repl_aggregates_with_threshold(value threshold,
|
||||||
|
LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddScalarReplAggregatesPassWithThreshold(PM, Int_val(threshold));
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_simplify_lib_calls(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddSimplifyLibCallsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_tail_call_elimination(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddTailCallEliminationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_constant_propagation(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddConstantPropagationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_demote_memory_to_register(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddDemoteMemoryToRegisterPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_verifier(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddVerifierPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_correlated_value_propagation(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddCorrelatedValuePropagationPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_early_cse(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddEarlyCSEPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_lower_expect_intrinsic(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLowerExpectIntrinsicPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_lower_constant_intrinsics(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLowerConstantIntrinsicsPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_type_based_alias_analysis(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddTypeBasedAliasAnalysisPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_scoped_no_alias_aa(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddScopedNoAliasAAPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_basic_alias_analysis(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddBasicAliasAnalysisPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_unify_function_exit_nodes(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddUnifyFunctionExitNodesPass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_transform_utils
|
||||||
|
OCAML llvm_transform_utils
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C transform_utils_ocaml
|
||||||
|
LLVM transformutils)
|
@ -0,0 +1,9 @@
|
|||||||
|
(*===-- llvm_transform_utils.ml - LLVM OCaml Interface --------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external clone_module : Llvm.llmodule -> Llvm.llmodule = "llvm_clone_module"
|
@ -0,0 +1,16 @@
|
|||||||
|
(*===-- llvm_transform_utils.mli - LLVM OCaml Interface -------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Transform Utilities.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM transform utilities, the
|
||||||
|
classes in the [LLVMTransformUtils] library. *)
|
||||||
|
|
||||||
|
(** [clone_module m] returns an exact copy of module [m].
|
||||||
|
See the [llvm::CloneModule] function. *)
|
||||||
|
external clone_module : Llvm.llmodule -> Llvm.llmodule = "llvm_clone_module"
|
@ -0,0 +1,31 @@
|
|||||||
|
/*===-- transform_utils_ocaml.c - LLVM OCaml Glue ---------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Core.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/misc.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not move directly into external. This function is here to pull in
|
||||||
|
* -lLLVMTransformUtils, which would otherwise be not linked on static builds,
|
||||||
|
* as ld can't see the reference from OCaml code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* llmodule -> llmodule */
|
||||||
|
CAMLprim LLVMModuleRef llvm_clone_module(LLVMModuleRef M) {
|
||||||
|
return LLVMCloneModule(M);
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
add_ocaml_library(llvm_vectorize
|
||||||
|
OCAML llvm_vectorize
|
||||||
|
OCAMLDEP llvm
|
||||||
|
C vectorize_ocaml
|
||||||
|
LLVM vectorize)
|
@ -0,0 +1,14 @@
|
|||||||
|
(*===-- llvm_vectorize.ml - LLVM OCaml Interface --------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
external add_loop_vectorize
|
||||||
|
: [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_vectorize"
|
||||||
|
external add_slp_vectorize
|
||||||
|
: [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_slp_vectorize"
|
@ -0,0 +1,22 @@
|
|||||||
|
(*===-- llvm_vectorize.mli - LLVM OCaml Interface -------------*- OCaml -*-===*
|
||||||
|
*
|
||||||
|
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
* See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
*
|
||||||
|
*===----------------------------------------------------------------------===*)
|
||||||
|
|
||||||
|
(** Vectorize Transforms.
|
||||||
|
|
||||||
|
This interface provides an OCaml API for LLVM vectorize transforms, the
|
||||||
|
classes in the [LLVMVectorize] library. *)
|
||||||
|
|
||||||
|
(** See the [llvm::createLoopVectorizePass] function. *)
|
||||||
|
external add_loop_vectorize
|
||||||
|
: [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_loop_vectorize"
|
||||||
|
|
||||||
|
(** See the [llvm::createSLPVectorizerPass] function. *)
|
||||||
|
external add_slp_vectorize
|
||||||
|
: [<Llvm.PassManager.any] Llvm.PassManager.t -> unit
|
||||||
|
= "llvm_add_slp_vectorize"
|
@ -0,0 +1,32 @@
|
|||||||
|
/*===-- vectorize_ocaml.c - LLVM OCaml Glue ---------------------*- C++ -*-===*\
|
||||||
|
|* *|
|
||||||
|
|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
|
||||||
|
|* Exceptions. *|
|
||||||
|
|* See https://llvm.org/LICENSE.txt for license information. *|
|
||||||
|
|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
|
||||||
|
|* *|
|
||||||
|
|*===----------------------------------------------------------------------===*|
|
||||||
|
|* *|
|
||||||
|
|* 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 *|
|
||||||
|
|* macros, since most of the parameters are not GC heap objects. *|
|
||||||
|
|* *|
|
||||||
|
\*===----------------------------------------------------------------------===*/
|
||||||
|
|
||||||
|
#include "llvm-c/Transforms/Vectorize.h"
|
||||||
|
#include "caml/mlvalues.h"
|
||||||
|
#include "caml/misc.h"
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_loop_vectorize(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddLoopVectorizePass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [<Llvm.PassManager.any] Llvm.PassManager.t -> unit */
|
||||||
|
CAMLprim value llvm_add_slp_vectorize(LLVMPassManagerRef PM) {
|
||||||
|
LLVMAddSLPVectorizePass(PM);
|
||||||
|
return Val_unit;
|
||||||
|
}
|
Loading…
Reference in new issue