Skip to content

Commit 0b80774

Browse files
authored
optimize Symbol with constant string argument (#32437)
1 parent f814301 commit 0b80774

File tree

4 files changed

+19
-13
lines changed

4 files changed

+19
-13
lines changed

base/boot.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,12 @@ Array{T}(A::AbstractArray{S,N}) where {T,N,S} = Array{T,N}(A)
432432
AbstractArray{T}(A::AbstractArray{S,N}) where {T,S,N} = AbstractArray{T,N}(A)
433433

434434
# primitive Symbol constructors
435-
function Symbol(s::String)
435+
eval(Core, :(function Symbol(s::String)
436+
$(Expr(:meta, :pure))
436437
return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int),
437438
ccall(:jl_string_ptr, Ptr{UInt8}, (Any,), s),
438439
sizeof(s))
439-
end
440+
end))
440441
function Symbol(a::Array{UInt8,1})
441442
return ccall(:jl_symbol_n, Ref{Symbol}, (Ptr{UInt8}, Int),
442443
ccall(:jl_array_ptr, Ptr{UInt8}, (Any,), a),

base/compiler/utilities.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ function quoted(@nospecialize(x))
7373
end
7474

7575
function is_inlineable_constant(@nospecialize(x))
76-
x isa Type && return true
76+
if x isa Type || x isa Symbol
77+
return true
78+
end
7779
return isbits(x) && Core.sizeof(x) <= MAX_INLINE_CONST_SIZE
7880
end
7981

base/strings/string.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Convert a string to a contiguous byte array representation encoded as UTF-8 byte
6666
This representation is often appropriate for passing strings to C.
6767
"""
6868
String(s::AbstractString) = print_to_string(s)
69-
String(s::Symbol) = unsafe_string(unsafe_convert(Ptr{UInt8}, s))
69+
@pure String(s::Symbol) = unsafe_string(unsafe_convert(Ptr{UInt8}, s))
7070

7171
unsafe_wrap(::Type{Vector{UInt8}}, s::String) = ccall(:jl_string_to_array, Ref{Vector{UInt8}}, (Any,), s)
7272

@@ -81,8 +81,8 @@ String(s::CodeUnits{UInt8,String}) = s.s
8181
pointer(s::String) = unsafe_convert(Ptr{UInt8}, s)
8282
pointer(s::String, i::Integer) = pointer(s)+(i-1)
8383

84-
ncodeunits(s::String) = Core.sizeof(s)
85-
sizeof(s::String) = Core.sizeof(s)
84+
@pure ncodeunits(s::String) = Core.sizeof(s)
85+
@pure sizeof(s::String) = Core.sizeof(s)
8686
codeunit(s::String) = UInt8
8787

8888
@inline function codeunit(s::String, i::Integer)

test/compiler/inference.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,20 +1711,19 @@ g26826(x) = getfield26826(x, :a, :b)
17111711
# If this test is broken (especially if inference is getting a correct, but loose result,
17121712
# like a Union) then it's potentially an indication that the optimizer isn't hitting the
17131713
# InferenceResult cache properly for varargs methods.
1714-
typed_code = Core.Compiler.code_typed(f26826, (Float64,))[1].first
1715-
found_well_typed_getfield_call = false
1716-
let i
1714+
let ct = Core.Compiler.code_typed(f26826, (Float64,))[1]
1715+
typed_code, retty = ct.first, ct.second
1716+
found_poorly_typed_getfield_call = false
17171717
for i = 1:length(typed_code.code)
17181718
stmt = typed_code.code[i]
17191719
rhs = Meta.isexpr(stmt, :(=)) ? stmt.args[2] : stmt
1720-
if Meta.isexpr(rhs, :call) && rhs.args[1] == GlobalRef(Base, :getfield) && typed_code.ssavaluetypes[i] === Float64
1721-
global found_well_typed_getfield_call = true
1720+
if Meta.isexpr(rhs, :call) && rhs.args[1] == GlobalRef(Base, :getfield) && typed_code.ssavaluetypes[i] !== Float64
1721+
found_poorly_typed_getfield_call = true
17221722
end
17231723
end
1724+
@test !found_poorly_typed_getfield_call && retty === Float64
17241725
end
17251726

1726-
@test found_well_typed_getfield_call
1727-
17281727
# 27059 fix fieldtype vararg and union handling
17291728

17301729
f27059(::Type{T}) where T = i -> fieldtype(T, i)
@@ -2482,3 +2481,7 @@ end
24822481
@test Base.return_types(g33768, ()) == Any[Any]
24832482
@test_throws ArgumentError h33768()
24842483
@test Base.return_types(h33768, ()) == Any[Union{}]
2484+
2485+
# constant prop of `Symbol("")`
2486+
f_getf_computed_symbol(p) = getfield(p, Symbol("first"))
2487+
@test Base.return_types(f_getf_computed_symbol, Tuple{Pair{Int8,String}}) == [Int8]

0 commit comments

Comments
 (0)