Skip to content

Commit 26b9ffa

Browse files
committed
[SYCL][LIBCLC] Add Control/Memory Barrier builtins for AMDGCN
1 parent 2e591fb commit 26b9ffa

File tree

4 files changed

+62
-30
lines changed

4 files changed

+62
-30
lines changed

libclc/amdgcn-amdhsa/libspirv/SOURCES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
workitem/get_global_size.cl
22
workitem/get_local_size.cl
33
workitem/get_num_groups.cl
4+
synchronization/barrier.cl
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <spirv/spirv.h>
10+
11+
void __clc_amdgcn_s_waitcnt(unsigned flags);
12+
13+
// s_waitcnt takes 16bit argument with a combined number of maximum allowed
14+
// pending operations:
15+
// [12:8] LGKM -- LDS, GDS, Konstant (SMRD), Messages
16+
// [7] -- undefined
17+
// [6:4] -- exports, GDS, and mem write
18+
// [3:0] -- vector memory operations
19+
20+
// Newer clang supports __builtin_amdgcn_s_waitcnt
21+
#if __clang_major__ >= 5
22+
# define __waitcnt(x) __builtin_amdgcn_s_waitcnt(x)
23+
#else
24+
# define __waitcnt(x) __clc_amdgcn_s_waitcnt(x)
25+
_CLC_DEF void __clc_amdgcn_s_waitcnt(unsigned) __asm("llvm.amdgcn.s.waitcnt");
26+
#endif
27+
28+
_CLC_DEF _CLC_OVERLOAD void __mem_fence(cl_mem_fence_flags flags) {
29+
if (flags & CLK_GLOBAL_MEM_FENCE) {
30+
// scalar loads are counted with LGKM but we don't know whether
31+
// the compiler turned any loads to scalar
32+
__waitcnt(0);
33+
} else if (flags & CLK_LOCAL_MEM_FENCE)
34+
__waitcnt(0xff); // LGKM is [12:8]
35+
}
36+
#undef __waitcnt
37+
38+
_CLC_OVERLOAD _CLC_DEF void __spirv_MemoryBarrier(unsigned int memory,
39+
unsigned int semantics) {
40+
__mem_fence(memory);
41+
}
42+
43+
_CLC_OVERLOAD _CLC_DEF _CLC_CONVERGENT void
44+
__spirv_ControlBarrier(unsigned int scope, unsigned int memory,
45+
unsigned int semantics) {
46+
if (semantics) {
47+
__mem_fence(memory);
48+
}
49+
__builtin_amdgcn_s_barrier();
50+
}

libclc/amdgcn/lib/mem_fence/fence.cl

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,13 @@
11
#include <clc/clc.h>
22

3-
void __clc_amdgcn_s_waitcnt(unsigned flags);
4-
5-
// s_waitcnt takes 16bit argument with a combined number of maximum allowed
6-
// pending operations:
7-
// [12:8] LGKM -- LDS, GDS, Konstant (SMRD), Messages
8-
// [7] -- undefined
9-
// [6:4] -- exports, GDS, and mem write
10-
// [3:0] -- vector memory operations
11-
12-
// Newer clang supports __builtin_amdgcn_s_waitcnt
13-
#if __clang_major__ >= 5
14-
# define __waitcnt(x) __builtin_amdgcn_s_waitcnt(x)
15-
#else
16-
# define __waitcnt(x) __clc_amdgcn_s_waitcnt(x)
17-
_CLC_DEF void __clc_amdgcn_s_waitcnt(unsigned) __asm("llvm.amdgcn.s.waitcnt");
18-
#endif
19-
20-
_CLC_DEF _CLC_OVERLOAD void mem_fence(cl_mem_fence_flags flags) {
21-
if (flags & CLK_GLOBAL_MEM_FENCE) {
22-
// scalar loads are counted with LGKM but we don't know whether
23-
// the compiler turned any loads to scalar
24-
__waitcnt(0);
25-
} else if (flags & CLK_LOCAL_MEM_FENCE)
26-
__waitcnt(0xff); // LGKM is [12:8]
27-
}
28-
#undef __waitcnt
3+
_CLC_OVERLOAD _CLC_DEF void __spirv_MemoryBarrier(unsigned int memory,
4+
unsigned int semantics);
295

306
// We don't have separate mechanism for read and write fences
317
_CLC_DEF _CLC_OVERLOAD void read_mem_fence(cl_mem_fence_flags flags) {
32-
mem_fence(flags);
8+
__spirv_MemoryBarrier(flags, 1);
339
}
3410

3511
_CLC_DEF _CLC_OVERLOAD void write_mem_fence(cl_mem_fence_flags flags) {
36-
mem_fence(flags);
12+
__spirv_MemoryBarrier(flags, 1);
3713
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include <clc/clc.h>
22

3+
_CLC_OVERLOAD _CLC_DEF _CLC_CONVERGENT void
4+
__spirv_ControlBarrier(unsigned int scope, unsigned int memory,
5+
unsigned int semantics);
6+
37
_CLC_DEF _CLC_OVERLOAD void barrier(cl_mem_fence_flags flags) {
4-
mem_fence(flags);
5-
__builtin_amdgcn_s_barrier();
8+
// Call spir-v implementation of the barrier.
9+
// Set semantics to not None, so it performs mem fence.
10+
__spirv_ControlBarrier(0, flags, 1);
611
}

0 commit comments

Comments
 (0)