|
136 | 136 |
|
137 | 137 | @unlocked function mcgen(job::CompilerJob{MetalCompilerTarget}, mod::LLVM.Module,
|
138 | 138 | format=LLVM.API.LLVMObjectFile)
|
| 139 | + ctx = context(mod) |
| 140 | + |
139 | 141 | strip_debuginfo!(mod) # XXX: is this needed?
|
140 | 142 |
|
| 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 | + |
141 | 174 | # translate to metallib
|
142 | 175 | input = tempname(cleanup=false) * ".bc"
|
143 | 176 | translated = tempname(cleanup=false) * ".metallib"
|
|
0 commit comments