Constant propagation through broadcast
- Dominant language
- Julia
- Stars
- 49.1k
- Forks
- 6k
- PR merge metrics
- PR metrics pending
Description
It would be nice if constant propagation worked through broadcasting.
```julia
using BenchmarkTools
get2(x) = getindex(x,2)
foo1(x) = sum(get2.(x))
foo2(x) = sum(getindex.(x,2))
x = fill((1,2.0,3//1),1000) # eltype(eltype(x)) is not concrete
@code_warntype foo1(x) # succeeds inference
@code_warntype foo2(x) # fails inference
@btime foo1($x); # 762.069 ns (1 allocation: 7.94 KiB)
@btime foo2($x); # 26.800 μs (2000 allocations: 70.39 KiB)
```
This fails because `getindex(::Tuple{A,B,C},i::Int) where {A,B,C}` is unstable unless `A==B==C` or `i` gets constant-folded.
One can work around this via the `get2` solution above or a similar `broadcast(...) do` block (and obviously `sum(get2,x)` is the best solution in this MWE), but having broadcast natively recognize and propagate scalar constants would be convenient and prevent people from unknowingly falling into this trap. The primary cases where I've gotten into trouble with this are broadcasts over `getindex` and `getproperty`.
Contributor guide
Research direction
Start with the supplied Julia MWE, comparing @code_warntype and @btime for foo1 and foo2. Investigate broadcast, constant propagation, and the getindex/getproperty cases described in the issue. Done means scalar constants are propagated through broadcast so these cases infer successfully without the workaround and avoid the demonstrated allocations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- julia
- Domain
- compilers, performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100