Skip to content

Commit 1a2f444

Browse files
committed
Simplify name mangling, and add support for Unions.
1 parent fc064b2 commit 1a2f444

File tree

5 files changed

+74
-38
lines changed

5 files changed

+74
-38
lines changed

src/irgen.jl

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ function irgen(@nospecialize(job::CompilerJob); ctx::JuliaContextType)
6161
# rename and process the entry point
6262
if job.config.name !== nothing
6363
LLVM.name!(entry, safe_name(string("julia_", job.config.name)))
64-
end
65-
if job.config.kernel
66-
LLVM.name!(entry, mangle_call(entry, job.source.specTypes))
64+
elseif job.config.kernel
65+
LLVM.name!(entry, mangle_sig(job.source.specTypes))
6766
end
6867
entry = process_entry!(job, mod, entry)
6968
if job.config.entry_abi === :specfunc
@@ -110,13 +109,13 @@ end
110109
# we generate function names that look like C++ functions, because many NVIDIA tools
111110
# support them, e.g., grouping different instantiations of the same kernel together.
112111

113-
function mangle_param(t, substitutions)
112+
function mangle_param(t, substitutions=String[])
114113
t == Nothing && return "v"
115114

116115
if isa(t, DataType) && t <: Ptr
117116
tn = mangle_param(eltype(t), substitutions)
118117
"P$tn"
119-
elseif isa(t, DataType) || isa(t, Core.Function)
118+
elseif isa(t, DataType)
120119
tn = safe_name(t)
121120

122121
# handle substitutions
@@ -139,6 +138,30 @@ function mangle_param(t, substitutions)
139138
str *= "E"
140139
end
141140

141+
str
142+
elseif isa(t, Union)
143+
tn = "Union"
144+
145+
# handle substitutions
146+
sub = findfirst(isequal(tn), substitutions)
147+
if sub === nothing
148+
str = "$(length(tn))$tn"
149+
push!(substitutions, tn)
150+
elseif sub == 1
151+
str = "S_"
152+
else
153+
str = "S$(sub-2)_"
154+
end
155+
156+
# encode union types as template parameters
157+
if !isempty(Base.uniontypes(t))
158+
str *= "I"
159+
for t in Base.uniontypes(t)
160+
str *= mangle_param(t, substitutions)
161+
end
162+
str *= "E"
163+
end
164+
142165
str
143166
elseif isa(t, Integer)
144167
t > 0 ? "Li$(t)E" : "Lin$(abs(t))E"
@@ -152,23 +175,36 @@ function mangle_param(t, substitutions)
152175
end
153176
end
154177

155-
# TODO: tt is sug, drop f
156-
function mangle_call(f, tt)
157-
fn = safe_name(f)
178+
function mangle_sig(sig)
179+
ft, tt... = sig.parameters
180+
181+
# mangle the function name
182+
fn = safe_name(ft)
158183
str = "_Z$(length(fn))$fn"
159184

185+
# mangle each parameter
160186
substitutions = String[]
161-
for t in tt.parameters
187+
for t in tt
162188
str *= mangle_param(t, substitutions)
163189
end
164190

165191
return str
166192
end
167193

168194
# make names safe for ptxas
169-
safe_name(fn::String) = replace(fn, r"[^A-Za-z0-9_]"=>"_")
170-
safe_name(f::Union{Core.Function,DataType}) = safe_name(String(nameof(f)))
171-
safe_name(f::LLVM.Function) = safe_name(LLVM.name(f))
195+
safe_name(fn::String) = replace(fn, r"[^A-Za-z0-9]"=>"_")
196+
safe_name(t::DataType) = safe_name(String(nameof(t)))
197+
function safe_name(t::Type{<:Function})
198+
# like Base.nameof, but for function types
199+
mt = t.name.mt
200+
fn = if mt === Symbol.name.mt
201+
# uses shared method table, so name is not unique to this function type
202+
nameof(t)
203+
else
204+
mt.name
205+
end
206+
safe_name(string(fn))
207+
end
172208
safe_name(x) = safe_name(repr(x))
173209

174210

test/gcn.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ end
8484
end
8585

