@@ -164,8 +164,20 @@ class OpenACCClauseCIREmitter final
164
164
builder.setInsertionPoint (operation.computeOp );
165
165
OpenACCClauseCIREmitter<typename OpTy::ComputeOpTy> computeEmitter{
166
166
operation.computeOp , cgf, builder, dirKind, dirLoc};
167
+
167
168
computeEmitter.lastDeviceTypeValues = lastDeviceTypeValues;
169
+
170
+ // Async handler uses the first data operand to figure out where to insert
171
+ // its information if it is present. This ensures that the new handler will
172
+ // correctly set the insertion point for async.
173
+ if (!dataOperands.empty ())
174
+ computeEmitter.dataOperands .push_back (dataOperands.front ());
168
175
computeEmitter.Visit (&c);
176
+
177
+ // Make sure all of the new data operands are kept track of here. The
178
+ // combined constructs always apply 'async' to only the compute component,
179
+ // so we need to collect these.
180
+ dataOperands.append (computeEmitter.dataOperands );
169
181
}
170
182
171
183
struct DataOperandInfo {
@@ -254,6 +266,8 @@ class OpenACCClauseCIREmitter final
254
266
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
255
267
mlir::acc::KernelsOp, mlir::acc::DataOp>)
256
268
return operation.getAsyncOnlyAttr ();
269
+ else if constexpr (isCombinedType<OpTy>)
270
+ return operation.computeOp .getAsyncOnlyAttr ();
257
271
258
272
// Note: 'wait' has async as well, but it cannot have data clauses, so we
259
273
// don't have to handle them here.
@@ -267,6 +281,8 @@ class OpenACCClauseCIREmitter final
267
281
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
268
282
mlir::acc::KernelsOp, mlir::acc::DataOp>)
269
283
return operation.getAsyncOperandsDeviceTypeAttr ();
284
+ else if constexpr (isCombinedType<OpTy>)
285
+ return operation.computeOp .getAsyncOperandsDeviceTypeAttr ();
270
286
271
287
// Note: 'wait' has async as well, but it cannot have data clauses, so we
272
288
// don't have to handle them here.
@@ -281,6 +297,8 @@ class OpenACCClauseCIREmitter final
281
297
if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp,
282
298
mlir::acc::KernelsOp, mlir::acc::DataOp>)
283
299
return operation.getAsyncOperands ();
300
+ else if constexpr (isCombinedType<OpTy>)
301
+ return operation.computeOp .getAsyncOperands ();
284
302
285
303
// Note: 'wait' has async as well, but it cannot have data clauses, so we
286
304
// don't have to handle them here.
@@ -296,8 +314,6 @@ class OpenACCClauseCIREmitter final
296
314
if (!hasAsyncClause || dataOperands.empty ())
297
315
return ;
298
316
299
- // TODO: OpenACC: Handle this correctly for combined constructs.
300
-
301
317
for (mlir::Operation *dataOp : dataOperands) {
302
318
llvm::TypeSwitch<mlir::Operation *, void >(dataOp)
303
319
.Case <ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS>([&](auto op) {
@@ -708,6 +724,8 @@ class OpenACCClauseCIREmitter final
708
724
addDataOperand<mlir::acc::CopyinOp, mlir::acc::CopyoutOp>(
709
725
var, mlir::acc::DataClause::acc_copy, /* structured=*/ true ,
710
726
/* implicit=*/ false );
727
+ } else if constexpr (isCombinedType<OpTy>) {
728
+ applyToComputeOp (clause);
711
729
} else {
712
730
// TODO: When we've implemented this for everything, switch this to an
713
731
// unreachable. data, declare, combined constructs remain.
0 commit comments