From e7361469bbb64d80a70d23bb24d45402b4644e3e Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 3 Feb 2022 15:03:58 +0100 Subject: [PATCH] [fir] Add fir.array_amend operation definition This patch adds the fir.array_amend operation. this op is used later in upstreaming patches for the F95 compliance. The `array_amend` operation marks an array value as having been changed via a reference obtain by an `array_access`. It acts as a logical transaction log that is used to merge the final result back with an `array_merge_store` operation. ```mlir // fetch the value of one of the array value's elements %1 = fir.array_access %v, %i, %j : (!fir.array, index, index) -> !fir.ref // modify the element by storing data using %1 as a reference %2 = ... %1 ... // mark the array value %new_v = fir.array_amend %v, %2 : (!fir.array, !fir.ref) -> !fir.array ``` This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: kiranchandramohan, schweitz Differential Revision: https://reviews.llvm.org/D112448 Co-authored-by: Eric Schweitz --- flang/include/flang/Optimizer/Dialect/FIROps.td | 34 +++++++++++++++++++++++++ flang/test/Fir/fir-ops.fir | 12 +++++++++ 2 files changed, 46 insertions(+) diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 2bb6e2a..e79fafa 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -1595,6 +1595,40 @@ def fir_ArrayAccessOp : fir_Op<"array_access", [AttrSizedOperandSegments, let verifier = "return ::verify(*this);"; } +def fir_ArrayAmendOp : fir_Op<"array_amend", [NoSideEffect]> { + let summary = "Mark an array value as having been changed by reference."; + + let description = [{ + The `array_amend` operation marks an array value as having been changed via + a reference obtained by an `array_access`. It acts as a logical transaction + log that is used to merge the final result back with an `array_merge_store` + operation. + + ```mlir + // fetch the value of one of the array value's elements + %1 = fir.array_access %v, %i, %j : (!fir.array, index, index) -> !fir.ref + // modify the element by storing data using %1 as a reference + %2 = ... %1 ... + // mark the array value + %new_v = fir.array_amend %v, %2 : (!fir.array, !fir.ref) -> !fir.array + ``` + + More information about `array_amend` and other array operations can be + found in flang/docs/FIRArrayOperations.md. + }]; + + let arguments = (ins + fir_SequenceType:$sequence, + fir_ReferenceType:$memref + ); + + let results = (outs fir_SequenceType); + + let assemblyFormat = [{ + $sequence `,` $memref attr-dict `:` functional-type(operands, results) + }]; +} + def fir_ArrayMergeStoreOp : fir_Op<"array_merge_store", [AttrSizedOperandSegments]> { diff --git a/flang/test/Fir/fir-ops.fir b/flang/test/Fir/fir-ops.fir index 3238e4e..38ec7ff 100644 --- a/flang/test/Fir/fir-ops.fir +++ b/flang/test/Fir/fir-ops.fir @@ -758,3 +758,15 @@ func @array_access_ops(%a : !fir.ref>) { // CHECK: %{{.*}} = fir.array_access %{{.*}}, %{{.*}}, %{{.*}} : (!fir.array, index, index) -> !fir.ref return } + +func @array_amend_ops(%a : !fir.ref>) { + %c1 = arith.constant 1 : index + %n = arith.constant 0 : index + %m = arith.constant 50 : index + %s = fir.shape %n, %m : (index, index) -> !fir.shape<2> + %v = fir.array_load %a(%s) : (!fir.ref>, !fir.shape<2>) -> !fir.array + %p = fir.array_access %v, %c1, %c1 : (!fir.array, index, index) -> !fir.ref + %res = fir.array_amend %v, %p : (!fir.array, !fir.ref) -> !fir.array + // CHECK: %{{.*}} = fir.array_amend %{{.*}}, %{{.*}} : (!fir.array, !fir.ref) -> !fir.array + return +} -- 2.7.4