Skip to content

Commit 316668b

Browse files
authored
Fix and test mangling (#632)
1 parent 4e0490c commit 316668b

File tree

3 files changed

+87
-27
lines changed

3 files changed

+87
-27
lines changed

src/mangling.jl

+49-19
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,37 @@ safe_name(x) = safe_name(repr(x))
2929
# we generate function names that look like C++ functions, because many tools, like NVIDIA's
3030
# profilers, support them (grouping different instantiations of the same kernel together).
3131

32-
function mangle_param(t, substitutions=String[])
32+
function mangle_param(t, substitutions=Any[])
3333
t == Nothing && return "v"
3434

35+
function find_substitution(x)
36+
sub = findfirst(isequal(x), substitutions)
37+
if sub === nothing
38+
nothing
39+
elseif sub == 1
40+
"S_"
41+
else
42+
seq_id = uppercase(string(sub-2; base=36))
43+
"S$(seq_id)_"
44+
end
45+
end
46+
3547
if isa(t, DataType) && t <: Ptr
3648
tn = mangle_param(eltype(t), substitutions)
3749
"P$tn"
3850
elseif isa(t, DataType)
39-
tn = safe_name(t)
51+
# check if we already know this type
52+
str = find_substitution(t)
53+
if str !== nothing
54+
return str
55+
end
4056

41-
# handle substitutions
42-
sub = findfirst(isequal(tn), substitutions)
43-
if sub === nothing
57+
# check if we already know this base type
58+
str = find_substitution(t.name.wrapper)
59+
if str === nothing
60+
tn = safe_name(t)
4461
str = "$(length(tn))$tn"
45-
push!(substitutions, tn)
46-
elseif sub == 1
47-
str = "S_"
48-
else
49-
str = "S$(sub-2)_"
62+
push!(substitutions, t.name.wrapper)
5063
end
5164

5265
# encode typevars as template parameters
@@ -56,21 +69,24 @@ function mangle_param(t, substitutions=String[])
5669
str *= mangle_param(t, substitutions)
5770
end
5871
str *= "E"
72+
73+
push!(substitutions, t)
5974
end
6075

6176
str
6277
elseif isa(t, Union)
63-
tn = "Union"
78+
# check if we already know this union type
79+
str = find_substitution(t)
80+
if str !== nothing
81+
return str
82+
end
6483

65-
# handle substitutions
66-
sub = findfirst(isequal(tn), substitutions)
67-
if sub === nothing
84+
# check if we already know the Union name
85+
str = find_substitution(Union)
86+
if str === nothing
87+
tn = "Union"
6888
str = "$(length(tn))$tn"
6989
push!(substitutions, tn)
70-
elseif sub == 1
71-
str = "S_"
72-
else
73-
str = "S$(sub-2)_"
7490
end
7591

7692
# encode union types as template parameters
@@ -80,9 +96,13 @@ function mangle_param(t, substitutions=String[])
8096
str *= mangle_param(t, substitutions)
8197
end
8298
str *= "E"
99+
100+
push!(substitutions, t)
83101
end
84102

85103
str
104+
elseif isa(t, UnionAll)
105+
mangle_param(t.body, substitutions)
86106
elseif isa(t, Union{Bool, Cchar, Cuchar, Cshort, Cushort, Cint, Cuint, Clong, Culong, Clonglong, Culonglong, Int128, UInt128})
87107
ts = t isa Bool ? 'b' : # bool
88108
t isa Cchar ? 'a' : # signed char
@@ -99,10 +119,20 @@ function mangle_param(t, substitutions=String[])
99119
t isa UInt128 ? 'o' : # unsigned __int128
100120
error("Invalid type")
101121
tn = string(abs(t), base=10)
122+
# for legibility, encode Julia-native integers as C-native integers, if possible
123+
if t isa Int && typemin(Cint) <= t <= typemax(Cint)
124+
ts = 'i'
125+
end
102126
if t < 0
103127
tn = 'n'*tn
104128
end
105129
"L$(ts)$(tn)E"
130+
elseif t isa Float32
131+
bits = string(reinterpret(UInt32, t); base=16)
132+
"Lf$(bits)E"
133+
elseif t isa Float64
134+
bits = string(reinterpret(UInt64, t); base=16)
135+
"Ld$(bits)E"
106136
else
107137
tn = safe_name(t) # TODO: actually does support digits...
108138
if startswith(tn, r"\d")
@@ -121,7 +151,7 @@ function mangle_sig(sig)
121151
str = "_Z$(length(fn))$fn"
122152

123153
# mangle each parameter
124-
substitutions = String[]
154+
substitutions = []
125155
for t in tt
126156
str *= mangle_param(t, substitutions)
127157
end

test/Project.toml

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SPIRV_LLVM_Translator_unified_jll = "85f0d8ed-5b39-5caa-b1ae-7472de402361"
1010
SPIRV_Tools_jll = "6ac6d60f-d740-5983-97d7-a4482c0689f4"
1111
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1212
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
13+
demumble_jll = "1e29f10c-031c-5a83-9565-69cddfc27673"
1314

1415
[compat]
1516
Aqua = "0.8"

test/util_tests.jl

+37-8
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,43 @@
99
@test groups[3] == [:(d=4)]
1010
end
1111

12-
@testset "mangle" begin
13-
struct XX{T} end
14-
# values checked with c++filt / cu++filt
15-
@test GPUCompiler.mangle_sig(Tuple{typeof(sin), XX{false}}) == "_Z3sin2XXILb0EE" # "sin(XX<false>)"
16-
@test GPUCompiler.mangle_sig(Tuple{typeof(sin), XX{true}}) == "_Z3sin2XXILb1EE" # "sin(XX<true>)"
17-
@test GPUCompiler.mangle_sig(Tuple{typeof(sin), XX{Cshort(10)}}) == "_Z3sin2XXILs10EE" # "sin(XX<(short)10>)"
18-
@test GPUCompiler.mangle_sig(Tuple{typeof(sin), XX{Cshort(0)}}) == "_Z3sin2XXILs0EE" # "sin(XX<(short)l>)"
19-
@test GPUCompiler.mangle_sig(Tuple{typeof(sin), XX{Cshort(-10)}}) == "_Z3sin2XXILsn10EE" # "sin(XX<(short)-10>)"
12+
@testset "mangling" begin
13+
using demumble_jll
14+
15+
function mangle(f, argtyps...)
16+
mangled = GPUCompiler.mangle_sig(Tuple{typeof(f), argtyps...})
17+
chomp(read(`$(demumble_jll.demumble()) $mangled`, String))
18+
end
19+
20+
# basic stuff
21+
@test mangle(identity) == "identity"
22+
@test mangle(identity, Nothing) == "identity()"
23+
24+
# primitive types
25+
@test mangle(identity, Int32) == "identity(Int32)"
26+
@test mangle(identity, Int64) == "identity(Int64)"
27+
28+
# literals
29+
@test mangle(identity, Val{1}) == "identity(Val<1>)"
30+
@test mangle(identity, Val{-1}) == "identity(Val<-1>)"
31+
@test mangle(identity, Val{Cshort(1)}) == "identity(Val<(short)1>)"
32+
@test mangle(identity, Val{1.0}) == "identity(Val<0x1p+0>)"
33+
@test mangle(identity, Val{1f0}) == "identity(Val<0x1p+0f>)"
34+
35+
# unions
36+
@test mangle(identity, Union{Int32, Int64}) == "identity(Union<Int32, Int64>)"
37+
38+
# union alls
39+
@test mangle(identity, Array) == "identity(Array<T, N>)"
40+
41+
# many substitutions
42+
@test mangle(identity, Val{1}, Val{2}, Val{3}, Val{4}, Val{5}, Val{6}, Val{7}, Val{8},
43+
Val{9}, Val{10}, Val{11}, Val{12}, Val{13}, Val{14}, Val{15},
44+
Val{16}, Val{16}) ==
45+
"identity(Val<1>, Val<2>, Val<3>, Val<4>, Val<5>, Val<6>, Val<7>, Val<8>, Val<9>, Val<10>, Val<11>, Val<12>, Val<13>, Val<14>, Val<15>, Val<16>, Val<16>)"
46+
47+
# problematic examples
48+
@test mangle(identity, String, Matrix{Float32}, Broadcast.Broadcasted{Broadcast.ArrayStyle{Matrix{Float32}}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(sin)}, Broadcast.Extruded{Matrix{Float32}, Tuple{Bool, Bool}, Tuple{Int64, Int64}}}}) == "identity(String, Array<Float32, 2>, Broadcasted<ArrayStyle<Array<Float32, 2>>, Tuple<OneTo<Int64>, OneTo<Int64>>, literal_pow, Tuple<RefValue<sin>, Extruded<Array<Float32, 2>, Tuple<Bool, Bool>, Tuple<Int64, Int64>>>>)"
2049
end
2150

2251
@testset "safe loggers" begin

0 commit comments

Comments
 (0)