From 6869ca86e7ab50535b000d680d31f0b758c3e05c Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 14 Oct 2024 09:47:41 +0200 Subject: [PATCH 1/2] propagate inbounds in a few more places for memoryref --- base/Base_compiler.jl | 1 + base/array.jl | 2 +- base/boot.jl | 5 +++-- base/essentials.jl | 4 ---- base/genericmemory.jl | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/base/Base_compiler.jl b/base/Base_compiler.jl index db3ebb0232e38..034cfdbff112a 100644 --- a/base/Base_compiler.jl +++ b/base/Base_compiler.jl @@ -40,6 +40,7 @@ macro inline() Expr(:meta, :inline) end macro noinline() Expr(:meta, :noinline) end macro _boundscheck() Expr(:boundscheck) end +macro _propagate_inbounds_meta() Expr(:meta, :inline, :propagate_inbounds) end # Try to help prevent users from shooting them-selves in the foot # with ambiguities by defining a few common and critical operations diff --git a/base/array.jl b/base/array.jl index aafcfc182124b..d7d663e157672 100644 --- a/base/array.jl +++ b/base/array.jl @@ -281,7 +281,7 @@ the same manner as C. """ function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n) n == 0 && return dest - unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n) + @inbounds unsafe_copyto!(memoryref(dest.ref, doffs), memoryref(src.ref, soffs), n) return dest end diff --git a/base/boot.jl b/base/boot.jl index 53e439d83ebe2..f4d069e82cb26 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -328,6 +328,7 @@ macro inline() Expr(:meta, :inline) end macro noinline() Expr(:meta, :noinline) end macro _boundscheck() Expr(:boundscheck) end +macro _propagate_inbounds_meta() Expr(:meta, :inline, :propagate_inbounds) end # n.b. the effects and model of these is refined in inference abstractinterpretation.jl TypeVar(@nospecialize(n)) = _typevar(n::Symbol, Union{}, Any) @@ -590,8 +591,8 @@ memoryref(mem::GenericMemory) = memoryrefnew(mem) memoryref(mem::GenericMemory, i::Integer) = memoryrefnew(memoryrefnew(mem), Int(i), @_boundscheck) memoryref(ref::GenericMemoryRef, i::Integer) = memoryrefnew(ref, Int(i), @_boundscheck) GenericMemoryRef(mem::GenericMemory) = memoryref(mem) -GenericMemoryRef(mem::GenericMemory, i::Integer) = memoryref(mem, i) -GenericMemoryRef(mem::GenericMemoryRef, i::Integer) = memoryref(mem, i) +GenericMemoryRef(mem::GenericMemory, i::Integer) = (@_propagate_inbounds_meta; memoryref(mem, i)) +GenericMemoryRef(mem::GenericMemoryRef, i::Integer) = (@_propagate_inbounds_meta; memoryref(mem, i)) const AtomicMemory{T} = GenericMemory{:atomic, T, CPU} const AtomicMemoryRef{T} = GenericMemoryRef{:atomic, T, CPU} diff --git a/base/essentials.jl b/base/essentials.jl index fa5cf79192f56..7174e59736153 100644 --- a/base/essentials.jl +++ b/base/essentials.jl @@ -369,10 +369,6 @@ macro _noub_if_noinbounds_meta() #=:nortcall=#false)) end -# another version of inlining that propagates an inbounds context -macro _propagate_inbounds_meta() - return Expr(:meta, :inline, :propagate_inbounds) -end macro _nospecializeinfer_meta() return Expr(:meta, :nospecializeinfer) end diff --git a/base/genericmemory.jl b/base/genericmemory.jl index 2a33336c0aad6..b423ee951b682 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -261,7 +261,7 @@ function setindex!(A::Memory{T}, x, i1::Int) where {T} end function setindex!(A::Memory{T}, x, i1::Int, i2::Int, I::Int...) where {T} - @inline + @_propagate_inbounds_meta @boundscheck (i2 == 1 && all(==(1), I)) || throw_boundserror(A, (i1, i2, I...)) setindex!(A, x, i1) end From c7cd406d078a6b48c0c52a6a15a1a44edc6efdd6 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Mon, 14 Oct 2024 15:55:34 +0200 Subject: [PATCH 2/2] don't check twice --- base/genericmemory.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/base/genericmemory.jl b/base/genericmemory.jl index b423ee951b682..82ce2d1c34cf1 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -250,7 +250,8 @@ getindex(A::Memory, c::Colon) = copy(A) function _setindex!(A::Memory{T}, x::T, i1::Int) where {T} ref = memoryrefnew(memoryref(A), i1, @_boundscheck) - memoryrefset!(ref, x, :not_atomic, @_boundscheck) + # boundscheck emitted by `memoryrefnew` also checks the index for memoryrefset! + memoryrefset!(ref, x, :not_atomic, false) return A end