# What is the maximum inlining depth in practice?

**URL:** <https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929>\
**Category:** General Usage\
**Tags:** compilation, optimization, function\
**Created:** [February 24, 2021, 12:40pm UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929 "2021-02-24T12:40:18Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sloede](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sloede/32/44787_2.png) [@sloede](https://discourse.julialang.org/u/sloede)\
**Post date:** [February 24, 2021, 12:40pm UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/1 "2021-02-24T12:40:18Z")

</div>

Out of professional curiosity: What is the maximum depth for inlining function calls in Julia in practice?

My programming intuition says that there must exist a practical limit regarding how deeply nested functions may be before they are not inlined anymore. Is this a fixed (possibly configurable) number? Or does it depend on some compiler heuristics? And if yes, what are the limits in practice that people have experienced?

I am asking since Julia favors [many](https://docs.julialang.org/en/v1/manual/performance-tips/#Break-functions-into-multiple-definitions) [small](https://docs.julialang.org/en/v1/manual/performance-tips/#kernel-functions) functions and we’ve tried to do this in Trixi.jl. However, people coming from other languages (_ahem_ C++ or Fortran _ahem_) still cringe when they see it, and I’d like to back my claim that small functions make for fast code with some hard numbers during the next discussion 😉

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [February 26, 2021, 7:36am UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/2 "2021-02-26T07:36:06Z")

</div>

As mentioned on Slack, I generated 52 functions each which calls the previous, where the final step calls `sum` (which itself has a call stack 13 functions deep), and that all inlined.

So if there is a limit, it’s at least 66 layers deep - and will probably never be reached in practice.

---

<div class="post-metadata">

**Author:** ![sloede](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sloede/32/44787_2.png) [@sloede](https://discourse.julialang.org/u/sloede)\
**Post date:** [February 26, 2021, 7:41am UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/3 "2021-02-26T07:41:22Z")

</div>

Thanks for your answer! Out of curiosity: How did you generate those functions and how were you able to determine that everything is inlined?

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [February 26, 2021, 9:16am UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/4 "2021-02-26T09:16:28Z")

</div>

I deleted the code, but it was something along the lines of

```julia
@inline a(x) = sum(x)
for i in 'b':'z'
    @eval @inline $(Symbol(i))(foo) = $(Symbol(i - 1))(foo)
end

```

I also added another loop with the capital letters. It’s easy to extend this as far as you want. To determine whether it inlined, I did  
`@code_native z([1])`

---

<div class="post-metadata">

**Author:** ![sloede](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sloede/32/44787_2.png) [@sloede](https://discourse.julialang.org/u/sloede)\
**Post date:** [February 26, 2021, 10:25am UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/5 "2021-02-26T10:25:07Z")

</div>

Thanks!

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [February 26, 2021, 12:11pm UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/6 "2021-02-26T12:11:39Z")

</div>

You could use numbers to make reaching arbitrary depths easier:

```julia
julia> @inline a_0(x) = sum(x)
a_0 (generic function with 1 method)

julia> for i in 1:200
           @eval @inline $(Symbol(:a_, i))(x) = $(Symbol(:a_, i-1))(x)
       end

julia> @code_native debuginfo=:none syntax=:intel a_200((1.0,2.0))
        .text
        vmovsd xmm0, qword ptr [rdi] # xmm0 = mem[0],zero
        vaddsd xmm0, xmm0, qword ptr [rdi + 8]
        ret
        nop word ptr [rax + rax]

```

```llvm
; julia> @code_llvm debuginfo=:none a_200((1.0,2.0))
define double @julia_a_200_1697([2 x double]* nocapture nonnull readonly align 8 dereferenceable(16) %0) {
top:
  %1 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 0
  %2 = getelementptr inbounds [2 x double], [2 x double]* %0, i64 0, i64 1
  %3 = load double, double* %1, align 8
  %4 = load double, double* %2, align 8
  %5 = fadd double %3, %4
  ret double %5
}

```

In practice, you can hit non-specializing heuristics if you’re not careful.

---

<div class="post-metadata">

**Author:** ![sloede](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sloede/32/44787_2.png) [@sloede](https://discourse.julialang.org/u/sloede)\
**Post date:** [February 26, 2021, 12:21pm UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/7 "2021-02-26T12:21:40Z")

</div>

> [@Elrod](#):
>
> In practice, you can hit non-specializing heuristics if you’re not careful.

Do you mean [this warning](https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing)?

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [February 26, 2021, 12:24pm UTC](https://discourse.julialang.org/t/what-is-the-maximum-inlining-depth-in-practice/55929/8 "2021-02-26T12:24:54Z")

</div>

Yes. I believe I also hit it using pass-through singleton types, but managed to avoid it via reconstructing them in each layer.
