[OpenACC][CIR] Implement 'exit data' construct + clauses (#146167)
Similar to 'enter data', except the data clauses have a 'getdeviceptr' operation before, so that they can properly use the 'exit' operation correctly. While this is a touch awkward, it fits perfectly into the existing infrastructure. Same as with 'enter data', we had to add some add-functions for async and wait.
This commit is contained in:
@@ -2083,6 +2083,26 @@ def OpenACC_ExitDataOp : OpenACC_Op<"exit_data",
|
||||
|
||||
/// The i-th data operand passed.
|
||||
Value getDataOperand(unsigned i);
|
||||
|
||||
/// Add an entry to the 'async-only' attribute (clause spelled without
|
||||
/// arguments). DeviceType array is supplied even though it should always be
|
||||
/// empty, so this can mirror other versions of this function.
|
||||
void addAsyncOnly(MLIRContext *, llvm::ArrayRef<DeviceType>);
|
||||
/// Add a value to the 'async'. DeviceType array is supplied even though it
|
||||
/// should always be empty, so this can mirror other versions of this
|
||||
/// function.
|
||||
void addAsyncOperand(MLIRContext *, mlir::Value,
|
||||
llvm::ArrayRef<DeviceType>);
|
||||
|
||||
/// Add an entry to the 'wait-only' attribute (clause spelled without
|
||||
/// arguments). DeviceType array is supplied even though it should always be
|
||||
/// empty, so this can mirror other versions of this function.
|
||||
void addWaitOnly(MLIRContext *, llvm::ArrayRef<DeviceType>);
|
||||
/// Add an array-like entry to the 'wait'. DeviceType array is supplied
|
||||
/// even though it should always be empty, so this can mirror other versions
|
||||
/// of this function.
|
||||
void addWaitOperands(MLIRContext *, bool hasDevnum, mlir::ValueRange,
|
||||
llvm::ArrayRef<DeviceType>);
|
||||
}];
|
||||
|
||||
let assemblyFormat = [{
|
||||
|
||||
@@ -3169,6 +3169,53 @@ void ExitDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
|
||||
results.add<RemoveConstantIfCondition<ExitDataOp>>(context);
|
||||
}
|
||||
|
||||
void ExitDataOp::addAsyncOnly(MLIRContext *context,
|
||||
llvm::ArrayRef<DeviceType> effectiveDeviceTypes) {
|
||||
assert(effectiveDeviceTypes.empty());
|
||||
assert(!getAsyncAttr());
|
||||
assert(!getAsyncOperand());
|
||||
|
||||
setAsyncAttr(mlir::UnitAttr::get(context));
|
||||
}
|
||||
|
||||
void ExitDataOp::addAsyncOperand(
|
||||
MLIRContext *context, mlir::Value newValue,
|
||||
llvm::ArrayRef<DeviceType> effectiveDeviceTypes) {
|
||||
assert(effectiveDeviceTypes.empty());
|
||||
assert(!getAsyncAttr());
|
||||
assert(!getAsyncOperand());
|
||||
|
||||
getAsyncOperandMutable().append(newValue);
|
||||
}
|
||||
|
||||
void ExitDataOp::addWaitOnly(MLIRContext *context,
|
||||
llvm::ArrayRef<DeviceType> effectiveDeviceTypes) {
|
||||
assert(effectiveDeviceTypes.empty());
|
||||
assert(!getWaitAttr());
|
||||
assert(getWaitOperands().empty());
|
||||
assert(!getWaitDevnum());
|
||||
|
||||
setWaitAttr(mlir::UnitAttr::get(context));
|
||||
}
|
||||
|
||||
void ExitDataOp::addWaitOperands(
|
||||
MLIRContext *context, bool hasDevnum, mlir::ValueRange newValues,
|
||||
llvm::ArrayRef<DeviceType> effectiveDeviceTypes) {
|
||||
assert(effectiveDeviceTypes.empty());
|
||||
assert(!getWaitAttr());
|
||||
assert(getWaitOperands().empty());
|
||||
assert(!getWaitDevnum());
|
||||
|
||||
// if hasDevnum, the first value is the devnum. The 'rest' go into the
|
||||
// operands list.
|
||||
if (hasDevnum) {
|
||||
getWaitDevnumMutable().append(newValues.front());
|
||||
newValues = newValues.drop_front();
|
||||
}
|
||||
|
||||
getWaitOperandsMutable().append(newValues);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// EnterDataOp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user