Skip to content

Commit 6647cef

Browse files
committed
Attempt atomic legalization
1 parent 8b8c73f commit 6647cef

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

atomics.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using GPUCompiler
2+
using LLVM
3+
4+
function initialize()
5+
if !GPUCompiler.__llvm_initialized[]
6+
InitializeAllTargets()
7+
InitializeAllTargetInfos()
8+
InitializeAllAsmPrinters()
9+
InitializeAllAsmParsers()
10+
InitializeAllTargetMCs()
11+
GPUCompiler.__llvm_initialized[] = true
12+
end
13+
end
14+
15+
# include all helpers
16+
include(joinpath("test", "helpers", "runtime.jl"))
17+
include(joinpath("test", "helpers", "ptx.jl"))
18+
19+
job, _ = PTX.create_job(identity, (Int,))
20+
21+
includet("src/atomic_legalization.jl")
22+
23+
# mod = """
24+
# define void @test(ptr %a) nounwind {
25+
# %1 = load atomic i128, ptr %a seq_cst, align 16
26+
# store atomic i128 %1, ptr %a seq_cst, align 16
27+
# ret void
28+
# }
29+
# """
30+
# => __sync_val_compare_and_swap_16
31+
32+
33+
# mod = """
34+
# define void @test(ptr %a) nounwind {
35+
# %1 = load atomic i8, ptr %a seq_cst, align 16
36+
# store atomic i8 %1, ptr %a seq_cst, align 16
37+
# ret void
38+
# }
39+
# """
40+
41+
# Cannot select: 0x67a0660: ch = AtomicStore<(store seq_cst (s8) into %ir.a, align 16)> 0x67a05f0:1, 0x67a0580, 0x67a05f0
42+
# 0x67a0580: i64,ch = load<(dereferenceable invariant load (s64) from `ptr addrspace(101) null`, addrspace 101)> 0x7125d30, TargetExternalSymbol:i64'test_param_0', undef:i64
43+
# 0x67a0200: i64 = TargetExternalSymbol'test_param_0'
44+
# 0x67a02e0: i64 = undef
45+
# 0x67a05f0: i16,ch = AtomicLoad<(load seq_cst (s8) from %ir.a, align 16)> 0x7125d30, 0x67a0580
46+
# 0x67a0580: i64,ch = load<(dereferenceable invariant load (s64) from `ptr addrspace(101) null`, addrspace 101)> 0x7125d30, TargetExternalSymbol:i64'test_param_0', undef:i64
47+
# 0x67a0200: i64 = TargetExternalSymbol'test_param_0'
48+
# 0x67a02e0: i64 = undef
49+
50+
mod = """
51+
define i8 @test(ptr %a) nounwind {
52+
%1 = load atomic i8, ptr %a seq_cst, align 16
53+
ret i8 %1
54+
}
55+
"""
56+
57+
asm, meta = JuliaContext(opaque_pointers=true) do ctx
58+
initialize()
59+
ir = parse(LLVM.Module, mod)
60+
ir = legalize_atomics!(job, ir)
61+
GPUCompiler.emit_asm(job, ir, LLVM.API.LLVMAssemblyFile)
62+
end
63+
64+

src/atomic_legalization.jl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# in bytes
2+
function smallest_atomic_size(job)
3+
return 4
4+
end
5+
6+
# 1. Legalize sizes
7+
# 2. Legalize ordering through fences
8+
# 3. Legalize operations through cmpswp
9+
10+
function legalize_atomics!(job, ir)
11+
dl = datalayout(ir)
12+
for f in functions(ir), bb in blocks(f), inst in instructions(bb)
13+
if inst isa LLVM.LoadInst && is_atomic(inst)
14+
typ = value_type(inst)
15+
if sizeof(dl, typ) < smallest_atomic_size(job)
16+
# Replace with a larger atomic type
17+
@dispose builder = IRBuilder() begin
18+
position!(builder, inst)
19+
ptr = only(operands(inst))
20+
load = load!(builder, LLVM.IntType(smallest_atomic_size(job) * 8), ptr)
21+
# TODO: alignment, ordering, etc.
22+
# TODO: Handle floats and other types appropriately
23+
# TODO: Do we need to shift the loaded value?
24+
new_inst = trunc!(builder, load, typ)
25+
26+
replace_uses!(inst, new_inst)
27+
erase!(inst)
28+
end
29+
end
30+
elseif inst isa LLVM.StoreInst && is_atomic(inst)
31+
end
32+
end
33+
return ir
34+
end

0 commit comments

Comments
 (0)