Skip to content

Commit

Permalink
Propagate inboudns through setindex!!
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf committed Jul 20, 2019
1 parent 7b670ed commit d7403b3
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 4 deletions.
22 changes: 22 additions & 0 deletions benchmark/map.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using BangBang


mapbb(f, xs::Array, inbounds::Val = Val(true)) =
__map!!(f, similar(xs, Union{}), xs, 1, inbounds)


@inline function __map!!(f, ys, xs, n, inbounds)
@simd for i in n:length(ys)
if inbounds === Val(true)
@inbounds begin
ys′ = setindex!!(ys, f(xs[i]), i)
end
else
ys′ = setindex!!(ys, f(xs[i]), i)
end
if !(ys′ isa typeof(ys))
return __map!!(f, ys′, xs, i + 1, inbounds)
end
end
return ys
end
4 changes: 3 additions & 1 deletion src/NoBang/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ _setindex(xs::NamedTuple, value, name) = setproperty(xs, name, value)
function _setindex(xs::AbstractArray, v, I...)
T = promote_type(eltype(xs), typeof(v))
ys = similar(xs, T)
copy!(ys, xs)
if eltype(xs) !== Union{}
copy!(ys, xs)
end
ys[I...] = v
return ys
end
Expand Down
4 changes: 2 additions & 2 deletions src/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ possible(::typeof(_splice!), xs::C, i::Any, ::S) where {C, S} =
"""
setindex!!(collection, value, indices...) -> collection′
"""
setindex!!(xs, v, I...) = may(_setindex!, xs, v, I...)
Base.@propagate_inbounds setindex!!(xs, v, I...) = may(_setindex!, xs, v, I...)

_setindex!(xs, v, I...) = (setindex!(xs, v, I...); xs)
Base.@propagate_inbounds _setindex!(xs, v, I...) = (setindex!(xs, v, I...); xs)

pure(::typeof(_setindex!)) = NoBang._setindex
possible(::typeof(_setindex!), ::Union{Tuple, NamedTuple}, ::Vararg) = false
Expand Down
2 changes: 1 addition & 1 deletion src/core.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
may(mutate, args...) =
Base.@propagate_inbounds may(mutate, args...) =
if possible(mutate, args...)
mutate(args...)
else
Expand Down
8 changes: 8 additions & 0 deletions test/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[IRTest]]
deps = ["Test"]
git-tree-sha1 = "5f2778f64fdc9d2e29176869ba49167777ed1170"
repo-rev = "master"
repo-url = "https://github.com/tkf/IRTest.jl"
uuid = "c9680f28-2a59-47f6-98e4-d41620d42cd2"
version = "0.1.0"

[[InitialValues]]
git-tree-sha1 = "00fc3631033606a66b6eebce4b020ad21abd5243"
repo-rev = "master"
Expand Down
2 changes: 2 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[deps]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
BangBang = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
IRTest = "c9680f28-2a59-47f6-98e4-d41620d42cd2"
InitialValues = "22cec73e-a1b8-11e9-2c92-598750a2cf9c"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
28 changes: 28 additions & 0 deletions test/__test_ir.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using InteractiveUtils: code_llvm
using Test

include("../benchmark/map.jl")

"""
llvm_ir(f, args) :: String
Get LLVM IR of `f(args...)` as a string.
"""
llvm_ir(f, args) = sprint(code_llvm, f, Base.typesof(args...))

nmatches(r, s) = count(_ -> true, eachmatch(r, s))

twice(x) = 2x

@testset "setindex!! (@inbounds)" begin
@test mapbb(twice, [1:3;], Val(false)) == [2, 4, 6]

ir_noinbounds = llvm_ir(mapbb, (twice, Float64[], Val(false)))
if Base.JLOptions().check_bounds == 2 # --check-bounds=no
@test nmatches(r"fmul <4 x double>", ir_noinbounds) >= 4
else
@test nmatches(r"fmul <4 x double>", ir_noinbounds) == 0
end
ir_inbounds = llvm_ir(mapbb, (twice, Float64[], Val(true)))
@test nmatches(r"fmul <4 x double>", ir_inbounds) >= 4
end
6 changes: 6 additions & 0 deletions test/test_ir.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module TestIR

using IRTest
IRTest.@include("__test_ir.jl")

end # module

0 comments on commit d7403b3

Please sign in to comment.