@@ -249,17 +249,29 @@ static void createDeclareAllocFuncWithArg(mlir::OpBuilder &modBuilder,
249249 if (unwrapFirBox)
250250 asFortranDesc << accFirDescriptorPostfix.str ();
251251
252- // Updating descriptor must occur before the mapping of the data so that
253- // attached data pointer is not overwritten.
254- mlir::acc::UpdateDeviceOp updateDeviceOp =
255- createDataEntryOp<mlir::acc::UpdateDeviceOp>(
256- builder, loc, registerFuncOp.getArgument (0 ), asFortranDesc, bounds,
257- /* structured=*/ false , /* implicit=*/ true ,
258- mlir::acc::DataClause::acc_update_device, descTy,
259- /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
260- llvm::SmallVector<int32_t > operandSegments{0 , 0 , 0 , 1 };
261- llvm::SmallVector<mlir::Value> operands{updateDeviceOp.getResult ()};
262- createSimpleOp<mlir::acc::UpdateOp>(builder, loc, operands, operandSegments);
252+ // For descriptor, preserve old behavior when unwrapping FIR box: update.
253+ if (unwrapFirBox) {
254+ mlir::acc::UpdateDeviceOp updateDeviceOp =
255+ createDataEntryOp<mlir::acc::UpdateDeviceOp>(
256+ builder, loc, registerFuncOp.getArgument (0 ), asFortranDesc, bounds,
257+ /* structured=*/ false , /* implicit=*/ true ,
258+ mlir::acc::DataClause::acc_update_device, descTy,
259+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
260+ llvm::SmallVector<int32_t > operandSegments{0 , 0 , 0 , 1 };
261+ llvm::SmallVector<mlir::Value> operands{updateDeviceOp.getResult ()};
262+ createSimpleOp<mlir::acc::UpdateOp>(builder, loc, operands,
263+ operandSegments);
264+ } else {
265+ // New behavior: start a structured region with declare_enter.
266+ EntryOp descEntryOp = createDataEntryOp<EntryOp>(
267+ builder, loc, registerFuncOp.getArgument (0 ), asFortranDesc, bounds,
268+ /* structured=*/ false , /* implicit=*/ true , clause, descTy,
269+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
270+ mlir::acc::DeclareEnterOp::create (
271+ builder, loc,
272+ mlir::acc::DeclareTokenType::get (descEntryOp.getContext ()),
273+ mlir::ValueRange (descEntryOp.getAccVar ()));
274+ }
263275
264276 if (unwrapFirBox) {
265277 mlir::Value desc =
@@ -304,30 +316,58 @@ static void createDeclareDeallocFuncWithArg(
304316 }
305317
306318 llvm::SmallVector<mlir::Value> bounds;
307- mlir::acc::GetDevicePtrOp entryOp =
308- createDataEntryOp<mlir::acc::GetDevicePtrOp>(
309- builder, loc, var, asFortran, bounds,
310- /* structured=*/ false , /* implicit=*/ false , clause, var.getType (),
311- /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
312- mlir::acc::DeclareExitOp::create (builder, loc, mlir::Value{},
313- mlir::ValueRange (entryOp.getAccVar ()));
314-
315- if constexpr (std::is_same_v<ExitOp, mlir::acc::CopyoutOp> ||
316- std::is_same_v<ExitOp, mlir::acc::UpdateHostOp>)
317- ExitOp::create (builder, entryOp.getLoc (), entryOp.getAccVar (),
318- entryOp.getVar (), entryOp.getVarType (), entryOp.getBounds (),
319- entryOp.getAsyncOperands (),
320- entryOp.getAsyncOperandsDeviceTypeAttr (),
321- entryOp.getAsyncOnlyAttr (), entryOp.getDataClause (),
322- /* structured=*/ false , /* implicit=*/ false ,
323- builder.getStringAttr (*entryOp.getName ()));
324- else
325- ExitOp::create (builder, entryOp.getLoc (), entryOp.getAccVar (),
326- entryOp.getBounds (), entryOp.getAsyncOperands (),
327- entryOp.getAsyncOperandsDeviceTypeAttr (),
328- entryOp.getAsyncOnlyAttr (), entryOp.getDataClause (),
329- /* structured=*/ false , /* implicit=*/ false ,
330- builder.getStringAttr (*entryOp.getName ()));
319+ if (unwrapFirBox) {
320+ // Unwrap: delete device payload using getdeviceptr + declare_exit + ExitOp
321+ mlir::acc::GetDevicePtrOp entryOp =
322+ createDataEntryOp<mlir::acc::GetDevicePtrOp>(
323+ builder, loc, var, asFortran, bounds,
324+ /* structured=*/ false , /* implicit=*/ false , clause, var.getType (),
325+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
326+ mlir::acc::DeclareExitOp::create (builder, loc, mlir::Value{},
327+ mlir::ValueRange (entryOp.getAccVar ()));
328+
329+ if constexpr (std::is_same_v<ExitOp, mlir::acc::CopyoutOp> ||
330+ std::is_same_v<ExitOp, mlir::acc::UpdateHostOp>)
331+ ExitOp::create (builder, entryOp.getLoc (), entryOp.getAccVar (),
332+ entryOp.getVar (), entryOp.getVarType (),
333+ entryOp.getBounds (), entryOp.getAsyncOperands (),
334+ entryOp.getAsyncOperandsDeviceTypeAttr (),
335+ entryOp.getAsyncOnlyAttr (), entryOp.getDataClause (),
336+ /* structured=*/ false , /* implicit=*/ false ,
337+ builder.getStringAttr (*entryOp.getName ()));
338+ else
339+ ExitOp::create (builder, entryOp.getLoc (), entryOp.getAccVar (),
340+ entryOp.getBounds (), entryOp.getAsyncOperands (),
341+ entryOp.getAsyncOperandsDeviceTypeAttr (),
342+ entryOp.getAsyncOnlyAttr (), entryOp.getDataClause (),
343+ /* structured=*/ false , /* implicit=*/ false ,
344+ builder.getStringAttr (*entryOp.getName ()));
345+ } else {
346+ mlir::acc::GetDevicePtrOp entryOp =
347+ createDataEntryOp<mlir::acc::GetDevicePtrOp>(
348+ builder, loc, var, asFortran, bounds,
349+ /* structured=*/ false , /* implicit=*/ false , clause, var.getType (),
350+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
351+ mlir::acc::DeclareExitOp::create (builder, loc, mlir::Value{},
352+ mlir::ValueRange (entryOp.getAccVar ()));
353+
354+ if constexpr (std::is_same_v<ExitOp, mlir::acc::CopyoutOp> ||
355+ std::is_same_v<ExitOp, mlir::acc::UpdateHostOp>)
356+ ExitOp::create (builder, entryOp.getLoc (), entryOp.getAccVar (),
357+ entryOp.getVar (), entryOp.getVarType (),
358+ entryOp.getBounds (), entryOp.getAsyncOperands (),
359+ entryOp.getAsyncOperandsDeviceTypeAttr (),
360+ entryOp.getAsyncOnlyAttr (), entryOp.getDataClause (),
361+ /* structured=*/ false , /* implicit=*/ false ,
362+ builder.getStringAttr (*entryOp.getName ()));
363+ else
364+ ExitOp::create (builder, entryOp.getLoc (), entryOp.getAccVar (),
365+ entryOp.getBounds (), entryOp.getAsyncOperands (),
366+ entryOp.getAsyncOperandsDeviceTypeAttr (),
367+ entryOp.getAsyncOnlyAttr (), entryOp.getDataClause (),
368+ /* structured=*/ false , /* implicit=*/ false ,
369+ builder.getStringAttr (*entryOp.getName ()));
370+ }
331371
332372 // Generate the post dealloc function.
333373 modBuilder.setInsertionPointAfter (preDeallocOp);
@@ -343,15 +383,28 @@ static void createDeclareDeallocFuncWithArg(
343383 asFortran << accFirDescriptorPostfix.str ();
344384 }
345385
346- mlir::acc::UpdateDeviceOp updateDeviceOp =
347- createDataEntryOp<mlir::acc::UpdateDeviceOp>(
348- builder, loc, var, asFortran, bounds,
349- /* structured=*/ false , /* implicit=*/ true ,
350- mlir::acc::DataClause::acc_update_device, var.getType (),
351- /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
352- llvm::SmallVector<int32_t > operandSegments{0 , 0 , 0 , 1 };
353- llvm::SmallVector<mlir::Value> operands{updateDeviceOp.getResult ()};
354- createSimpleOp<mlir::acc::UpdateOp>(builder, loc, operands, operandSegments);
386+ if (unwrapFirBox) {
387+ // Old behavior: update descriptor after deallocation.
388+ mlir::acc::UpdateDeviceOp updateDeviceOp =
389+ createDataEntryOp<mlir::acc::UpdateDeviceOp>(
390+ builder, loc, var, asFortran, bounds,
391+ /* structured=*/ false , /* implicit=*/ true ,
392+ mlir::acc::DataClause::acc_update_device, var.getType (),
393+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
394+ llvm::SmallVector<int32_t > operandSegments{0 , 0 , 0 , 1 };
395+ llvm::SmallVector<mlir::Value> operands{updateDeviceOp.getResult ()};
396+ createSimpleOp<mlir::acc::UpdateOp>(builder, loc, operands,
397+ operandSegments);
398+ } else {
399+ // New behavior: end structured region with declare_exit.
400+ mlir::acc::GetDevicePtrOp postEntryOp =
401+ createDataEntryOp<mlir::acc::GetDevicePtrOp>(
402+ builder, loc, var, asFortran, bounds,
403+ /* structured=*/ false , /* implicit=*/ true , clause, var.getType (),
404+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
405+ mlir::acc::DeclareExitOp::create (builder, loc, mlir::Value{},
406+ mlir::ValueRange (postEntryOp.getAccVar ()));
407+ }
355408 modBuilder.setInsertionPointAfter (postDeallocOp);
356409 builder.restoreInsertionPoint (crtInsPt);
357410}
@@ -3994,17 +4047,28 @@ static void createDeclareAllocFunc(mlir::OpBuilder &modBuilder,
39944047 asFortranDesc << accFirDescriptorPostfix.str ();
39954048 llvm::SmallVector<mlir::Value> bounds;
39964049
3997- // Updating descriptor must occur before the mapping of the data so that
3998- // attached data pointer is not overwritten.
3999- mlir::acc::UpdateDeviceOp updateDeviceOp =
4000- createDataEntryOp<mlir::acc::UpdateDeviceOp>(
4001- builder, loc, addrOp, asFortranDesc, bounds,
4002- /* structured=*/ false , /* implicit=*/ true ,
4003- mlir::acc::DataClause::acc_update_device, addrOp.getType (),
4004- /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
4005- llvm::SmallVector<int32_t > operandSegments{0 , 0 , 0 , 1 };
4006- llvm::SmallVector<mlir::Value> operands{updateDeviceOp.getResult ()};
4007- createSimpleOp<mlir::acc::UpdateOp>(builder, loc, operands, operandSegments);
4050+ // For unwrapFirBox=false this remains declare_enter; for unwrapFirBox=true,
4051+ // the descriptor post-alloc remains update behavior.
4052+ if (unwrapFirBox) {
4053+ mlir::acc::UpdateDeviceOp updDesc =
4054+ createDataEntryOp<mlir::acc::UpdateDeviceOp>(
4055+ builder, loc, addrOp, asFortranDesc, bounds,
4056+ /* structured=*/ false , /* implicit=*/ true ,
4057+ mlir::acc::DataClause::acc_update_device, addrOp.getType (),
4058+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
4059+ llvm::SmallVector<int32_t > seg{0 , 0 , 0 , 1 };
4060+ llvm::SmallVector<mlir::Value> ops{updDesc.getResult ()};
4061+ createSimpleOp<mlir::acc::UpdateOp>(builder, loc, ops, seg);
4062+ } else {
4063+ EntryOp descEntryOp = createDataEntryOp<EntryOp>(
4064+ builder, loc, addrOp, asFortranDesc, bounds,
4065+ /* structured=*/ false , /* implicit=*/ true , clause, addrOp.getType (),
4066+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
4067+ mlir::acc::DeclareEnterOp::create (
4068+ builder, loc,
4069+ mlir::acc::DeclareTokenType::get (descEntryOp.getContext ()),
4070+ mlir::ValueRange (descEntryOp.getAccVar ()));
4071+ }
40084072
40094073 if (unwrapFirBox) {
40104074 auto loadOp = fir::LoadOp::create (builder, loc, addrOp.getResult ());
@@ -4097,15 +4161,27 @@ static void createDeclareDeallocFunc(mlir::OpBuilder &modBuilder,
40974161 if (unwrapFirBox)
40984162 asFortran << accFirDescriptorPostfix.str ();
40994163 llvm::SmallVector<mlir::Value> bounds;
4100- mlir::acc::UpdateDeviceOp updateDeviceOp =
4101- createDataEntryOp<mlir::acc::UpdateDeviceOp>(
4102- builder, loc, addrOp, asFortran, bounds,
4103- /* structured=*/ false , /* implicit=*/ true ,
4104- mlir::acc::DataClause::acc_update_device, addrOp.getType (),
4105- /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
4106- llvm::SmallVector<int32_t > operandSegments{0 , 0 , 0 , 1 };
4107- llvm::SmallVector<mlir::Value> operands{updateDeviceOp.getResult ()};
4108- createSimpleOp<mlir::acc::UpdateOp>(builder, loc, operands, operandSegments);
4164+ if (unwrapFirBox) {
4165+ // Unwrap mode: update the descriptor after deallocation (no declare_exit).
4166+ mlir::acc::UpdateDeviceOp updDesc =
4167+ createDataEntryOp<mlir::acc::UpdateDeviceOp>(
4168+ builder, loc, addrOp, asFortran, bounds,
4169+ /* structured=*/ false , /* implicit=*/ true ,
4170+ mlir::acc::DataClause::acc_update_device, addrOp.getType (),
4171+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
4172+ llvm::SmallVector<int32_t > seg{0 , 0 , 0 , 1 };
4173+ llvm::SmallVector<mlir::Value> ops{updDesc.getResult ()};
4174+ createSimpleOp<mlir::acc::UpdateOp>(builder, loc, ops, seg);
4175+ } else {
4176+ // Default: end the structured declare region using declare_exit.
4177+ mlir::acc::GetDevicePtrOp descEntryOp =
4178+ createDataEntryOp<mlir::acc::GetDevicePtrOp>(
4179+ builder, loc, addrOp, asFortran, bounds,
4180+ /* structured=*/ false , /* implicit=*/ true , clause, addrOp.getType (),
4181+ /* async=*/ {}, /* asyncDeviceTypes=*/ {}, /* asyncOnlyDeviceTypes=*/ {});
4182+ mlir::acc::DeclareExitOp::create (builder, loc, mlir::Value{},
4183+ mlir::ValueRange (descEntryOp.getAccVar ()));
4184+ }
41094185 modBuilder.setInsertionPointAfter (postDeallocOp);
41104186}
41114187
0 commit comments