8686
asm = sprint(io->gcn_code_native(io, entry, Tuple{Int64}; dump_module=true, kernel=true))
87-
@test occursin(r"\.amdhsa_kernel _Z\d*julia_entry", asm)
88-
@test !occursin(r"\.amdhsa_kernel _Z\d*julia_nonentry", asm)
89-
@test occursin(r"\.type.*julia_nonentry_\d*,@function", asm)
87+
@test occursin(r"\.amdhsa_kernel \w*entry", asm)
88+
@test !occursin(r"\.amdhsa_kernel \w*nonentry", asm)
89+
@test occursin(r"\.type.*\w*nonentry\w*,@function", asm)
9090
end
9191

9292
@testset "child function reuse" begin

test/metal.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,22 @@ end
2424
kernel(x) = return
2525

2626
ir = sprint(io->metal_code_llvm(io, kernel, Tuple{Tuple{Int}}))
27-
@test occursin(r"@.*julia.*kernel.*\(({ i64 }|\[1 x i64\])\*", ir)
27+
@test occursin(r"@\w*kernel\w*\(({ i64 }|\[1 x i64\])\*", ir)
2828

2929
# for kernels, every pointer argument needs to take an address space
3030
ir = sprint(io->metal_code_llvm(io, kernel, Tuple{Tuple{Int}}; kernel=true))
31-
@test occursin(r"@.*julia.*kernel.*\(({ i64 }|\[1 x i64\]) addrspace\(1\)\*", ir)
31+
@test occursin(r"@\w*kernel\w*\(({ i64 }|\[1 x i64\]) addrspace\(1\)\*", ir)
3232
end
3333

3434
@testset "byref primitives" begin
3535
kernel(x) = return
3636

3737
ir = sprint(io->metal_code_llvm(io, kernel, Tuple{Int}))
38-
@test occursin(r"@.*julia.*kernel.*\(i64 ", ir)
38+
@test occursin(r"@\w*kernel\w*\(i64 ", ir)
3939

4040
# for kernels, every pointer argument needs to take an address space
4141
ir = sprint(io->metal_code_llvm(io, kernel, Tuple{Int}; kernel=true))
42-
@test occursin(r"@.*julia.*kernel.*\(i64 addrspace\(1\)\*", ir)
42+
@test occursin(r"@\w*kernel\w*\(i64 addrspace\(1\)\*", ir)
4343
end
4444

4545
@testset "module metadata" begin
@@ -71,11 +71,11 @@ end
7171
end
7272

7373
ir = sprint(io->metal_code_llvm(io, kernel, Tuple{Core.LLVMPtr{Int,1}}))
74-
@test occursin(r"@.*julia.*kernel.*\(.* addrspace\(1\)\* %0\)", ir)
74+
@test occursin(r"@\w*kernel\w*\(.* addrspace\(1\)\* %0\)", ir)
7575
@test occursin(r"call i32 @julia.air.thread_position_in_threadgroup.i32", ir)
7676

7777
ir = sprint(io->metal_code_llvm(io, kernel, Tuple{Core.LLVMPtr{Int,1}}; kernel=true))
78-
@test occursin(r"@.*julia.*kernel.*\(.* addrspace\(1\)\* %0, i32 %thread_position_in_threadgroup\)", ir)
78+
@test occursin(r"@\w*kernel\w*\(.* addrspace\(1\)\* %0, i32 %thread_position_in_threadgroup\)", ir)
7979
@test !occursin(r"call i32 @julia.air.thread_position_in_threadgroup.i32", ir)
8080
end
8181

@@ -94,8 +94,8 @@ Sys.isapple() && @testset "asm" begin
9494
dump_module=true, kernel=true))
9595
@test occursin("[header]", asm)
9696
@test occursin("[program]", asm)
97-
@test occursin(r"name: .*julia.*kernel.*", asm)
98-
@test occursin(r"define void @.*julia.*kernel.*", asm)
97+
@test occursin(r"name: \w*kernel\w*", asm)
98+
@test occursin(r"define void @\w*kernel\w*", asm)
9999
end
100100

101101
end

test/ptx.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ end
2525
end
2626

2727
ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{Aggregate}))
28-
@test occursin(r"@.*julia_kernel.+\(({ i64 }|\[1 x i64\])\* ", ir)
28+
@test occursin(r"@\w*kernel\w*\(({ i64 }|\[1 x i64\])\* ", ir)
2929

