# Minimal self-containing example of code transformation using generated functions?

**URL:** <https://discourse.julialang.org/t/minimal-self-containing-example-of-code-transformation-using-generated-functions/88535>\
**Category:** Internals & Design\
**Tags:** runtimegeneratedfunc\
**Created:** [October 10, 2022, 9:15pm UTC](https://discourse.julialang.org/t/minimal-self-containing-example-of-code-transformation-using-generated-functions/88535 "2022-10-10T21:15:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [October 10, 2022, 9:15pm UTC](https://discourse.julialang.org/t/minimal-self-containing-example-of-code-transformation-using-generated-functions/88535/1 "2022-10-10T21:15:09Z")

</div>

Cassette, IRTools, Diffractor and others use generated functions to transform a method’s `CodeInfo` / `IRCode`. Although I used these tools dozen times, I never managed to understand or reproduce it. Is there a minimal self-containing example of such a transformation?

* * *

For the context, I’m currently fighting extremely slow tracing of deeply nested function calls using [Umlaut](https://github.com/dfdx/Umlaut.jl). Umlaut uses [CompilerPluginTools](https://github.com/JuliaCompilerPlugins/CompilerPluginTools.jl) to extract `IRCode` and execute it instruction by instruction, but this way most time is spent in abstract interpreter / type inference. I _guess_ messing up with `@generared` functions directly may give me more control. If not, I hope to at least learn something new about Julia internals 🙂

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [October 10, 2022, 10:13pm UTC](https://discourse.julialang.org/t/minimal-self-containing-example-of-code-transformation-using-generated-functions/88535/2 "2022-10-10T22:13:26Z")

</div>

As always, writing down a question brings a lot of new ideas. Such as watching the Jarrett’s talk on Cassette design, especially [this moment](https://youtu.be/lyX-isPDS2M?t=1712) where he explains that generated functions can return either an expressions, or `CodeInfo` instance. So I tried this:

```julia
@generated function transform(f, args...)
    ci = @code_lowered f(args...)
    return ci
end

inc(x) = x + 1
transform(inc, 2.0)

```

which didn’t work and just returned an empty `Core.CodeInfo[]`. The problem of course was that generated functions work not on values, but on types, so `f, args` are actually `(typeof(inc), (Float64,))`. Thus we need a slightly different way of getting the `CodeInfo`:

```julia
@generated function transform(f, args...)
    ci = code_lowered(f.instance, args)[1]
    return ci
end

transform(inc, 2.0)

```

This version fails with segfault, but in this case it’s a good thing - it means that Julia accepted the new `CodeInfo` instance, just couldn’t validate it. I know that generating a valid instance of CI can be done using tools from the [JuliaCompilerPlugins](https://github.com/JuliaCompilerPlugins) org, but if somebody wants to jump in with a quick example, you are welcome!

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [October 25, 2022, 4:58am UTC](https://discourse.julialang.org/t/minimal-self-containing-example-of-code-transformation-using-generated-functions/88535/3 "2022-10-25T04:58:29Z")

</div>

Unfortunately I’m not aware of any remotely accessible and self-contained example in the wild for this, but here are some possible leads. [Does overdubbing in generated function inserts inlined code - #7 by Tomas\_Pevny](https://discourse.julialang.org/t/does-overdubbing-in-generated-function-inserts-inlined-code/71868/7) has a self-contained snippet, but didn’t seem to work? [Cassette’s docs](https://julia.mit.edu/Cassette.jl/latest/overdub.html) shows how to create a valid CodeInfo output using its API but doesn’t go into details. The underlying code may thus be worth a read. Lastly, the genfuncs in [Zygote’s compiler](https://github.com/FluxML/Zygote.jl/blob/master/src/compiler/interface2.jl#L9-L59) show most of the steps required for ingesting a CodeInfo for a function argument and manipulating it to be compatible with the generated function signature, but you’ll have to read through some IRTools methods to know exactly what it’s doing under the hood and a lot of the AD-related stuff may be a distraction.

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [October 25, 2022, 4:39pm UTC](https://discourse.julialang.org/t/minimal-self-containing-example-of-code-transformation-using-generated-functions/88535/4 "2022-10-25T16:39:12Z")

</div>

I do not know, if it helps, but my understanding of machinery is written here [Scientific-Programming-in-Julia/lecture.md at master · JuliaTeachingCTU/Scientific-Programming-in-Julia · GitHub](https://github.com/JuliaTeachingCTU/Scientific-Programming-in-Julia/blob/master/docs/src/lecture_09/lecture.md)

With some examples in the directory, but not sure, if it helps. I might improve it in next weeks, as my teaching of that subject is approaching. Bug reports and suggestions for improvement is welcomed.
