@@ -249,17 +249,29 @@ static void createDeclareAllocFuncWithArg(mlir::OpBuilder &modBuilder,
249
249
if (unwrapFirBox)
250
250
asFortranDesc << accFirDescriptorPostfix.str ();
251
251
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
+ }
263
275
264
276
if (unwrapFirBox) {
265
277
mlir::Value desc =
@@ -304,30 +316,58 @@ static void createDeclareDeallocFuncWithArg(
304
316
}
305
317
306
318
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
+ }
331
371
332
372
// Generate the post dealloc function.
333
373
modBuilder.setInsertionPointAfter (preDeallocOp);
@@ -343,15 +383,28 @@ static void createDeclareDeallocFuncWithArg(
343
383
asFortran << accFirDescriptorPostfix.str ();
344
384
}
345
385
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
+ }
355
408
modBuilder.setInsertionPointAfter (postDeallocOp);
356
409
builder.restoreInsertionPoint (crtInsPt);
357
410
}
@@ -3994,17 +4047,28 @@ static void createDeclareAllocFunc(mlir::OpBuilder &modBuilder,
3994
4047
asFortranDesc << accFirDescriptorPostfix.str ();
3995
4048
llvm::SmallVector<mlir::Value> bounds;
3996
4049
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
+ }
4008
4072
4009
4073
if (unwrapFirBox) {
4010
4074
auto loadOp = fir::LoadOp::create (builder, loc, addrOp.getResult ());
@@ -4097,15 +4161,27 @@ static void createDeclareDeallocFunc(mlir::OpBuilder &modBuilder,
4097
4161
if (unwrapFirBox)
4098
4162
asFortran << accFirDescriptorPostfix.str ();
4099
4163
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
+ }
4109
4185
modBuilder.setInsertionPointAfter (postDeallocOp);
4110
4186
}
4111
4187
0 commit comments