@@ -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