3030
ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{Aggregate}; kernel=true))
31-
@test occursin(r"@.*julia_kernel.+\(.*({ i64 }|\[1 x i64\]) ", ir)
31+
@test occursin(r"@\w*kernel\w*\(.*({ i64 }|\[1 x i64\]) ", ir)
3232
end
3333

3434
@testset "property_annotations" begin
@@ -83,10 +83,10 @@ end
8383
kernel() = return
8484

8585
ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{}))
86-
@test any(occursin(r"@.*kernel.+\(\)", a) for a in split(ir, "\n"))
86+
@test occursin(r"@\w*kernel\w*\(\)", ir)
8787

8888
ir = sprint(io->ptx_code_llvm(io, kernel, Tuple{}; kernel=true))
89-
@test any(occursin(r"@.*kernel.+\(\[1 x i64\] %state\)", a) for a in split(ir, "\n"))
89+
@test occursin(r"@\w*kernel\w*\(\[1 x i64\] %state\)", ir)
9090

9191
# state should only passed to device functions that use it
9292

@@ -106,16 +106,16 @@ end
106106
kernel=true, dump_module=true))
107107

108108
# kernel should take state argument before all else
109-
@test any(occursin(r"@.*kernel.+\(\[1 x i64\] %state", a) for a in split(ir, "\n"))
109+
@test occursin(r"@\w*kernel\w*\(\[1 x i64\] %state", ir)
110110

111111
# child1 doesn't use the state
112-
@test any(occursin(r"@.*child1.+\(i64", a) for a in split(ir, "\n"))
112+
@test occursin(r"@\w*child1\w*\(i64", ir)
113113

114114
# child2 does
115-
@test any(occursin(r"@.*child2.+\(\[1 x i64\] %state", a) for a in split(ir, "\n"))
115+
@test occursin(r"@\w*child2\w*\(\[1 x i64\] %state", ir)
116116

117117
# can't have the unlowered intrinsic
118-
@test !any(occursin("julia.gpu.state_getter", a) for a in split(ir, "\n"))
118+
@test !occursin("julia.gpu.state_getter", ir)
119119
end
120120
end
121121

@@ -146,9 +146,9 @@ end
146146
end
147147

148148
asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64}; kernel=true))
149-
@test occursin(r"\.visible \.entry .*julia_entry", asm)
150-
@test !occursin(r"\.visible \.func .*julia_nonentry", asm)
151-
@test occursin(r"\.func .*julia_nonentry", asm)
149+
@test occursin(r"\.visible \.entry \w*entry", asm)
150+
@test !occursin(r"\.visible \.func \w*nonentry", asm)
151+
@test occursin(r"\.func \w*nonentry", asm)
152152

153153
@testset "property_annotations" begin
154154
asm = sprint(io->ptx_code_native(io, entry, Tuple{Int64}; kernel=true))
@@ -185,15 +185,15 @@ end
185185
end
186186

187187
asm = sprint(io->ptx_code_native(io, parent1, Tuple{Int}))
188-
@test occursin(r".func julia_.*child_", asm)
188+
@test occursin(r".func \w*child_", asm)
189189

190190
function parent2(i)
191191
child(i+1)
192192
return
193193
end
194194

195195
asm = sprint(io->ptx_code_native(io, parent2, Tuple{Int}))
196-
@test occursin(r".func julia_.*child_", asm)
196+
@test occursin(r".func \w*child_", asm)
197197
end
198198

199199
@testset "child function reuse bis" begin

test/spirv.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ end
2424
kernel(x) = return
2525

2626
ir = sprint(io->spirv_code_llvm(io, kernel, Tuple{Tuple{Int}}))
27-
@test occursin(r"@.*julia_.+_kernel.+\(({ i64 }|\[1 x i64\])\*", ir)
27+
@test occursin(r"@\w*kernel\w*\(({ i64 }|\[1 x i64\])\*", ir)
2828

2929
ir = sprint(io->spirv_code_llvm(io, kernel, Tuple{Tuple{Int}}; kernel=true))
30-
@test occursin(r"@.*julia_.+_kernel.+\(.*{ ({ i64 }|\[1 x i64\]) }\*.+byval", ir)
30+
@test occursin(r"@\w*kernel\w*\(.*{ ({ i64 }|\[1 x i64\]) }\*.+byval", ir)
3131
end
3232

3333
@testset "byval bug" begin

0 commit comments

Comments
 (0)