Skip to content

Commit e8d41a5

Browse files
authored
Metal: Inline functions to avoid unreachable function attributes. (#454)
1 parent 30cd0ae commit e8d41a5

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

src/metal.jl

+33
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,41 @@ end
136136

137137
@unlocked function mcgen(job::CompilerJob{MetalCompilerTarget}, mod::LLVM.Module,
138138
format=LLVM.API.LLVMObjectFile)
139+
ctx = context(mod)
140+
139141
strip_debuginfo!(mod) # XXX: is this needed?
140142

143+
# hide `noreturn` function attributes, which cause issues with the back-end compiler,
144+
# probably because of thread-divergent control flow as we've encountered with CUDA.
145+
# note that it isn't enough to remove the function attribute, because the Metal LLVM
146+
# compiler re-optimizes and will rediscover the property. to avoid this, we inline
147+
# all functions that are marked noreturn, i.e., until LLVM cannot rediscover it.
148+
let
149+
noreturn_attr = EnumAttribute("noreturn", 0; ctx)
150+
noinline_attr = EnumAttribute("noinline", 0; ctx)
151+
alwaysinline_attr = EnumAttribute("alwaysinline", 0; ctx)
152+
153+
any_noreturn = false
154+
for f in functions(mod)
155+
attrs = function_attributes(f)
156+
if noreturn_attr in collect(attrs)
157+
delete!(attrs, noreturn_attr)
158+
delete!(attrs, noinline_attr)
159+
push!(attrs, alwaysinline_attr)
160+
any_noreturn = true
161+
end
162+
end
163+
164+
if any_noreturn
165+
@dispose pm=ModulePassManager() begin
166+
always_inliner!(pm)
167+
cfgsimplification!(pm)
168+
instruction_combining!(pm)
169+
run!(pm, mod)
170+
end
171+
end
172+
end
173+
141174
# translate to metallib
142175
input = tempname(cleanup=false) * ".bc"
143176
translated = tempname(cleanup=false) * ".metallib"

0 commit comments

Comments
 (0)