@@ -202,6 +202,16 @@ class PrepareForOMPOffloadPrivatizationPass
202202 return clonedOp;
203203 };
204204
205+ if (isFirstPrivate) {
206+ Region ©Region = privatizer.getCopyRegion ();
207+ assert (!copyRegion.empty () && " copyRegion cannot be empty" );
208+ LLVM::LLVMFuncOp copyFunc = createFuncOpForRegion (
209+ loc, mod, copyRegion,
210+ llvm::formatv (" {0}_{1}" , privatizer.getSymName (), " copy" ).str (),
211+ firstOp, rewriter);
212+ rewriter.create <LLVM::CallOp>(loc, copyFunc, ValueRange{varPtr, heapMem});
213+ }
214+
205215 rewriter.setInsertionPoint (targetOp);
206216 rewriter.setInsertionPoint (cloneAndMarkForDeletion (mapInfoOperation));
207217
@@ -218,76 +228,8 @@ class PrepareForOMPOffloadPrivatizationPass
218228 if (memberMapInfoOp.getVarPtrPtr ()) {
219229 Operation *varPtrPtrdefOp =
220230 memberMapInfoOp.getVarPtrPtr ().getDefiningOp ();
221-
222- // In the case of firstprivate, we have to do the following
223- // 1. Allocate heap memory for the underlying data.
224- // 2. Copy the original underlying data to the new memory
225- // allocated on the heap.
226- // 3. Put this new (heap) address in the originating
227- // struct/descriptor
228-
229- // Consider the following sequence of omp.map.info and omp.target
230- // operations.
231- // %0 = llvm.getelementptr %19[0, 0]
232- // %1 = omp.map.info var_ptr(%19 : !llvm.ptr, i32) ...
233- // var_ptr_ptr(%0 : !llvm.ptr) bounds(..)
234- // %2 = omp.map.info var_ptr(%19 : !llvm.ptr, !desc_type)>) ...
235- // members(%1 : [0] : !llvm.ptr) -> !llvm.ptr
236- // omp.target nowait map_entries(%2 -> %arg5, %1 -> %arg8 : ..)
237- // private(@privatizer %19 -> %arg9 [map_idx=1]
238- // : !llvm.ptr) {
239- // We need to allocate memory on the heap for the underlying
240- // pointer which is stored at the var_ptr_ptr operand of %1. Then
241- // we need to copy this pointer to the new heap allocated memory
242- // location. Then, we need to store the address of the new heap
243- // location in the originating struct/descriptor. So, we generate
244- // the following (pseudo) MLIR code (Using the same names of
245- // mlir::Value instances in the example as in the code below)
246- //
247- // %dataMalloc = malloc(totalSize)
248- // %loadDataPtr = load %0 : !llvm.ptr -> !llvm.ptr
249- // memcpy(%dataMalloc, %loadDataPtr, totalSize)
250- // %newVarPtrPtrOp = llvm.getelementptr %heapMem[0, 0]
251- // llvm.store %dataMalloc, %newVarPtrPtrOp
252- // %1.cloned = omp.map.info var_ptr(%heapMem : !llvm.ptr, i32) ...
253- // var_ptr_ptr(%newVarPtrPtrOp :
254- // !llvm.ptr)
255- // %2.cloned = omp.map.info var_ptr(%heapMem : !llvm.ptr,
256- // !desc_type)>) ...
257- // members(%1.cloned : [0] : !llvm.ptr)
258- // -> !llvm.ptr
259- // omp.target nowait map_entries(%2.cloned -> %arg5,
260- // %1.cloned -> %arg8 : ..)
261- // private(@privatizer %heapMem -> .. [map_idx=1] : ..)
262- // {
263-
264- if (isFirstPrivate) {
265- assert (!memberMapInfoOp.getBounds ().empty () &&
266- " empty bounds on member map of firstprivate variable" );
267- Location loc = memberMapInfoOp.getLoc ();
268- Value totalSize =
269- getSizeInBytes (memberMapInfoOp, mod, rewriter);
270- auto dataMalloc =
271- allocateHeapMem (loc, totalSize, mod, rewriter);
272- auto loadDataPtr = rewriter.create <LLVM::LoadOp>(
273- loc, memberMapInfoOp.getVarPtrPtr ().getType (),
274- memberMapInfoOp.getVarPtrPtr ());
275- (void )rewriter.create <LLVM::MemcpyOp>(
276- loc, dataMalloc.getResult (), loadDataPtr.getResult (),
277- totalSize, /* isVolatile=*/ false );
278- Operation *newVarPtrPtrOp = rewriter.clone (*varPtrPtrdefOp);
279- rewriter.replaceAllUsesExcept (memberMapInfoOp.getVarPtrPtr (),
280- newVarPtrPtrOp->getOpResult (0 ),
281- loadDataPtr);
282- rewriter.modifyOpInPlace (newVarPtrPtrOp, [&]() {
283- newVarPtrPtrOp->replaceUsesOfWith (varPtr, heapMem);
284- });
285- (void )rewriter.create <LLVM::StoreOp>(
286- loc, dataMalloc.getResult (), newVarPtrPtrOp->getResult (0 ));
287- } else {
288- rewriter.setInsertionPoint (
289- cloneAndMarkForDeletion (varPtrPtrdefOp));
290- }
231+ rewriter.setInsertionPoint (
232+ cloneAndMarkForDeletion (varPtrPtrdefOp));
291233 }
292234 }
293235 }
0 commit comments