How to get LLVM IR of a function

I’d like to get the LLVM IR representation of a function just before Numba compiles that function to machine code. I want to play around with this representation, possibly editing it before finishing the compilation and executing the result.

I found a way of getting an llvm representation on stackoverflow was using the inspect_llvm method. I tried this, but inspect_llvm returns a string version of this representation which I then have to use to create an numba.llvmlite.Module type, however that Module lists no functions inside, so clearly I’ve done something wrong, or something has gone wrong here. Here’s what I did:

# Define function and jit it
@nb.jit
def func_1(x):
    return x**2

# Call with argument to trigger compile
func_1(1.)

# Get llvm string
llvm_str = func_1.inspect_llvm()[(nb.types.float64,)]

print(llvm_str)

# Build llvmlite Module
func_1_llvm_mod = nb.llvmlite.ir.Module(llvm_str)

print(func_1_llvm_mod.functions)

The second print statement just yields [].

What is the right way to get this representation right now? Or have I misunderstood something? Currently I’m using numba 0.56.4

It is a bit more involved than that. What you have done here:
func_1_llvm_mod = nb.llvmlite.ir.Module(llvm_str) is to create an empty module with the string you passed in as the argument as the name of the module.

To convert the string to an LLVM module use the llvlite.binding.module.parse_assembly function.

For reference look at what Numba’s CPUCodegen does: numba/codegen.py at 0830ee85cc8f7b5932afcd5d90591e9de4800e49 · numba/numba · GitHub

That worked! Thanks a lot!