Skip to content

Commit 51d9cde

Browse files
committed
switch to using clang instead of bultin LLVM for compilation
1 parent 1cb3501 commit 51d9cde

4 files changed

Lines changed: 76 additions & 1 deletion

File tree

src/compiler/codegen.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,44 @@ function GPUCompiler.link_libraries!(@nospecialize(job::HIPCompilerJob), mod::LL
4242
wavefrontsize64=job.config.params.wavefrontsize64)
4343
end
4444

45+
46+
GPUCompiler.@unlocked function GPUCompiler.mcgen(
47+
@nospecialize(job::CompilerJob{<:GCNCompilerTarget}), mod::LLVM.Module, format=LLVM.API.LLVMAssemblyFile,
48+
)
49+
clang_path = AMDGPU.ROCmDiscovery.clang_path
50+
if isempty(clang_path)
51+
# Fallback to GPUCompiler default if no external clang is found
52+
return invoke(GPUCompiler.mcgen, Tuple{CompilerJob, LLVM.Module, typeof(format)}, job, mod, format)
53+
end
54+
55+
target = job.config.target
56+
filetype = if format == LLVM.API.LLVMAssemblyFile
57+
"asm"
58+
elseif format == LLVM.API.LLVMObjectFile
59+
"obj"
60+
else
61+
error("Unsupported GCN output format $format")
62+
end
63+
64+
input = tempname(cleanup=false) * ".bc"
65+
output = tempname(cleanup=false) * (filetype == "asm" ? ".s" : ".o")
66+
write(input, mod)
67+
68+
cmd = `$clang_path -x ir $input -mcpu=$(target.dev_isa) --target=$(GPUCompiler.llvm_triple(target)) -nogpulib $(filetype == "asm" ? "-S" : "-c") -o $output`
69+
70+
try
71+
run(cmd)
72+
catch
73+
error("""Failed to compile to GCN with external clang.
74+
If you think this is a bug, please file an issue and attach $(input).""")
75+
end
76+
77+
code = filetype == "asm" ? read(output, String) : String(read(output))
78+
rm(input)
79+
rm(output)
80+
return code
81+
end
82+
4583
function GPUCompiler.finish_module!(
4684
@nospecialize(job::HIPCompilerJob), mod::LLVM.Module, entry::LLVM.Function,
4785
)

src/compiler/device_libs.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ function link_device_libs!(
2828
wavefrontsize64::Bool,
2929
)
3030
isnothing(libdevice_libs) && return
31+
if !isempty(AMDGPU.ROCmDiscovery.clang_path)
32+
return
33+
end
3134

3235
# 1. Load other libraries.
3336
lib_names = ("hc", "hip", "irif", "ockl", "opencl", "ocml")

src/discovery/discovery.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module ROCmDiscovery
22

3-
export lld_artifact, lld_path, libhsaruntime, libdevice_libs, libhip
3+
export lld_artifact, lld_path, clang_path, clang_artifact, libhsaruntime, libdevice_libs, libhip
44
export librocblas, librocsparse, librocsolver
55
export librocrand, librocfft, libMIOpen_path
66

@@ -26,6 +26,16 @@ function get_ld_lld(rocm_path::String)::Tuple{String, Bool}
2626
return (LLD_jll.lld_path, true)
2727
end
2828

29+
function get_clang(rocm_path::String)::Tuple{String, Bool}
30+
clang_path = find_clang(rocm_path)
31+
if isempty(clang_path)
32+
# Not found, could use LLD_jll or something if it had clang, but it doesn't.
33+
# So return empty
34+
return ("", false)
35+
end
36+
return (clang_path, true)
37+
end
38+
2939
function _hip_runtime_version()
3040
v_ref = Ref{Cint}()
3141
res = ccall((:hipRuntimeGetVersion, libhip), UInt32, (Ptr{Cint},), v_ref)
@@ -42,6 +52,8 @@ global rel_libdir::String = Sys.islinux() ? "" : "bin"
4252
global libhsaruntime::String = ""
4353
global lld_path::String = ""
4454
global lld_artifact::Bool = false
55+
global clang_path::String = ""
56+
global clang_artifact::Bool = false
4557
global libhip::String = ""
4658
global libdevice_libs::String = ""
4759
global librocblas::String = ""
@@ -78,6 +90,11 @@ function __init__()
7890
lld_path, lld_artifact = get_ld_lld(rocm_path)
7991
global lld_path = lld_path
8092
global lld_artifact = lld_artifact
93+
94+
# Clang
95+
clang_path, clang_artifact = get_clang(rocm_path)
96+
global clang_path = clang_path
97+
global clang_artifact = clang_artifact
8198
global libhip = find_rocm_library(Sys.islinux() ? "libamdhip64" : "amdhip64"; rocm_path)
8299

83100
global libdevice_libs = find_device_libs(rocm_path)

src/discovery/utils.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,20 @@ function find_ld_lld(rocm_path::String)::String
162162
end
163163
return ""
164164
end
165+
166+
function find_clang(rocm_path::String)::String
167+
clang_name = "clang" * (Sys.iswindows() ? ".exe" : "")
168+
169+
dirs = (joinpath(rocm_path, "llvm", "bin"), joinpath(rocm_path, "bin"))
170+
hipconfig = Sys.which("hipconfig")
171+
if !isnothing(hipconfig)
172+
clang_path = read(`$hipconfig --hipclangpath`, String)
173+
dirs = (dirs..., clang_path)
174+
end
175+
for dir in dirs
176+
exp_clang_path = joinpath(dir, clang_name)
177+
ispath(exp_clang_path) || continue
178+
return exp_clang_path
179+
end
180+
return ""
181+
end

0 commit comments

Comments
 (0)