diff --git a/src/comp/lib/llvm.rs b/src/comp/lib/llvm.rs index 6063c3c653f..c5236725d6d 100644 --- a/src/comp/lib/llvm.rs +++ b/src/comp/lib/llvm.rs @@ -687,6 +687,16 @@ native mod llvm = llvm_lib { fn LLVMPreferredAlignmentOfType(TargetDataRef TD, TypeRef Ty) -> uint; /** Disposes target data. */ fn LLVMDisposeTargetData(TargetDataRef TD); + + /** Creates a pass manager. */ + fn LLVMCreatePassManager() -> PassManagerRef; + /** Disposes a pass manager. */ + fn LLVMDisposePassManager(PassManagerRef PM); + /** Runs a pass manager on a module. */ + fn LLVMRunPassManager(PassManagerRef PM, ModuleRef M) -> Bool; + + /** Adds a verification pass. */ + fn LLVMAddVerifierPass(PassManagerRef PM); } /* Slightly more terse object-interface to LLVM's 'builder' functions. */ @@ -1209,6 +1219,19 @@ fn mk_target_data(str string_rep) -> target_data { ret rec(lltd=lltd, dtor=target_data_dtor(lltd)); } +/* Memory-managed interface to pass managers. */ + +obj pass_manager_dtor(PassManagerRef PM) { + drop { llvm.LLVMDisposePassManager(PM); } +} + +type pass_manager = rec(PassManagerRef llpm, pass_manager_dtor dtor); + +fn mk_pass_manager() -> pass_manager { + auto llpm = llvm.LLVMCreatePassManager(); + ret rec(llpm=llpm, dtor=pass_manager_dtor(llpm)); +} + // // Local Variables: diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 9b6450cb9b8..6f3705e86d0 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -23,8 +23,9 @@ import lib.llvm.llvm; import lib.llvm.builder; import lib.llvm.target_data; import lib.llvm.type_handle; -import lib.llvm.mk_type_handle; +import lib.llvm.mk_pass_manager; import lib.llvm.mk_target_data; +import lib.llvm.mk_type_handle; import lib.llvm.llvm.ModuleRef; import lib.llvm.llvm.ValueRef; import lib.llvm.llvm.TypeRef; @@ -2245,6 +2246,14 @@ fn declare_intrinsics(ModuleRef llmod) -> hashmap[str,ValueRef] { ret intrinsics; } +fn check_module(ModuleRef llmod) { + auto pm = mk_pass_manager(); + llvm.LLVMAddVerifierPass(pm.llpm); + llvm.LLVMRunPassManager(pm.llpm, llmod); + + // TODO: run the linter here also, once there are llvm-c bindings for it. +} + fn trans_crate(session.session sess, @ast.crate crate, str output) { auto llmod = llvm.LLVMModuleCreateWithNameInContext(_str.buf("rust_out"), @@ -2302,6 +2311,8 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) { trans_exit_task_glue(cx); trans_main_fn(cx, crate_constant(cx)); + check_module(llmod); + llvm.LLVMWriteBitcodeToFile(llmod, _str.buf(output)); llvm.LLVMDisposeModule(llmod); }