@@ -165,4 +165,112 @@ class SPIRVToOCL : public ModulePass, public InstVisitor<SPIRVToOCL> {
165
165
Module *M;
166
166
LLVMContext *Ctx;
167
167
};
168
+
169
+ class SPIRVToOCL12 : public SPIRVToOCL {
170
+ public:
171
+ SPIRVToOCL12() : SPIRVToOCL(ID) {
172
+ initializeSPIRVToOCL12Pass(*PassRegistry::getPassRegistry());
173
+ }
174
+ bool runOnModule(Module &M) override;
175
+
176
+ /// Transform __spirv_MemoryBarrier to atomic_work_item_fence.
177
+ /// __spirv_MemoryBarrier(scope, sema) =>
178
+ /// atomic_work_item_fence(flag(sema), order(sema), map(scope))
179
+ void visitCallSPIRVMemoryBarrier(CallInst *CI) override;
180
+
181
+ /// Transform __spirv_ControlBarrier to barrier.
182
+ /// __spirv_ControlBarrier(execScope, memScope, sema) =>
183
+ /// barrier(flag(sema))
184
+ void visitCallSPIRVControlBarrier(CallInst *CI) override;
185
+
186
+ /// Transform __spirv_OpAtomic functions. It firstly conduct generic
187
+ /// mutations for all builtins and then mutate some of them seperately
188
+ Instruction *visitCallSPIRVAtomicBuiltin(CallInst *CI, Op OC) override;
189
+
190
+ /// Transform __spirv_OpAtomicIIncrement / OpAtomicIDecrement to
191
+ /// atomic_inc / atomic_dec
192
+ Instruction *visitCallSPIRVAtomicIncDec(CallInst *CI, Op OC) override;
193
+
194
+ /// Transform __spirv_OpAtomicUMin/SMin/UMax/SMax into
195
+ /// atomic_min/atomic_max, as there is no distinction in OpenCL 1.2
196
+ /// between signed and unsigned version of those functions
197
+ Instruction *visitCallSPIRVAtomicUMinUMax(CallInst *CI, Op OC);
198
+
199
+ /// Transform __spirv_OpAtomicLoad to atomic_add(*ptr, 0)
200
+ Instruction *visitCallSPIRVAtomicLoad(CallInst *CI);
201
+
202
+ /// Transform __spirv_OpAtomicStore to atomic_xchg(*ptr, value)
203
+ Instruction *visitCallSPIRVAtomicStore(CallInst *CI);
204
+
205
+ /// Transform __spirv_OpAtomicFlagClear to atomic_xchg(*ptr, 0)
206
+ /// with ignoring the result
207
+ Instruction *visitCallSPIRVAtomicFlagClear(CallInst *CI);
208
+
209
+ /// Transform __spirv_OpAtomicFlagTestAndTest to
210
+ /// (bool)atomic_xchg(*ptr, 1)
211
+ Instruction *visitCallSPIRVAtomicFlagTestAndSet(CallInst *CI);
212
+
213
+ /// Transform __spirv_OpAtomicCompareExchange and
214
+ /// __spirv_OpAtomicCompareExchangeWeak into atomic_cmpxchg. There is no
215
+ /// weak version of function in OpenCL 1.2
216
+ Instruction *visitCallSPIRVAtomicCmpExchg(CallInst *CI, Op OC) override;
217
+
218
+ /// Conduct generic mutations for all atomic builtins
219
+ CallInst *mutateCommonAtomicArguments(CallInst *CI, Op OC) override;
220
+
221
+ /// Transform atomic builtin name into correct ocl-dependent name
222
+ Instruction *mutateAtomicName(CallInst *CI, Op OC) override;
223
+
224
+ /// Transform SPIR-V atomic instruction opcode into OpenCL 1.2 builtin name.
225
+ /// Depending on the type, the return name starts with "atomic_" for 32-bit
226
+ /// types or with "atom_" for 64-bit types, as specified by
227
+ /// cl_khr_int64_base_atomics and cl_khr_int64_extended_atomics extensions.
228
+ std::string mapAtomicName(Op OC, Type *Ty);
229
+
230
+ static char ID;
231
+ };
232
+
233
+ class SPIRVToOCL20 : public SPIRVToOCL {
234
+ public:
235
+ SPIRVToOCL20() : SPIRVToOCL(ID) {
236
+ initializeSPIRVToOCL20Pass(*PassRegistry::getPassRegistry());
237
+ }
238
+ bool runOnModule(Module &M) override;
239
+
240
+ /// Transform __spirv_MemoryBarrier to atomic_work_item_fence.
241
+ /// __spirv_MemoryBarrier(scope, sema) =>
242
+ /// atomic_work_item_fence(flag(sema), order(sema), map(scope))
243
+ void visitCallSPIRVMemoryBarrier(CallInst *CI) override;
244
+
245
+ /// Transform __spirv_ControlBarrier to work_group_barrier/sub_group_barrier.
246
+ /// If execution scope is ScopeWorkgroup:
247
+ /// __spirv_ControlBarrier(execScope, memScope, sema) =>
248
+ /// work_group_barrier(flag(sema), map(memScope))
249
+ /// Otherwise:
250
+ /// __spirv_ControlBarrier(execScope, memScope, sema) =>
251
+ /// sub_group_barrier(flag(sema), map(memScope))
252
+ void visitCallSPIRVControlBarrier(CallInst *CI) override;
253
+
254
+ /// Transform __spirv_Atomic* to atomic_*.
255
+ /// __spirv_Atomic*(atomic_op, scope, sema, ops, ...) =>
256
+ /// atomic_*(generic atomic_op, ops, ..., order(sema), map(scope))
257
+ Instruction *visitCallSPIRVAtomicBuiltin(CallInst *CI, Op OC) override;
258
+
259
+ /// Transform __spirv_OpAtomicIIncrement / OpAtomicIDecrement to
260
+ /// atomic_fetch_add_explicit / atomic_fetch_sub_explicit
261
+ Instruction *visitCallSPIRVAtomicIncDec(CallInst *CI, Op OC) override;
262
+
263
+ /// Conduct generic mutations for all atomic builtins
264
+ CallInst *mutateCommonAtomicArguments(CallInst *CI, Op OC) override;
265
+
266
+ /// Transform atomic builtin name into correct ocl-dependent name
267
+ Instruction *mutateAtomicName(CallInst *CI, Op OC) override;
268
+
269
+ /// Transform __spirv_OpAtomicCompareExchange/Weak into
270
+ /// compare_exchange_strong/weak_explicit
271
+ Instruction *visitCallSPIRVAtomicCmpExchg(CallInst *CI, Op OC) override;
272
+
273
+ static char ID;
274
+ };
275
+
168
276
} // namespace SPIRV
0 commit comments