Skip to content

Constant Propagation on Base.getindex #35531

Closed
@stev47

Description

@stev47

Due to high compile times for very large static vectors constant propagation was changed in #32105 to bail out on Base.getindex in cases where the object is any non-singleton AbstractArray.

This can prevent one from harnessing constant propagation to provide type-stability in cases where the index is constant:

# constant propagation and getindex

# not inheriting from AbstractArray works
struct A <: AbstractArray{Int,1}
    # making A empty (i.e a singleton) works
    x::Int
end
# this does not help
#Base.issingletontype(::Type{<:A}) = true

Base.size(::A) = (1,)

my_getindex(a::A, i) = i > 1 ? missing : i
Base.getindex(a::A, i) = i > 1 ? missing : i

f(a) = my_getindex(a, 1)
g(a) = Base.getindex(a, 1)

a = A(0)

# this infers correctly to `Int` using constant propagation
@code_warntype f(a)
# this infers to `Union{Missing,Int}`
@code_warntype g(a)

A more concrete usecase is the package StaticKernels where the user is defining a kernel function with constant relative indexing on a moving Window array that efficiently handles array boundaries using the type system.
In order not to sacrifice the user interface the current workaround is to not inherit from AbstractArray even though it would make sense.

Can we provide a method for array types to opt-in to constant propagation for getindex or refine the current heuristic?

julia> versioninfo()
Julia Version 1.5.0-DEV.650
Commit dd738f9ee8* (2020-04-19 16:28 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: AMD A10-7860K Radeon R7, 12 Compute Cores 4C+8G
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, bdver3)
Environment:
  JULIA_PKG_SERVER = pkg.julialang.org

Metadata

Metadata

Assignees

No one assigned

    Labels

    arrays[a, r, r, a, y, s]

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions