diff --git a/llvm/_core.cpp b/llvm/_core.cpp index fd28f01..d6e781f 100644 --- a/llvm/_core.cpp +++ b/llvm/_core.cpp @@ -1431,7 +1431,7 @@ _wLLVMParseEnvOpts(PyObject *self, PyObject *args) Py_RETURN_NONE; } -//_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) +_wrap_obj2obj(LLVMInlineFunction, LLVMValueRef, int) /* Expose the void* inside a PyCObject as a PyLong. This allows us to * use it as a unique ID. */ @@ -2038,7 +2038,7 @@ static PyMethodDef core_methods[] = { _method( LLVMLoadLibraryPermanently ) _method( LLVMParseEnvOpts ) - //_method( LLVMInlineFunction ) + _method( LLVMInlineFunction ) _method( PyCObjectVoidPtrToPyLong ) { NULL } }; diff --git a/llvm/core.py b/llvm/core.py index dc31e58..efcc672 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -2157,7 +2157,7 @@ def load_library_permanently(filename): def inline_function(call): check_is_value(call) - return _core.LLVMInlineFunction(call.ptr) + return bool(_core.LLVMInlineFunction(call.ptr)) def parse_environment_options(progname, envname): _core.LLVMParseEnvOpts(progname, envname) diff --git a/llvm/extra.cpp b/llvm/extra.cpp index 3615fca..e79755b 100644 --- a/llvm/extra.cpp +++ b/llvm/extra.cpp @@ -1032,16 +1032,15 @@ int LLVMInlineFunction(LLVMValueRef call) llvm::Value *callp = llvm::unwrap(call); assert(callp); -// llvm::CallSite cs = llvm::CallSite::get(callp); - llvm::CallSite cs; + llvm::InlineFunctionInfo unused; + llvm::Instruction *II = llvm::dyn_cast(callp); if (II->getOpcode() == llvm::Instruction::Call) - cs = llvm::CallSite(static_cast(II)); + return llvm::InlineFunction(static_cast(II), unused); else if (II->getOpcode() == llvm::Instruction::Invoke) - cs = llvm::CallSite(static_cast(II)); - - llvm::InlineFunctionInfo unused; - return llvm::InlineFunction(cs, unused); + return llvm::InlineFunction(static_cast(II), unused); + else + return 0; } unsigned LLVMGetParamAlignment(LLVMValueRef arg) diff --git a/llvm/extra.h b/llvm/extra.h index 339500a..b428ed5 100644 --- a/llvm/extra.h +++ b/llvm/extra.h @@ -449,8 +449,9 @@ void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn); /* Wraps llvm::InlineFunction(). Inlines a function. C is the call * instruction, created by LLVMBuildCall. Even if it fails, the Function - * containing the call is still in a proper state (not changed). */ -//int LLVMInlineFunction(LLVMValueRef call); + * containing the call is still in a proper state (not changed). + */ +int LLVMInlineFunction(LLVMValueRef call); /* Wraps llvm::getAlignmentFromAttrs from Attributes.h. Compliments the * already available LLVMSetParamAlignment(). */ diff --git a/test/inlining.py b/test/inlining.py new file mode 100644 index 0000000..82d6932 --- /dev/null +++ b/test/inlining.py @@ -0,0 +1,32 @@ +from llvm.core import * +import unittest + +class TestInlining(unittest.TestCase): + def test_inline_call(self): + mod = Module.new(__name__) + callee = mod.add_function(Type.function(Type.int(), [Type.int()]), + name='bar') + + builder = Builder.new(callee.append_basic_block('entry')) + builder.ret(builder.add(callee.args[0], callee.args[0])) + + caller = mod.add_function(Type.function(Type.int(), []), + name='foo') + + builder = Builder.new(caller.append_basic_block('entry')) + callinst = builder.call(callee, [Constant.int(Type.int(), 1234)]) + builder.ret(callinst) + + pre_inlining = str(caller) + self.assertIn('call', pre_inlining) + + self.assertTrue(inline_function(callinst)) + + post_inlining = str(caller) + self.assertNotIn('call', post_inlining) + self.assertIn('2468', post_inlining) + + +if __name__ == '__main__': + unittest.main() +