aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bindings/ocaml/llvm/llvm.ml18
-rw-r--r--bindings/ocaml/llvm/llvm.mli54
-rw-r--r--bindings/ocaml/llvm/llvm_ocaml.c34
-rw-r--r--include/llvm-c/Core.h81
-rw-r--r--lib/VMCore/PassManager.cpp31
-rw-r--r--test/Bindings/Ocaml/vmcore.ml30
6 files changed, 234 insertions, 14 deletions
diff --git a/bindings/ocaml/llvm/llvm.ml b/bindings/ocaml/llvm/llvm.ml
index 92c60c4..dfa772b 100644
--- a/bindings/ocaml/llvm/llvm.ml
+++ b/bindings/ocaml/llvm/llvm.ml
@@ -483,6 +483,24 @@ module MemoryBuffer = struct
end
+(*===-- Pass Manager ------------------------------------------------------===*)
+
+module PassManager = struct
+ type 'a t
+ type any = [ `Module | `Function ]
+ external create : unit -> [ `Module ] t = "llvm_passmanager_create"
+ external create_function : llmoduleprovider -> [ `Function ] t
+ = "LLVMCreateFunctionPassManager"
+ external run_module : llmodule -> [ `Module ] t -> bool
+ = "llvm_passmanager_run_module"
+ external initialize : [ `Function ] t -> bool = "llvm_passmanager_initialize"
+ external run_function : llvalue -> [ `Function ] t -> bool
+ = "llvm_passmanager_run_function"
+ external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize"
+ external dispose : [< any ] t -> unit = "llvm_passmanager_dispose"
+end
+
+
(*===-- Non-Externs -------------------------------------------------------===*)
(* These functions are built using the externals, so must be declared late. *)
diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli
index 60b3bce..2d0b9f0 100644
--- a/bindings/ocaml/llvm/llvm.mli
+++ b/bindings/ocaml/llvm/llvm.mli
@@ -1357,3 +1357,57 @@ module MemoryBuffer : sig
(** Disposes of a memory buffer. *)
external dispose : llmemorybuffer -> unit = "llvm_memorybuffer_dispose"
end
+
+
+(** {6 Pass Managers} *)
+
+module PassManager : sig
+ (** *)
+ type 'a t
+ type any = [ `Module | `Function ]
+
+ (** [PassManager.create ()] constructs a new whole-module pass pipeline. This
+ type of pipeline is suitable for link-time optimization and whole-module
+ transformations.
+ See the constructor of [llvm::PassManager]. *)
+ external create : unit -> [ `Module ] t = "llvm_passmanager_create"
+
+ (** [PassManager.create_function mp] constructs a new function-by-function
+ pass pipeline over the module provider [mp]. It does not take ownership of
+ [mp]. This type of pipeline is suitable for code generation and JIT
+ compilation tasks.
+ See the constructor of [llvm::FunctionPassManager]. *)
+ external create_function : llmoduleprovider -> [ `Function ] t
+ = "LLVMCreateFunctionPassManager"
+
+ (** [run_module m pm] initializes, executes on the module [m], and finalizes
+ all of the passes scheduled in the pass manager [pm]. Returns [true] if
+ any of the passes modified the module, [false] otherwise.
+ See the [llvm::PassManager::run] method. *)
+ external run_module : llmodule -> [ `Module ] t -> bool
+ = "llvm_passmanager_run_module"
+
+ (** [initialize fpm] initializes all of the function passes scheduled in the
+ function pass manager [fpm]. Returns [true] if any of the passes modified
+ the module, [false] otherwise.
+ See the [llvm::FunctionPassManager::doInitialization] method. *)
+ external initialize : [ `Function ] t -> bool = "llvm_passmanager_initialize"
+
+ (** [run_function f fpm] executes all of the function passes scheduled in the
+ function pass manager [fpm] over the function [f]. Returns [true] if any
+ of the passes modified [f], [false] otherwise.
+ See the [llvm::FunctionPassManager::run] method. *)
+ external run_function : llvalue -> [ `Function ] t -> bool
+ = "llvm_passmanager_run_function"
+
+ (** [finalize fpm] finalizes all of the function passes scheduled in in the
+ function pass manager [fpm]. Returns [true] if any of the passes
+ modified the module, [false] otherwise.
+ See the [llvm::FunctionPassManager::doFinalization] method. *)
+ external finalize : [ `Function ] t -> bool = "llvm_passmanager_finalize"
+
+ (** Frees the memory of a pass pipeline. For function pipelines, does not free
+ the module provider.
+ See the destructor of [llvm::BasePassManager]. *)
+ external dispose : [< any ] t -> unit = "llvm_passmanager_dispose"
+end
diff --git a/bindings/ocaml/llvm/llvm_ocaml.c b/bindings/ocaml/llvm/llvm_ocaml.c
index ebe09dc..01e83e8 100644
--- a/bindings/ocaml/llvm/llvm_ocaml.c
+++ b/bindings/ocaml/llvm/llvm_ocaml.c
@@ -1180,3 +1180,37 @@ CAMLprim value llvm_memorybuffer_dispose(LLVMMemoryBufferRef MemBuf) {
return Val_unit;
}
+/*===-- Pass Managers -----------------------------------------------------===*/
+
+/* unit -> [ `Module ] PassManager.t */
+CAMLprim LLVMPassManagerRef llvm_passmanager_create(value Unit) {
+ return LLVMCreatePassManager();
+}
+
+/* llmodule -> [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_run_module(LLVMModuleRef M,
+ LLVMPassManagerRef PM) {
+ return Val_bool(LLVMRunPassManager(PM, M));
+}
+
+/* [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_initialize(LLVMPassManagerRef FPM) {
+ return Val_bool(LLVMInitializeFunctionPassManager(FPM));
+}
+
+/* llvalue -> [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_run_function(LLVMValueRef F,
+ LLVMPassManagerRef FPM) {
+ return Val_bool(LLVMRunFunctionPassManager(FPM, F));
+}
+
+/* [ `Function ] PassManager.t -> bool */
+CAMLprim value llvm_passmanager_finalize(LLVMPassManagerRef FPM) {
+ return Val_bool(LLVMFinalizeFunctionPassManager(FPM));
+}
+
+/* PassManager.any PassManager.t -> unit */
+CAMLprim value llvm_passmanager_dispose(LLVMPassManagerRef PM) {
+ LLVMDisposePassManager(PM);
+ return Val_unit;
+}
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h
index b10e2b7..6c4b5de 100644
--- a/include/llvm-c/Core.h
+++ b/include/llvm-c/Core.h
@@ -39,6 +39,8 @@
and 'unwrap' conversion functions. */
#include "llvm/Module.h"
#include "llvm/Support/LLVMBuilder.h"
+#include "llvm/Pass.h"
+#include "llvm/PassManager.h"
extern "C" {
#endif
@@ -79,6 +81,9 @@ typedef struct LLVMOpaqueModuleProvider *LLVMModuleProviderRef;
*/
typedef struct LLVMOpaqueMemoryBuffer *LLVMMemoryBufferRef;
+/** See the llvm::PassManagerBase class. */
+typedef struct LLVMOpaquePassManager *LLVMPassManagerRef;
+
typedef enum {
LLVMVoidTypeKind, /**< type with no size */
LLVMFloatTypeKind, /**< 32 bit floating point type */
@@ -575,6 +580,47 @@ int LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef *OutMemBuf,
char **OutMessage);
void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef MemBuf);
+
+/*===-- Pass Managers -----------------------------------------------------===*/
+
+/** Constructs a new whole-module pass pipeline. This type of pipeline is
+ suitable for link-time optimization and whole-module transformations.
+ See llvm::PassManager::PassManager. */
+LLVMPassManagerRef LLVMCreatePassManager();
+
+/** Constructs a new function-by-function pass pipeline over the module
+ provider. It does not take ownership of the module provider. This type of
+ pipeline is suitable for code generation and JIT compilation tasks.
+ See llvm::FunctionPassManager::FunctionPassManager. */
+LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef MP);
+
+/** Initializes, executes on the provided module, and finalizes all of the
+ passes scheduled in the pass manager. Returns 1 if any of the passes
+ modified the module, 0 otherwise. See llvm::PassManager::run(Module&). */
+int LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M);
+
+/** Initializes all of the function passes scheduled in the function pass
+ manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+ See llvm::FunctionPassManager::doInitialization. */
+int LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM);
+
+/** Executes all of the function passes scheduled in the function pass manager
+ on the provided function. Returns 1 if any of the passes modified the
+ function, false otherwise.
+ See llvm::FunctionPassManager::run(Function&). */
+int LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F);
+
+/** Finalizes all of the function passes scheduled in in the function pass
+ manager. Returns 1 if any of the passes modified the module, 0 otherwise.
+ See llvm::FunctionPassManager::doFinalization. */
+int LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM);
+
+/** Frees the memory of a pass pipeline. For function pipelines, does not free
+ the module provider.
+ See llvm::PassManagerBase::~PassManagerBase. */
+void LLVMDisposePassManager(LLVMPassManagerRef PM);
+
+
#ifdef __cplusplus
}
@@ -591,24 +637,40 @@ namespace llvm {
return reinterpret_cast<ref>(const_cast<ty*>(P)); \
}
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Type, LLVMTypeRef )
- DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Value, LLVMValueRef )
+ #define DEFINE_ISA_CONVERSION_FUNCTIONS(ty, ref) \
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
+ \
+ template<typename T> \
+ inline T *unwrap(ref P) { \
+ return cast<T>(unwrap(P)); \
+ }
+
+ #define DEFINE_STDCXX_CONVERSION_FUNCTIONS(ty, ref) \
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ty, ref) \
+ \
+ template<typename T> \
+ inline T *unwrap(ref P) { \
+ T *Q = dynamic_cast<T*>(unwrap(P)); \
+ assert(Q && "Invalid cast!"); \
+ return Q; \
+ }
+
+ DEFINE_ISA_CONVERSION_FUNCTIONS (Type, LLVMTypeRef )
+ DEFINE_ISA_CONVERSION_FUNCTIONS (Value, LLVMValueRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Module, LLVMModuleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMFoldingBuilder, LLVMBuilderRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(PATypeHolder, LLVMTypeHandleRef )
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(ModuleProvider, LLVMModuleProviderRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(MemoryBuffer, LLVMMemoryBufferRef )
+ DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBase, LLVMPassManagerRef )
+ #undef DEFINE_STDCXX_CONVERSION_FUNCTIONS
+ #undef DEFINE_ISA_CONVERSION_FUNCTIONS
#undef DEFINE_SIMPLE_CONVERSION_FUNCTIONS
/* Specialized opaque type conversions.
*/
- template<typename T>
- inline T *unwrap(LLVMTypeRef Ty) {
- return cast<T>(unwrap(Ty));
- }
-
inline Type **unwrap(LLVMTypeRef* Tys) {
return reinterpret_cast<Type**>(Tys);
}
@@ -619,11 +681,6 @@ namespace llvm {
/* Specialized opaque value conversions.
*/
- template<typename T>
- inline T *unwrap(LLVMValueRef Val) {
- return cast<T>(unwrap(Val));
- }
-
inline Value **unwrap(LLVMValueRef *Vals) {
return reinterpret_cast<Value**>(Vals);
}
diff --git a/lib/VMCore/PassManager.cpp b/lib/VMCore/PassManager.cpp
index 5a85a16..e7d7c5b 100644
--- a/lib/VMCore/PassManager.cpp
+++ b/lib/VMCore/PassManager.cpp
@@ -19,6 +19,7 @@
#include "llvm/ModuleProvider.h"
#include "llvm/Support/Streams.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm-c/Core.h"
#include <algorithm>
#include <vector>
#include <map>
@@ -1526,3 +1527,33 @@ void BasicBlockPass::assignPassManager(PMStack &PMS,
}
PassManagerBase::~PassManagerBase() {}
+
+/*===-- C Bindings --------------------------------------------------------===*/
+
+LLVMPassManagerRef LLVMCreatePassManager() {
+ return wrap(new PassManager());
+}
+
+LLVMPassManagerRef LLVMCreateFunctionPassManager(LLVMModuleProviderRef P) {
+ return wrap(new FunctionPassManager(unwrap(P)));
+}
+
+int LLVMRunPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
+ return unwrap<PassManager>(PM)->run(*unwrap(M));
+}
+
+int LLVMInitializeFunctionPassManager(LLVMPassManagerRef FPM) {
+ return unwrap<FunctionPassManager>(FPM)->doInitialization();
+}
+
+int LLVMRunFunctionPassManager(LLVMPassManagerRef FPM, LLVMValueRef F) {
+ return unwrap<FunctionPassManager>(FPM)->run(*unwrap<Function>(F));
+}
+
+int LLVMFinalizeFunctionPassManager(LLVMPassManagerRef FPM) {
+ return unwrap<FunctionPassManager>(FPM)->doFinalization();
+}
+
+void LLVMDisposePassManager(LLVMPassManagerRef PM) {
+ delete unwrap(PM);
+}
diff --git a/test/Bindings/Ocaml/vmcore.ml b/test/Bindings/Ocaml/vmcore.ml
index cfa22d5..696157e 100644
--- a/test/Bindings/Ocaml/vmcore.ml
+++ b/test/Bindings/Ocaml/vmcore.ml
@@ -34,6 +34,7 @@ let suite name f =
let filename = Sys.argv.(1)
let m = create_module filename
+let mp = ModuleProvider.create m
(*===-- Target ------------------------------------------------------------===*)
@@ -836,6 +837,30 @@ let test_module_provider () =
ModuleProvider.dispose mp
+(*===-- Pass Managers -----------------------------------------------------===*)
+
+let test_pass_manager () =
+ let (++) x f = ignore (f x); x in
+
+ begin group "module pass manager";
+ ignore (PassManager.create ()
+ ++ PassManager.run_module m
+ ++ PassManager.dispose)
+ end;
+
+ begin group "function pass manager";
+ let fty = function_type void_type [| |] in
+ let fn = define_function "FunctionPassManager" fty m in
+ ignore (build_ret_void (builder_at_end (entry_block fn)));
+
+ ignore (PassManager.create_function mp
+ ++ PassManager.initialize
+ ++ PassManager.run_function fn
+ ++ PassManager.finalize
+ ++ PassManager.dispose)
+ end
+
+
(*===-- Writer ------------------------------------------------------------===*)
let test_writer () =
@@ -847,7 +872,7 @@ let test_writer () =
group "writer";
insist (write_bitcode_file m filename);
- dispose_module m
+ ModuleProvider.dispose mp
(*===-- Driver ------------------------------------------------------------===*)
@@ -862,5 +887,6 @@ let _ =
suite "basic blocks" test_basic_blocks;
suite "builder" test_builder;
suite "module provider" test_module_provider;
- suite "writer" test_writer;
+ suite "pass manager" test_pass_manager;
+ suite "writer" test_writer; (* Keep this last; it disposes m. *)
exit !exit_status