# HG changeset patch # User Max Brister # Date 1347624581 21600 # Node ID 8ccb187b24e971d246cbc939264ec9626e8640b1 # Parent d8d7596fc68d559871d70c7adf643c953d44d94a Erase partially created functions on JIT compilation failure (bug #37308) * pt-jit.cc (tree_jit::optimize): Verify module in debug mode. (jit_function_info::jit_function_info): Erase functions on failure. diff --git a/libinterp/interp-core/jit-typeinfo.cc b/libinterp/interp-core/jit-typeinfo.cc --- a/libinterp/interp-core/jit-typeinfo.cc +++ b/libinterp/interp-core/jit-typeinfo.cc @@ -586,6 +586,16 @@ args (fn.args), call_conv (fn.call_conv), mcan_error (fn.mcan_error) {} +void +jit_function::erase (void) +{ + if (! llvm_function) + return; + + llvm_function->eraseFromParent (); + llvm_function = 0; +} + std::string jit_function::name (void) const { diff --git a/libinterp/interp-core/jit-typeinfo.h b/libinterp/interp-core/jit-typeinfo.h --- a/libinterp/interp-core/jit-typeinfo.h +++ b/libinterp/interp-core/jit-typeinfo.h @@ -236,6 +236,9 @@ jit_function (const jit_function& fn); + // erase the interal LLVM function (if it exists). Will become invalid. + void erase (void); + template void add_mapping (llvm::ExecutionEngine *engine, T fn) { diff --git a/libinterp/interp-core/pt-jit.cc b/libinterp/interp-core/pt-jit.cc --- a/libinterp/interp-core/pt-jit.cc +++ b/libinterp/interp-core/pt-jit.cc @@ -1865,6 +1865,9 @@ void tree_jit::optimize (llvm::Function *fn) { + if (Venable_jit_debug) + llvm::verifyModule (*module); + module_pass_manager->run (*module); pass_manager->run (*fn); @@ -1887,6 +1890,9 @@ for (size_t i = 0; i < nargs; ++i) argument_types[i] = jit_typeinfo::type_of (ov_args(i)); + jit_function raw_fn; + jit_function wrapper; + try { jit_convert conv (fcn, argument_types); @@ -1912,10 +1918,9 @@ jit_factory& factory = conv.get_factory (); llvm::Module *module = tjit.get_module (); jit_convert_llvm to_llvm; - jit_function raw_fn = to_llvm.convert_function (module, - infer.get_blocks (), - factory.constants (), - fcn, argument_types); + raw_fn = to_llvm.convert_function (module, infer.get_blocks (), + factory.constants (), fcn, + argument_types); if (Venable_jit_debug) { @@ -1928,8 +1933,9 @@ std::string wrapper_name = fcn.name () + "_wrapper"; jit_type *any_t = jit_typeinfo::get_any (); std::vector wrapper_args (1, jit_typeinfo::get_any_ptr ()); - jit_function wrapper (module, jit_convention::internal, wrapper_name, - any_t, wrapper_args); + wrapper = jit_function (module, jit_convention::internal, wrapper_name, + any_t, wrapper_args); + llvm::BasicBlock *wrapper_body = wrapper.new_block (); builder.SetInsertPoint (wrapper_body); @@ -1985,6 +1991,9 @@ if (e.known ()) std::cout << "jit fail: " << e.what () << std::endl; } + + wrapper.erase (); + raw_fn.erase (); } }