# Force recompiling functions in conditional compilation

**URL:** <https://discourse.julialang.org/t/force-recompiling-functions-in-conditional-compilation/92132>\
**Category:** General Usage\
**Created:** [December 26, 2022, 8:17am UTC](https://discourse.julialang.org/t/force-recompiling-functions-in-conditional-compilation/92132 "2022-12-26T08:17:11Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [December 27, 2022, 10:43pm UTC](https://discourse.julialang.org/t/force-recompiling-functions-in-conditional-compilation/92132/2 "2022-12-27T22:43:37Z")

</div>

This thread seems to be relevant

> [@@assert alternatives?](https://discourse.julialang.org/t/assert-alternatives/24775):
>
> AFAIK there is no way yet to globally disable @assert with a compiler switch, even if doing so was already considered in the past ([here](https://github.com/JuliaLang/julia/issues/7732) and [here](https://github.com/JuliaLang/julia/issues/10614), for example). While this is not done (as I do like to believe some day someone will implement this), what is the “de facto” solution for having @assert in performance critical code? There is a package? We can redefine the behavior for a no-op in some way? Should we implement our own macro? Use ifs and a global boolean variable?

In it, you’ll find the following technique, which also forms the core of the implementation of [`ToggleableAsserts`](https://github.com/MasonProtter/ToggleableAsserts.jl). Re-writing your example, it would look like this:

```julia
julia> mode_on() = true
mode_on (generic function with 1 method)

julia> function inc!(a)
           if mode_on()
               a .+= 1
           else
               a .+= 2
           end
       end
inc! (generic function with 1 method)

```

You’ll notice that lowered code is not entirely free of branches:

```julia
julia> @code_lowered inc!([1,2,3])
CodeInfo(
1 ─ %1 = Main.mode_on()
└── goto #3 if not %1
2 ─ %3 = Base.broadcasted(Main.:+, a, 1)
│ %4 = Base.materialize!(a, %3)
└── return %4
3 ─ %6 = Base.broadcasted(Main.:+, a, 2)
│ %7 = Base.materialize!(a, %6)
└── return %7
)

```

But later stages of compilation (starting with typed code) do eliminate branches (note how the second block below is considered unreachable):

```julia
julia> @code_warntype inc!([1,2,3])
MethodInstance for inc!(::Vector{Int64})
  from inc!(a) in Main at REPL[3]:1
Arguments
  #self#::Core.Const(inc!)
  a::Vector{Int64}
Body::Vector{Int64}
1 ─ %1 = Main.mode_on()::Core.Const(true)
│ Core.typeassert(%1, Core.Bool)
│ %3 = Base.broadcasted(Main.:+, a, 1)::Core.PartialStruct(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(+), Tuple{Vector{Int64}, Int64}}, Any[Core.Const(+), Core.PartialStruct(Tuple{Vector{Int64}, Int64}, Any[Vector{Int64}, Core.Const(1)]), Core.Const(nothing)])
│ %4 = Base.materialize!(a, %3)::Vector{Int64}
└── return %4
2 ─ Core.Const(:(Base.broadcasted(Main.:+, a, 2)))
│ Core.Const(:(Base.materialize!(a, %6)))
└── Core.Const(:(return %7))

```

So I’d say this qualifies as conditional compilation. Furthermore, if the `mode_on()` method is redefined, then it will invalidate `inc!` and force its re-compilation next time it is called (note how the `else` clause is now the only reachable part of the code):

```julia
julia> mode_on() = false
mode_on (generic function with 1 method)

julia> @code_warntype inc!([1,2,3])
MethodInstance for inc!(::Vector{Int64})
  from inc!(a) in Main at REPL[3]:1
Arguments
  #self#::Core.Const(inc!)
  a::Vector{Int64}
Body::Vector{Int64}
1 ─ %1 = Main.mode_on()::Core.Const(false)
└── goto #3 if not %1
2 ─ Core.Const(:(Base.broadcasted(Main.:+, a, 1)))
│ Core.Const(:(Base.materialize!(a, %3)))
└── Core.Const(:(return %4))
3 ┄ %6 = Base.broadcasted(Main.:+, a, 2)::Core.PartialStruct(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(+), Tuple{Vector{Int64}, Int64}}, Any[Core.Const(+), Core.PartialStruct(Tuple{Vector{Int64}, Int64}, Any[Vector{Int64}, Core.Const(2)]), Core.Const(nothing)])
│ %7 = Base.materialize!(a, %6)::Vector{Int64}
└── return %7

```

---

_[View the full topic](https://discourse.julialang.org/t/force-recompiling-functions-in-conditional-compilation/92132)._
