Revision df3da0582a7800dab72bf4c7b1f1b69cd6605744 authored by Shuhei Kadowaki on 23 August 2022, 05:19:59 UTC, committed by GitHub on 23 August 2022, 05:19:59 UTC
This builtin is useful to control compiler behavior.
It could be considered as a more robust and generalized version of `inferencebarrier`.

I scratched the following docstring for `compilerbarrier`, that hopefully
explains its purpose.

    Base.compilerbarrier(setting::Symbol, val)

This function puts a barrier at a specified compilation phase.
It is supposed to only influence the compilation behavior according to `setting`,
and its runtime semantics is just to return the second argument `val` (except that
this function will perform additional checks on `setting` in a case when `setting`
isn't known precisely at compile-time.)

Currently either of the following `setting`s is allowed:
- Barriers on abstract interpretation:
* `:type`: the return type of this function call will be inferred as `Any` always
(the strongest barrier on abstract interpretation)
* `:const`: the return type of this function call will be inferred with widening
constant information on `val`
* `:conditional`: the return type of this function call will be inferred with widening
conditional information on `val` (see the example below)
- Any barriers on optimization aren't implemented yet

!!! note
    This function is supposed to be used _with `setting` known precisely at compile-time_.
    Note that in a case when the `setting` isn't known precisely at compile-time, the compiler
    currently will put the most strongest barrier(s) rather than emitting a compile-time warning.

\# Examples

```julia
julia> Base.return_types((Int,)) do a
       x = compilerbarrier(:type, a) # `x` won't be inferred as `x::Int`
       return x
   end |> only
Any

julia> Base.return_types() do
       x = compilerbarrier(:const, 42)
       if x == 42 # no constant information here, so inference also accounts for the else branch
           return x # but `x` is still inferred as `x::Int` at least here
       else
           return nothing
       end
   end |> only
Union{Nothing, Int64}

julia> Base.return_types((Union{Int,Nothing},)) do a
       if compilerbarrier(:conditional, isa(a, Int))
           # the conditional information `a::Int` isn't available here (leading to less accurate return type inference)
           return a
       else
           return nothing
       end
   end |> only
Union{Nothing, Int64}
```

As a result, `Base.inferencebarrier` is now defined as
```julia
inferencebarrier(@nospecialize(x)) = compilerbarrier(:type, x)
```
1 parent 80e50b5
History
File Mode Size
.devcontainer
.github
base
cli
contrib
deps
doc
etc
src
stdlib
test
.buildkite-external-version -rw-r--r-- 5 bytes
.clang-format -rw-r--r-- 3.3 KB
.codecov.yml -rw-r--r-- 52 bytes
.git-blame-ignore-revs -rw-r--r-- 294 bytes
.gitattributes -rw-r--r-- 65 bytes
.gitignore -rw-r--r-- 493 bytes
.mailmap -rw-r--r-- 12.1 KB
CITATION.bib -rw-r--r-- 513 bytes
CITATION.cff -rw-r--r-- 940 bytes
CONTRIBUTING.md -rw-r--r-- 23.2 KB
HISTORY.md -rw-r--r-- 349.9 KB
LICENSE.md -rw-r--r-- 1.3 KB
Make.inc -rw-r--r-- 50.0 KB
Makefile -rw-r--r-- 26.7 KB
NEWS.md -rw-r--r-- 7.7 KB
README.md -rw-r--r-- 7.3 KB
THIRDPARTY.md -rw-r--r-- 3.7 KB
VERSION -rw-r--r-- 10 bytes
julia.spdx.json -rw-r--r-- 35.8 KB
sysimage.mk -rw-r--r-- 4.1 KB

README.md

back to top