# @code\_typed for ccall

**URL:** <https://discourse.julialang.org/t/code-typed-for-ccall/24487>\
**Category:** General Usage\
**Tags:** ccall\
**Created:** [May 22, 2019, 4:35pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487 "2019-05-22T16:35:32Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![vitreo12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitreo12/32/4028_2.png) [@vitreo12](https://discourse.julialang.org/u/vitreo12)\
**Post date:** [May 22, 2019, 4:35pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/1 "2019-05-22T16:35:32Z")

</div>

Hello everyone,  
I was wondering if there was a way of checking what happens on Julia side when executing a `ccall` function. Consider the following code:

```julia
@code_typed ccall(("expm1", Base.Math.libm), Float64, (Float64,), 1.5)

```

This would give an error:

```julia
ERROR: UndefVarError: ccall not defined

```

Even if wrapping the `ccall` in a `function`, I don’t get many informations out:

```julia
function my_func()
       return ccall(("expm1", Base.Math.libm), Float64, (Float64,), 1.5)
end

@code_typed my_func()

```

```julia
CodeInfo(
2 1 ─ %1 = $(Expr(:foreigncall, :((Core.tuple)("expm1", Base.Math.libm)), Float64, svec(Float64), :(:ccall), 1, 1.5, 1.5))::Float64 │
  └── return %1 │
) => Float64

```

Digging through the source code, I could not find where an `Expr(:foreigncall, ...)` actually turns into Julia functions. I would like to find these, and precompile them for some calls into C libraries that I need, without having to execute `ccall` once per C function to compile all the Julia stuff, considering that all the C side is already compiled.

I hope it makes sense.  
Thank you

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [May 22, 2019, 4:46pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/2 "2019-05-22T16:46:52Z")

</div>

> [@vitreo12](#):
>
> I was wondering if there was a way of checking what happens on Julia side when executing a `ccall` function. Consider the following code:

What exactly do you want to know and at what level?

> [@vitreo12](#):
>
> I don’t get many informations out:

What information are you looking for? You should expect all the julia side conversion although since this is a really simple one there isn’t much to see there. The actually call is just a call, you don’t see more at this level for the same reason you don’t write much more complicated code when calling a C function in C.

> [@vitreo12](#):
>
> I could not find where an `Expr(:foreigncall, ...)` actually turns into Julia functions.

It never does.

> [@vitreo12](#):
>
> I would like to find these, and precompile them for some calls into C libraries that I need, without having to execute `ccall` once per C function to compile all the Julia stuff, considering that all the C side is already compiled.

It’s unclear what you mean by this. `ccall` is compiled, there’s nothing about “execute `ccall`” or “compilie all the julia stuff”. In another word, you’ve seen all the “julia stuff” and the reason you didn’t see any is because there isn’t any, not because they are hidden.

---

<div class="post-metadata">

**Author:** ![vitreo12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitreo12/32/4028_2.png) [@vitreo12](https://discourse.julialang.org/u/vitreo12)\
**Post date:** [May 22, 2019, 5:02pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/3 "2019-05-22T17:02:18Z")

</div>

> [@yuyichao](#):
>
> It’s unclear what you mean by this. `ccall` is compiled, there’s nothing about "execute `ccall` " or “compilie all the julia stuff”. In another word, you’ve seen all the “julia stuff” and the reason you didn’t see any is because there isn’t any, not because they are hidden.

I didn’t mean they were hidden, just that I was not finding them, if there were any. Consider calling `@time ccall(("expm1", Base.Math.libm), Float64, (Float64,), 1.5)` two times:

```julia
@time a = 1.0 #Just to compile all @time related stuff

@time ccall(("expm1", Base.Math.libm), Float64, (Float64,), 1.5)

@time ccall(("expm1", Base.Math.libm), Float64, (Float64,), 1.5)

```

On my machine, the first time the `ccall` is executed, the result is:

```julia
0.000010 seconds

```

The second time, the result is:

```julia
0.000001 seconds

```

All successive calls are as fast as the second one. This is why I was assuming there was some Julia compilation that was happening.

I found the problem when trying to `precompile(tanh, (Float64,))`. By analyzing the `@code_typed` of the `tanh(Float64)` function, I found that only two calls to external functions are made. These are to  
`$(Expr(:foreigncall, :((Core.tuple)("expm1", Base.Math.libm)), Float64, svec(Float64), :(:ccall), 1, :(%31), :(%31)))::Float64 `  
and  
`$(Expr(:foreigncall, "llvm.pow.f64", Float64, svec(Float64, Float64), :(:llvmcall), 2, 2.0, -28.0, -28.0, 2.0))::Float64`.  
If running `@time tanh(1.5)`, however, the first call is always much slower than the successive ones, despite the function being compiled (in fact, the same number of allocations are performed).

```julia
precompile(tanh, (Float64,))

@time tanh(1.5) #Result is 0.000036 seconds (5 allocations: 176 bytes)

@time tanh(1.5) #Result is 0.000004 seconds (5 allocations: 176 bytes)

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [May 22, 2019, 5:12pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/4 "2019-05-22T17:12:21Z")

</div>

> [@vitreo12](#):
>
> On my machine, the first time the `ccall` is executed, the result is:
> 
> ```julia
> 0.000010 seconds
> 
> ```
> 
> The second time, the result is:
> 
> ```julia
> 0.000001 seconds
> 
> ```

None of those numbers are trustworthy. And the absense of allocation clearly shows that there is no compilation. Same for,

> [@vitreo12](#):
>
> ```julia
> precompile(tanh, (Float64,))
> 
> @time tanh(1.5) #Result is 0.000036 seconds (5 allocations: 176 bytes)
> 
> @time tanh(1.5) #Result is 0.000004 seconds (5 allocations: 176 bytes)
> 
> ```

In any case, I don’t see your logic here. You should realize that. What you are suspecting is compilation not being complete. You should realize that if you suspect it is a compilation issue, there will be no way to avoid it unless you completely avoid the julia compiler. In another word, if it is the compilation you are worried about, you should not write julia code or look for any julia stuff, you should just write the code in C or assembly or any other language that does pass through the julia compiler.

A few more points,

Your `@time ccall` does not show anything about compilation after running since the two line are compiled completely independently.

Also, in most C program, the first call of a function is also slower.

---

<div class="post-metadata">

**Author:** ![vitreo12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vitreo12/32/4028_2.png) [@vitreo12](https://discourse.julialang.org/u/vitreo12)\
**Post date:** [May 22, 2019, 5:21pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/5 "2019-05-22T17:21:58Z")

</div>

> [@yuyichao](#):
>
> And the absense of allocation clearly shows that there is no compilation. Same for,

Good to know that. I was only wondering if I was running in some compilation slowdown. I am happy to know that it wasn’t the case.

> [@yuyichao](#):
>
> In any case, I don’t see your logic here. You should realize that. What you are suspecting is compilation not being complete. You should realize that if you suspect it is a compilation issue, there will be no way to avoid it unless you completely avoid the julia compiler. In another word, if it is the compilation you are worried about, you should not write julia code or look for any julia stuff, you should just write the code in C or assembly or any other language that does pass through the julia compiler.

I am not trying to avoid the Julia compiler. I just tried to submit a minimal working example for something that I am working on that relies heavily on Julia’s features.

> [@yuyichao](#):
>
> Also, in most C program, the first call of a function is also slower.

Would you say, then, that this could be the reason why the first call is slower than successive ones? Or could there be other non-compiler related reasons?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [May 22, 2019, 5:29pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/6 "2019-05-22T17:29:27Z")

</div>

> [@vitreo12](#):
>
> Would you say, then, that this could be the reason why the first call is slower than successive ones? Or could there be other non-compiler related reasons

Hard to say, and that number is not trust worthy to this precision anyway.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [May 22, 2019, 8:55pm UTC](https://discourse.julialang.org/t/code-typed-for-ccall/24487/7 "2019-05-22T20:55:17Z")

</div>

As @yuyichao says, the `foreigncall` expression is as low-level as it gets on the Julia side. But just to give you a bit of information about what happens next: from there, [codegen takes over](https://github.com/JuliaLang/julia/blob/bc82b7f98ade59969adc04003b074f38db3cba8d/src/codegen.cpp#L4034-L4036) and [emits LLVM IR](https://github.com/JuliaLang/julia/blob/bc82b7f98ade59969adc04003b074f38db3cba8d/src/ccall.cpp#L1381-L1752) for that expression.
