In numba/numba/core/funcdesc.py at f0d24824fcd6a454827e3c108882395d00befc04 · numba/numba · GitHub, it exposes C-compatible wrapper in LLVM IR.
def llvm_cfunc_wrapper_name(self):
"""
The LLVM-registered name for a C-compatible wrapper of the
raw function.
"""
return 'cfunc.' + self.mangled_name
Is there documentation on how to properly invoke the C-compatible wrapper? Like for this example,
@nb.njit
def f(a: np.array):
return a + 1
f(np.zeros((3, 3), dtype=np.float32))
What will be the signature of the C-compatible wrapper in LLVM IR in this case?
I am currently seeing the cfunc.<...> generated from the above f is like:
define { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } @cfunc._ZN8__main__1fB2v1B38c8tJTIeFIjxB2IKSgI4CrvQClQZ6FczSBAA_3dE5ArrayIdLi2E1C7mutable7alignedE({ ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %.1) local_unnamed_addr {
entry:
%.3 = alloca { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] }, align 8
%.fca.1.gep = getelementptr inbounds nuw i8, ptr %.3, i64 8
%.fca.2.gep = getelementptr inbounds nuw i8, ptr %.3, i64 16
%.fca.3.gep = getelementptr inbounds nuw i8, ptr %.3, i64 24
%.fca.4.gep = getelementptr inbounds nuw i8, ptr %.3, i64 32
%.fca.5.0.gep = getelementptr inbounds nuw i8, ptr %.3, i64 40
%.fca.5.1.gep = getelementptr inbounds nuw i8, ptr %.3, i64 48
%.fca.6.0.gep = getelementptr inbounds nuw i8, ptr %.3, i64 56
%.fca.6.1.gep = getelementptr inbounds nuw i8, ptr %.3, i64 64
%excinfo = alloca ptr, align 8
call void @llvm.memset.p0.i64(ptr noundef nonnull align 8 dereferenceable(72) %.3, i8 0, i64 72, i1 false)
store ptr null, ptr %excinfo, align 8
%extracted.meminfo = extractvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %.1, 0
%extracted.data = extractvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %.1, 4
%extracted.shape = extractvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %.1, 5
%.7 = extractvalue [2 x i64] %extracted.shape, 0
%.8 = extractvalue [2 x i64] %extracted.shape, 1
%.11 = call i32 @_ZN8__main__1fB2v1B38c8tJTIeFIjxB2IKSgI4CrvQClQZ6FczSBAA_3dE5ArrayIdLi2E1C7mutable7alignedE(ptr nonnull %.3, ptr nonnull %excinfo, ptr %extracted.meminfo, ptr poison, i64 poison, i64 poison, ptr %extracted.data, i64 %.7, i64 %.8, i64 poison, i64 poison) #3
%.12 = load ptr, ptr %excinfo, align 8
%.21.fca.0.load = load ptr, ptr %.3, align 8
%.21.fca.1.load = load ptr, ptr %.fca.1.gep, align 8
%.21.fca.2.load = load i64, ptr %.fca.2.gep, align 8
%.21.fca.3.load = load i64, ptr %.fca.3.gep, align 8
%.21.fca.4.load = load ptr, ptr %.fca.4.gep, align 8
%.21.fca.5.0.load = load i64, ptr %.fca.5.0.gep, align 8
%.21.fca.5.1.load = load i64, ptr %.fca.5.1.gep, align 8
%.21.fca.6.0.load = load i64, ptr %.fca.6.0.gep, align 8
%.21.fca.6.1.load = load i64, ptr %.fca.6.1.gep, align 8
%inserted.meminfo = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } undef, ptr %.21.fca.0.load, 0
%inserted.parent = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %inserted.meminfo, ptr %.21.fca.1.load, 1
%inserted.nitems = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %inserted.parent, i64 %.21.fca.2.load, 2
%inserted.itemsize = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %inserted.nitems, i64 %.21.fca.3.load, 3
%inserted.data = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %inserted.itemsize, ptr %.21.fca.4.load, 4
%.30 = insertvalue [2 x i64] undef, i64 %.21.fca.5.0.load, 0
%.32 = insertvalue [2 x i64] %.30, i64 %.21.fca.5.1.load, 1
%inserted.shape = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %inserted.data, [2 x i64] %.32, 5
%.34 = insertvalue [2 x i64] undef, i64 %.21.fca.6.0.load, 0
%.36 = insertvalue [2 x i64] %.34, i64 %.21.fca.6.1.load, 1
%inserted.strides = insertvalue { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %inserted.shape, [2 x i64] %.36, 6
%.38 = alloca i32, align 4
store i32 0, ptr %.38, align 4
%cond = icmp eq i32 %.11, 0
br i1 %cond, label %common.ret, label %entry.if.if
common.ret: ; preds = %entry, %entry.if.if.if.if, %.41
%common.ret.op = phi { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } [ zeroinitializer, %entry.if.if.if.if ], [ %inserted.strides, %.41 ], [ %inserted.strides, %entry ]
ret { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %common.ret.op
.41: ; preds = %entry.if.if.endif.if, %entry.if.if.endif
%.89 = call ptr @PyUnicode_FromString(ptr nonnull @".const.<numba.core.cpu.CPUContext object at 0x53af7c21d190>")
call void @PyErr_WriteUnraisable(ptr %.89)
call void @Py_DecRef(ptr %.89)
call void @numba_gil_release(ptr nonnull %.38)
br label %common.ret
entry.if.if: ; preds = %entry
call void @numba_gil_ensure(ptr nonnull %.38)
call void @PyErr_Clear()
%.44 = load { ptr, i32, ptr, ptr, i32 }, ptr %.12, align 8
%.45 = extractvalue { ptr, i32, ptr, ptr, i32 } %.44, 4
%.46 = icmp sgt i32 %.45, 0
%.49 = extractvalue { ptr, i32, ptr, ptr, i32 } %.44, 0
%.51 = extractvalue { ptr, i32, ptr, ptr, i32 } %.44, 1
br i1 %.46, label %entry.if.if.if, label %entry.if.if.else
entry.if.if.if: ; preds = %entry.if.if
%.52 = sext i32 %.51 to i64
%.53 = call ptr @PyBytes_FromStringAndSize(ptr %.49, i64 %.52)
%.54 = load { ptr, i32, ptr, ptr, i32 }, ptr %.12, align 8
%.55 = extractvalue { ptr, i32, ptr, ptr, i32 } %.54, 2
%.57 = extractvalue { ptr, i32, ptr, ptr, i32 } %.54, 3
%.59 = call ptr %.57(ptr %.55)
%.60 = icmp eq ptr %.59, null
br i1 %.60, label %entry.if.if.if.if, label %entry.if.if.if.endif, !prof !0
entry.if.if.else: ; preds = %entry.if.if
%.73 = extractvalue { ptr, i32, ptr, ptr, i32 } %.44, 2
%.74 = call ptr @numba_unpickle(ptr %.49, i32 %.51, ptr %.73)
br label %entry.if.if.endif
entry.if.if.endif: ; preds = %entry.if.if.if.endif, %entry.if.if.else
%.76 = phi ptr [ %.64, %entry.if.if.if.endif ], [ %.74, %entry.if.if.else ]
%.77.not = icmp eq ptr %.76, null
br i1 %.77.not, label %.41, label %entry.if.if.endif.if, !prof !0
entry.if.if.if.if: ; preds = %entry.if.if.if
call void @PyErr_SetString(ptr nonnull @PyExc_RuntimeError, ptr nonnull @".const.Error creating Python tuple from runtime exception arguments.1")
br label %common.ret
entry.if.if.if.endif: ; preds = %entry.if.if.if
%.64 = call ptr @numba_runtime_build_excinfo_struct(ptr %.53, ptr nonnull %.59)
call void @NRT_Free(ptr nonnull %.12)
br label %entry.if.if.endif
entry.if.if.endif.if: ; preds = %entry.if.if.endif
call void @numba_do_raise(ptr nonnull %.76)
br label %.41
}
How does { ptr, ptr, i64, i64, ptr, [2 x i64], [2 x i64] } %.1 translate into C function signature?
Full LLVM IR generated: LLVM IR - JustPaste.it