Context: I am currently trying to port the LLVM IR generated from numba.cfunc to a pure C environment to run.
I notice that most symbols are added to LLVM symbol table through
def add_symbol(name, address):
"""
Register the *address* of global symbol *name*. This will make
it usable (e.g. callable) from LLVM-compiled functions.
"""
ffi.lib.LLVMPY_AddSymbol(_encode_string(name), c_void_p(address))
in llvmlite at llvmlite/binding/dylib.py
But I don’t see any statement like add_symbol("Py_FatalError", ...)
Question: When are things like Py_FatalError being added to the underlying LLVM?
In other words, how is it possible that jitted LLVM IR can run without Py_FatalError being explicitly added to the symbol?
Or perhaps that means there exist a way in LLVM to expose the C functions in the global namespace to the jitted LLVM IR?
I am a newbie in LLVM so hope someone can shed some light on the mechanism of this.
Probably not relevant to the question for just for context, the LLVM IR generated looks like this:
; ModuleID = 'my_cfunc'
source_filename = "<string>"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-grtev4-linux-gnu"
@_ZN08NumbaEnv8__main__8my_cfuncB2v1B52c8tJTIeFIjxB2IKSgI4CrvQClUYkACQB1EiFSRSVgFmaAA_3d_3dE8int32_2ai = common local_unnamed_addr global ptr null
@".const.Error creating Python tuple from runtime exception arguments" = internal constant [61 x i8] c"Error creating Python tuple from runtime exception arguments\00"
@".const.<numba.core.cpu.CPUContext object at 0x10d13b5a6a90>" = internal constant [53 x i8] c"<numba.core.cpu.CPUContext object at 0x10d13b5a6a90>\00"
@_ZN08NumbaEnv5numba2np8arrayobj11impl_carray12_3clocals_3e4implB2v2B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE8int32_2a8UniTupleIiLi1EE27omitted_28default_3dNone_29 = common local_unnamed_addr global ptr null
@_ZN08NumbaEnv5numba2np8arrayobj15_call_allocatorB2v7B42c8tJTC_2fWQA93W1AaAIYBPIqRBFCjDSZRVAJmaQIAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj = common local_unnamed_addr global ptr null
@_ZN08NumbaEnv5numba2np8arrayobj18_ol_array_allocate12_3clocals_3e4implB2v8B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj = common local_unnamed_addr global ptr null
@.const.pickledata.18490829436608 = internal constant [86 x i8] c"\80\04\95K\00\00\00\00\00\00\00\8C\08builtins\94\8C\0BMemoryError\94\93\94\8C'Allocation failed (probably too large).\94\85\94N\87\94."
@.const.pickledata.18490829436608.sha1 = internal constant [20 x i8] c"\BA(\9D\81\F0\\p \F3G|\15sH\04\DFe\AB\E2\09"
@.const.picklebuf.18490829436608 = internal constant { ptr, i32, ptr, ptr, i32 } { ptr @.const.pickledata.18490829436608, i32 86, ptr @.const.pickledata.18490829436608.sha1, ptr null, i32 0 }
@_ZN08NumbaEnv5numba2np8arrayobj9array_dot12_3clocals_3e8dot_implB2v3B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE = common local_unnamed_addr global ptr null
@_ZN08NumbaEnv5numba2np6linalg10dot_2_impl12_3clocals_3e12_3clambda_3eB2v4B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE = common local_unnamed_addr global ptr null
@".const.BLAS wrapper returned with an error" = internal constant [36 x i8] c"BLAS wrapper returned with an error\00"
@PyExc_RuntimeError = external global i8
@_ZN08NumbaEnv5numba2np6linalg8dot_2_vv12_3clocals_3e10check_argsB2v5B42c8tJTC_2fWQA93W1AaAIYBPIqRBFCjDSZRVAJmaQIAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE = common local_unnamed_addr global ptr null
@_ZN08NumbaEnv5numba2np6linalg11check_c_int12_3clocals_3e4implB2v6B42c8tJTC_2fWQA93W1AaAIYBPIqRBFCjDSZRVAJmaQIAEx = common local_unnamed_addr global ptr null
define range(i32 0, 2) i32 @_ZN8__main__8my_cfuncB2v1B52c8tJTIeFIjxB2IKSgI4CrvQClUYkACQB1EiFSRSVgFmaAA_3d_3dE8int32_2ai(ptr noalias writeonly captures(none) %retptr, ptr noalias writeonly captures(none) %excinfo, ptr readonly captures(none) %arg.array_ptr, i32 %arg.m) local_unnamed_addr {
B0.endif:
%.95.i.i = alloca float, align 4
%.107.i.i = alloca i32, align 4
%.12.i = sext i32 %arg.m to i64
%.70 = shl nsw i64 %.12.i, 2
%.7.i.i = tail call ptr @NRT_MemInfo_alloc_aligned(i64 %.70, i32 32), !noalias !0
%.8.i.i = icmp eq ptr %.7.i.i, null
br i1 %.8.i.i, label %B0.endif.endif.if.if, label %B0.endif.endif.endif, !prof !7
common.ret: ; preds = %for.end.endif, %B0.endif.endif.if.if
%common.ret.op = phi i32 [ 1, %B0.endif.endif.if.if ], [ 0, %for.end.endif ]
ret i32 %common.ret.op
B0.endif.endif.endif: ; preds = %B0.endif
%.5.i = getelementptr i8, ptr %.7.i.i, i64 24
%.6.i = load ptr, ptr %.5.i, align 8
%.13427 = icmp sgt i32 %arg.m, 0
br i1 %.13427, label %iter.check, label %B0.endif.endif.i.i
iter.check: ; preds = %B0.endif.endif.endif
%0 = ptrtoint ptr %arg.array_ptr to i64
%.6.i12 = ptrtoint ptr %.6.i to i64
%min.iters.check = icmp samesign ult i32 %arg.m, 4
%1 = sub i64 %.6.i12, %0
%diff.check = icmp ult i64 %1, 128
%or.cond = select i1 %min.iters.check, i1 true, i1 %diff.check
br i1 %or.cond, label %for.body.preheader, label %vector.main.loop.iter.check
for.body.preheader: ; preds = %vec.epilog.middle.block, %vec.epilog.iter.check, %iter.check
%loop.index28.ph = phi i64 [ %n.vec, %vec.epilog.iter.check ], [ 0, %iter.check ], [ %n.vec19, %vec.epilog.middle.block ]
%2 = sub nsw i64 %.12.i, %loop.index28.ph
%xtraiter = and i64 %2, 7
%lcmp.mod.not = icmp eq i64 %xtraiter, 0
br i1 %lcmp.mod.not, label %for.body.prol.loopexit, label %for.body.prol.preheader
for.body.prol.preheader: ; preds = %for.body.preheader
br label %for.body.prol
for.body.prol: ; preds = %for.body.prol.preheader, %for.body.prol
%lsr.iv = phi i64 [ %xtraiter, %for.body.prol.preheader ], [ %lsr.iv.next, %for.body.prol ]
%loop.index28.prol = phi i64 [ %.145.prol, %for.body.prol ], [ %loop.index28.ph, %for.body.prol.preheader ]
%3 = shl nuw nsw i64 %loop.index28.prol, 2
%scevgep38 = getelementptr i8, ptr %arg.array_ptr, i64 %3
%4 = shl nuw nsw i64 %loop.index28.prol, 2
%scevgep37 = getelementptr i8, ptr %.6.i, i64 %4
%.142.prol = load i32, ptr %scevgep38, align 4
%.143.prol = sitofp i32 %.142.prol to float
store float %.143.prol, ptr %scevgep37, align 4
%.145.prol = add nuw nsw i64 %loop.index28.prol, 1
%lsr.iv.next = add nsw i64 %lsr.iv, -1
%prol.iter.cmp.not = icmp eq i64 %lsr.iv.next, 0
br i1 %prol.iter.cmp.not, label %for.body.prol.loopexit, label %for.body.prol, !llvm.loop !8
for.body.prol.loopexit: ; preds = %for.body.prol, %for.body.preheader
%loop.index28.unr = phi i64 [ %loop.index28.ph, %for.body.preheader ], [ %.145.prol, %for.body.prol ]
%5 = sub nsw i64 %loop.index28.ph, %.12.i
%6 = icmp ugt i64 %5, -8
br i1 %6, label %B0.endif.endif.i.i, label %for.body.preheader5
for.body.preheader5: ; preds = %for.body.prol.loopexit
br label %for.body
vector.main.loop.iter.check: ; preds = %iter.check
%min.iters.check14 = icmp samesign ult i32 %arg.m, 32
br i1 %min.iters.check14, label %vec.epilog.ph, label %vector.ph
vector.ph: ; preds = %vector.main.loop.iter.check
%n.vec = and i64 %.12.i, 2147483616
%7 = lshr i64 %.12.i, 5
%8 = trunc i64 %7 to i26
%9 = zext i26 %8 to i64
%10 = shl nuw nsw i64 %9, 7
br label %vector.body
vector.body: ; preds = %vector.body, %vector.ph
%lsr.iv41 = phi i64 [ %lsr.iv.next42, %vector.body ], [ 0, %vector.ph ]
%sunkaddr = getelementptr i8, ptr %arg.array_ptr, i64 %lsr.iv41
%wide.load = load <8 x i32>, ptr %sunkaddr, align 4
%sunkaddr58 = getelementptr i8, ptr %arg.array_ptr, i64 %lsr.iv41
%sunkaddr59 = getelementptr i8, ptr %sunkaddr58, i64 32
%wide.load15 = load <8 x i32>, ptr %sunkaddr59, align 4
%sunkaddr60 = getelementptr i8, ptr %arg.array_ptr, i64 %lsr.iv41
%sunkaddr61 = getelementptr i8, ptr %sunkaddr60, i64 64
%wide.load16 = load <8 x i32>, ptr %sunkaddr61, align 4
%sunkaddr62 = getelementptr i8, ptr %arg.array_ptr, i64 %lsr.iv41
%sunkaddr63 = getelementptr i8, ptr %sunkaddr62, i64 96
%wide.load17 = load <8 x i32>, ptr %sunkaddr63, align 4
%11 = sitofp <8 x i32> %wide.load to <8 x float>
%12 = sitofp <8 x i32> %wide.load15 to <8 x float>
%13 = sitofp <8 x i32> %wide.load16 to <8 x float>
%14 = sitofp <8 x i32> %wide.load17 to <8 x float>
%sunkaddr64 = getelementptr i8, ptr %.6.i, i64 %lsr.iv41
store <8 x float> %11, ptr %sunkaddr64, align 4
%sunkaddr65 = getelementptr i8, ptr %.6.i, i64 %lsr.iv41
%sunkaddr66 = getelementptr i8, ptr %sunkaddr65, i64 32
store <8 x float> %12, ptr %sunkaddr66, align 4
%sunkaddr67 = getelementptr i8, ptr %.6.i, i64 %lsr.iv41
%sunkaddr68 = getelementptr i8, ptr %sunkaddr67, i64 64
store <8 x float> %13, ptr %sunkaddr68, align 4
%sunkaddr69 = getelementptr i8, ptr %.6.i, i64 %lsr.iv41
%sunkaddr70 = getelementptr i8, ptr %sunkaddr69, i64 96
store <8 x float> %14, ptr %sunkaddr70, align 4
%lsr.iv.next42 = add nuw nsw i64 %lsr.iv41, 128
%15 = icmp eq i64 %10, %lsr.iv.next42
br i1 %15, label %middle.block, label %vector.body, !llvm.loop !10
middle.block: ; preds = %vector.body
%cmp.n = icmp eq i64 %n.vec, %.12.i
br i1 %cmp.n, label %B0.endif.endif.i.i, label %vec.epilog.iter.check
vec.epilog.iter.check: ; preds = %middle.block
%16 = and i32 %arg.m, 28
%min.epilog.iters.check = icmp eq i32 %16, 0
br i1 %min.epilog.iters.check, label %for.body.preheader, label %vec.epilog.ph
vec.epilog.ph: ; preds = %vec.epilog.iter.check, %vector.main.loop.iter.check
%vec.epilog.resume.val = phi i64 [ %n.vec, %vec.epilog.iter.check ], [ 0, %vector.main.loop.iter.check ]
%n.vec19 = and i64 %.12.i, 2147483644
br label %vec.epilog.vector.body
vec.epilog.vector.body: ; preds = %vec.epilog.vector.body, %vec.epilog.ph
%index20 = phi i64 [ %vec.epilog.resume.val, %vec.epilog.ph ], [ %index.next22, %vec.epilog.vector.body ]
%17 = shl i64 %index20, 2
%scevgep40 = getelementptr i8, ptr %arg.array_ptr, i64 %17
%18 = shl i64 %index20, 2
%scevgep39 = getelementptr i8, ptr %.6.i, i64 %18
%wide.load21 = load <4 x i32>, ptr %scevgep40, align 4
%19 = sitofp <4 x i32> %wide.load21 to <4 x float>
store <4 x float> %19, ptr %scevgep39, align 4
%index.next22 = add nuw i64 %index20, 4
%20 = icmp eq i64 %n.vec19, %index.next22
br i1 %20, label %vec.epilog.middle.block, label %vec.epilog.vector.body, !llvm.loop !13
vec.epilog.middle.block: ; preds = %vec.epilog.vector.body
%cmp.n23 = icmp eq i64 %n.vec19, %.12.i
br i1 %cmp.n23, label %B0.endif.endif.i.i, label %for.body.preheader
B0.endif.endif.if.if: ; preds = %B0.endif
store ptr @.const.picklebuf.18490829436608, ptr %excinfo, align 8
br label %common.ret
for.body: ; preds = %for.body.preheader5, %for.body
%loop.index28 = phi i64 [ %.145.7, %for.body ], [ %loop.index28.unr, %for.body.preheader5 ]
%sunkaddr71 = mul i64 %loop.index28, 4
%sunkaddr72 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr71
%.142 = load i32, ptr %sunkaddr72, align 4
%.143 = sitofp i32 %.142 to float
%sunkaddr73 = mul i64 %loop.index28, 4
%sunkaddr74 = getelementptr i8, ptr %.6.i, i64 %sunkaddr73
store float %.143, ptr %sunkaddr74, align 4
%sunkaddr75 = mul i64 %loop.index28, 4
%sunkaddr76 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr75
%sunkaddr77 = getelementptr i8, ptr %sunkaddr76, i64 4
%.142.1 = load i32, ptr %sunkaddr77, align 4
%.143.1 = sitofp i32 %.142.1 to float
%sunkaddr78 = mul i64 %loop.index28, 4
%sunkaddr79 = getelementptr i8, ptr %.6.i, i64 %sunkaddr78
%sunkaddr80 = getelementptr i8, ptr %sunkaddr79, i64 4
store float %.143.1, ptr %sunkaddr80, align 4
%sunkaddr81 = mul i64 %loop.index28, 4
%sunkaddr82 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr81
%sunkaddr83 = getelementptr i8, ptr %sunkaddr82, i64 8
%.142.2 = load i32, ptr %sunkaddr83, align 4
%.143.2 = sitofp i32 %.142.2 to float
%sunkaddr84 = mul i64 %loop.index28, 4
%sunkaddr85 = getelementptr i8, ptr %.6.i, i64 %sunkaddr84
%sunkaddr86 = getelementptr i8, ptr %sunkaddr85, i64 8
store float %.143.2, ptr %sunkaddr86, align 4
%sunkaddr87 = mul i64 %loop.index28, 4
%sunkaddr88 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr87
%sunkaddr89 = getelementptr i8, ptr %sunkaddr88, i64 12
%.142.3 = load i32, ptr %sunkaddr89, align 4
%.143.3 = sitofp i32 %.142.3 to float
%sunkaddr90 = mul i64 %loop.index28, 4
%sunkaddr91 = getelementptr i8, ptr %.6.i, i64 %sunkaddr90
%sunkaddr92 = getelementptr i8, ptr %sunkaddr91, i64 12
store float %.143.3, ptr %sunkaddr92, align 4
%sunkaddr93 = mul i64 %loop.index28, 4
%sunkaddr94 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr93
%sunkaddr95 = getelementptr i8, ptr %sunkaddr94, i64 16
%.142.4 = load i32, ptr %sunkaddr95, align 4
%.143.4 = sitofp i32 %.142.4 to float
%sunkaddr96 = mul i64 %loop.index28, 4
%sunkaddr97 = getelementptr i8, ptr %.6.i, i64 %sunkaddr96
%sunkaddr98 = getelementptr i8, ptr %sunkaddr97, i64 16
store float %.143.4, ptr %sunkaddr98, align 4
%sunkaddr99 = mul i64 %loop.index28, 4
%sunkaddr100 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr99
%sunkaddr101 = getelementptr i8, ptr %sunkaddr100, i64 20
%.142.5 = load i32, ptr %sunkaddr101, align 4
%.143.5 = sitofp i32 %.142.5 to float
%sunkaddr102 = mul i64 %loop.index28, 4
%sunkaddr103 = getelementptr i8, ptr %.6.i, i64 %sunkaddr102
%sunkaddr104 = getelementptr i8, ptr %sunkaddr103, i64 20
store float %.143.5, ptr %sunkaddr104, align 4
%sunkaddr105 = mul i64 %loop.index28, 4
%sunkaddr106 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr105
%sunkaddr107 = getelementptr i8, ptr %sunkaddr106, i64 24
%.142.6 = load i32, ptr %sunkaddr107, align 4
%.143.6 = sitofp i32 %.142.6 to float
%sunkaddr108 = mul i64 %loop.index28, 4
%sunkaddr109 = getelementptr i8, ptr %.6.i, i64 %sunkaddr108
%sunkaddr110 = getelementptr i8, ptr %sunkaddr109, i64 24
store float %.143.6, ptr %sunkaddr110, align 4
%sunkaddr111 = mul i64 %loop.index28, 4
%sunkaddr112 = getelementptr i8, ptr %arg.array_ptr, i64 %sunkaddr111
%sunkaddr113 = getelementptr i8, ptr %sunkaddr112, i64 28
%.142.7 = load i32, ptr %sunkaddr113, align 4
%.143.7 = sitofp i32 %.142.7 to float
%sunkaddr114 = mul i64 %loop.index28, 4
%sunkaddr115 = getelementptr i8, ptr %.6.i, i64 %sunkaddr114
%sunkaddr116 = getelementptr i8, ptr %sunkaddr115, i64 28
store float %.143.7, ptr %sunkaddr116, align 4
%.145.7 = add nuw nsw i64 %loop.index28, 8
%exitcond.not.7 = icmp eq i64 %.12.i, %.145.7
br i1 %exitcond.not.7, label %B0.endif.endif.i.i, label %for.body, !llvm.loop !14
B0.endif.endif.i.i: ; preds = %for.body, %vec.epilog.middle.block, %middle.block, %for.body.prol.loopexit, %B0.endif.endif.endif
tail call void @NRT_incref(ptr nonnull %.7.i.i)
tail call void @NRT_decref(ptr null)
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %.95.i.i), !noalias !15
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %.107.i.i), !noalias !15
store float 0.000000e+00, ptr %.95.i.i, align 4, !noalias !19
store i32 0, ptr %.107.i.i, align 4, !noalias !19
%.104.i.i = call i32 @numba_xxdot(i8 115, i8 0, i64 %.12.i, ptr %.6.i, ptr %.6.i, ptr nonnull %.95.i.i), !noalias !19
%.105.not.i.i = icmp eq i32 %.104.i.i, 0
br i1 %.105.not.i.i, label %for.end.endif, label %B0.endif.endif.if.i.i, !prof !23
B0.endif.endif.if.i.i: ; preds = %B0.endif.endif.i.i
call void @numba_gil_ensure(ptr nonnull %.107.i.i), !noalias !19
call void @Py_FatalError(ptr nonnull @".const.BLAS wrapper returned with an error"), !noalias !19
unreachable
for.end.endif: ; preds = %B0.endif.endif.i.i
%.112.i.i = load float, ptr %.95.i.i, align 4, !noalias !19
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %.95.i.i), !noalias !15
call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %.107.i.i), !noalias !15
tail call void @NRT_decref(ptr nonnull %.7.i.i)
tail call void @NRT_decref(ptr nonnull %.7.i.i)
%.188 = fptosi float %.112.i.i to i32
store i32 %.188, ptr %retptr, align 4
br label %common.ret
}
define i32 @cfunc._ZN8__main__8my_cfuncB2v1B52c8tJTIeFIjxB2IKSgI4CrvQClUYkACQB1EiFSRSVgFmaAA_3d_3dE8int32_2ai(ptr readonly captures(none) %.1, i32 %.2) local_unnamed_addr {
entry:
%.4 = alloca i32, align 4
store i32 0, ptr %.4, align 4
%excinfo = alloca ptr, align 8
store ptr null, ptr %excinfo, align 8
%.8 = call i32 @_ZN8__main__8my_cfuncB2v1B52c8tJTIeFIjxB2IKSgI4CrvQClUYkACQB1EiFSRSVgFmaAA_3d_3dE8int32_2ai(ptr nonnull %.4, ptr nonnull %excinfo, ptr %.1, i32 %.2) #3
%.9 = load ptr, ptr %excinfo, align 8
%.18 = load i32, ptr %.4, align 4
%.20 = alloca i32, align 4
store i32 0, ptr %.20, align 4
%cond = icmp eq i32 %.8, 0
br i1 %cond, label %common.ret, label %entry.if.if
common.ret: ; preds = %entry.if.if.if.if, %.23, %entry
%common.ret.op = phi i32 [ 0, %entry.if.if.if.if ], [ %.18, %.23 ], [ %.18, %entry ]
ret i32 %common.ret.op
.23: ; preds = %entry.if.if.endif.if, %entry.if.if.endif
%.71 = call ptr @PyUnicode_FromString(ptr nonnull @".const.<numba.core.cpu.CPUContext object at 0x10d13b5a6a90>")
call void @PyErr_WriteUnraisable(ptr %.71)
call void @Py_DecRef(ptr %.71)
call void @numba_gil_release(ptr nonnull %.20)
br label %common.ret
entry.if.if: ; preds = %entry
call void @numba_gil_ensure(ptr nonnull %.20)
call void @PyErr_Clear()
%.26 = load { ptr, i32, ptr, ptr, i32 }, ptr %.9, align 8
%.27 = extractvalue { ptr, i32, ptr, ptr, i32 } %.26, 4
%.28 = icmp sgt i32 %.27, 0
%.31 = extractvalue { ptr, i32, ptr, ptr, i32 } %.26, 0
%.33 = extractvalue { ptr, i32, ptr, ptr, i32 } %.26, 1
br i1 %.28, label %entry.if.if.if, label %entry.if.if.else
entry.if.if.if: ; preds = %entry.if.if
%.34 = sext i32 %.33 to i64
%.35 = call ptr @PyBytes_FromStringAndSize(ptr %.31, i64 %.34)
%.36 = load { ptr, i32, ptr, ptr, i32 }, ptr %.9, align 8
%.37 = extractvalue { ptr, i32, ptr, ptr, i32 } %.36, 2
%.39 = extractvalue { ptr, i32, ptr, ptr, i32 } %.36, 3
%.41 = call ptr %.39(ptr %.37)
%.42 = icmp eq ptr %.41, null
br i1 %.42, label %entry.if.if.if.if, label %entry.if.if.if.endif, !prof !7
entry.if.if.else: ; preds = %entry.if.if
%.55 = extractvalue { ptr, i32, ptr, ptr, i32 } %.26, 2
%.56 = call ptr @numba_unpickle(ptr %.31, i32 %.33, ptr %.55)
br label %entry.if.if.endif
entry.if.if.endif: ; preds = %entry.if.if.if.endif, %entry.if.if.else
%.58 = phi ptr [ %.46, %entry.if.if.if.endif ], [ %.56, %entry.if.if.else ]
%.59.not = icmp eq ptr %.58, null
br i1 %.59.not, label %.23, label %entry.if.if.endif.if, !prof !7
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")
br label %common.ret
entry.if.if.if.endif: ; preds = %entry.if.if.if
%.46 = call ptr @numba_runtime_build_excinfo_struct(ptr %.35, ptr nonnull %.41)
call void @NRT_Free(ptr nonnull %.9)
br label %entry.if.if.endif
entry.if.if.endif.if: ; preds = %entry.if.if.endif
call void @numba_do_raise(ptr nonnull %.58)
br label %.23
}
declare void @numba_gil_ensure(ptr) local_unnamed_addr
declare ptr @PyUnicode_FromString(ptr) local_unnamed_addr
declare void @PyErr_WriteUnraisable(ptr) local_unnamed_addr
declare void @Py_DecRef(ptr) local_unnamed_addr
declare void @numba_gil_release(ptr) local_unnamed_addr
declare void @PyErr_Clear() local_unnamed_addr
declare ptr @PyBytes_FromStringAndSize(ptr, i64) local_unnamed_addr
declare ptr @numba_unpickle(ptr, i32, ptr) local_unnamed_addr
declare void @PyErr_SetString(ptr, ptr) local_unnamed_addr
declare ptr @numba_runtime_build_excinfo_struct(ptr, ptr) local_unnamed_addr
declare void @NRT_Free(ptr) local_unnamed_addr
declare void @numba_do_raise(ptr) local_unnamed_addr
declare noalias ptr @NRT_MemInfo_alloc_aligned(i64, i32) local_unnamed_addr
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0
declare i32 @numba_xxdot(i8, i8, i64, ptr, ptr, ptr) local_unnamed_addr
; Function Attrs: noreturn
declare void @Py_FatalError(ptr) local_unnamed_addr #1
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
declare void @llvm.lifetime.end.p0(i64 immarg, ptr captures(none)) #0
; Function Attrs: mustprogress nofree noinline norecurse nounwind willreturn memory(argmem: readwrite)
define linkonce_odr void @NRT_incref(ptr %.1) local_unnamed_addr #2 {
.3:
%.4 = icmp eq ptr %.1, null
br i1 %.4, label %common.ret, label %.3.endif, !prof !7
common.ret: ; preds = %.3.endif, %.3
ret void
.3.endif: ; preds = %.3
%.4.i = atomicrmw add ptr %.1, i64 1 monotonic, align 8
br label %common.ret
}
; Function Attrs: noinline
define linkonce_odr void @NRT_decref(ptr %.1) local_unnamed_addr #3 {
.3:
%.4 = icmp eq ptr %.1, null
br i1 %.4, label %common.ret1, label %.3.endif, !prof !7
common.ret1: ; preds = %.3.endif, %.3
ret void
.3.endif: ; preds = %.3
fence release
%0 = tail call i8 @llvm.x86.atomic.sub.cc.i64(ptr nonnull %.1, i64 1, i32 4)
%1 = trunc i8 %0 to i1
br i1 %1, label %.3.endif.if, label %common.ret1, !prof !7
.3.endif.if: ; preds = %.3.endif
fence acquire
tail call void @NRT_MemInfo_call_dtor(ptr nonnull %.1)
ret void
}
; Function Attrs: nounwind
declare i8 @llvm.x86.atomic.sub.cc.i64(ptr, i64, i32 immarg) #4
declare void @NRT_MemInfo_call_dtor(ptr) local_unnamed_addr
attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
attributes #1 = { noreturn }
attributes #2 = { mustprogress nofree noinline norecurse nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { noinline }
attributes #4 = { nounwind }
!0 = !{!1, !3, !4, !6}
!1 = distinct !{!1, !2, !"_ZN5numba2np8arrayobj18_ol_array_allocate12_3clocals_3e4implB2v8B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj: %retptr"}
!2 = distinct !{!2, !"_ZN5numba2np8arrayobj18_ol_array_allocate12_3clocals_3e4implB2v8B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj"}
!3 = distinct !{!3, !2, !"_ZN5numba2np8arrayobj18_ol_array_allocate12_3clocals_3e4implB2v8B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj: %excinfo"}
!4 = distinct !{!4, !5, !"_ZN5numba2np8arrayobj15_call_allocatorB2v7B42c8tJTC_2fWQA93W1AaAIYBPIqRBFCjDSZRVAJmaQIAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj: %retptr"}
!5 = distinct !{!5, !"_ZN5numba2np8arrayobj15_call_allocatorB2v7B42c8tJTC_2fWQA93W1AaAIYBPIqRBFCjDSZRVAJmaQIAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj"}
!6 = distinct !{!6, !5, !"_ZN5numba2np8arrayobj15_call_allocatorB2v7B42c8tJTC_2fWQA93W1AaAIYBPIqRBFCjDSZRVAJmaQIAEN29typeref_5b_3cclass_20_27numba4core5types8npytypes14Array_27_3e_5dExj: %excinfo"}
!7 = !{!"branch_weights", i32 1, i32 99}
!8 = distinct !{!8, !9}
!9 = !{!"llvm.loop.unroll.disable"}
!10 = distinct !{!10, !11, !12}
!11 = !{!"llvm.loop.isvectorized", i32 1}
!12 = !{!"llvm.loop.unroll.runtime.disable"}
!13 = distinct !{!13, !11, !12}
!14 = distinct !{!14, !11}
!15 = !{!16, !18}
!16 = distinct !{!16, !17, !"_ZN5numba2np8arrayobj9array_dot12_3clocals_3e8dot_implB2v3B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE: %retptr"}
!17 = distinct !{!17, !"_ZN5numba2np8arrayobj9array_dot12_3clocals_3e8dot_implB2v3B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE"}
!18 = distinct !{!18, !17, !"_ZN5numba2np8arrayobj9array_dot12_3clocals_3e8dot_implB2v3B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE: %excinfo"}
!19 = !{!20, !22, !16, !18}
!20 = distinct !{!20, !21, !"_ZN5numba2np6linalg10dot_2_impl12_3clocals_3e12_3clambda_3eB2v4B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE: %retptr"}
!21 = distinct !{!21, !"_ZN5numba2np6linalg10dot_2_impl12_3clocals_3e12_3clambda_3eB2v4B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE"}
!22 = distinct !{!22, !21, !"_ZN5numba2np6linalg10dot_2_impl12_3clocals_3e12_3clambda_3eB2v4B40c8tJTIeFIjxB2IKSgI4CrvQClcaMQ5hEUQmYpQkAE5ArrayIfLi1E1C7mutable7alignedE5ArrayIfLi1E1C7mutable7alignedE: %excinfo"}
!23 = !{!"branch_weights", i32 99, i32 1}
generated from:
@nb.cfunc(
nb.types.intc(nb.types.CPointer(nb.types.intc), nb.types.intc),
nopython=True,
)
def my_cfunc(array_ptr, m):
a = nb.carray(array_ptr, (m,))
a = a.astype(np.float32)
return a.dot(a)