diff options
-rw-r--r-- | bindings/ocaml/llvm/llvm.ml | 18 | ||||
-rw-r--r-- | bindings/ocaml/llvm/llvm.mli | 54 | ||||
-rw-r--r-- | bindings/ocaml/llvm/llvm_ocaml.c | 34 | ||||
-rw-r--r-- | include/llvm-c/Core.h | 81 | ||||
-rw-r--r-- | lib/VMCore/PassManager.cpp | 31 | ||||
-rw-r--r-- | test/Bindings/Ocaml/vmcore.ml | 30 |
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 |