[flang-commits] [flang] e4ebe14 - [mlir][OpenMP] Add nontemporal clause definition to simd construct
Dominik Adamski via flang-commits
flang-commits at lists.llvm.org
Thu Jan 19 03:50:59 PST 2023
Author: Dominik Adamski
Date: 2023-01-19T05:41:50-06:00
New Revision: e4ebe14fd16f9aa3ec38ccad3297636e23c7f40d
URL: https://github.com/llvm/llvm-project/commit/e4ebe14fd16f9aa3ec38ccad3297636e23c7f40d
DIFF: https://github.com/llvm/llvm-project/commit/e4ebe14fd16f9aa3ec38ccad3297636e23c7f40d.diff
LOG: [mlir][OpenMP] Add nontemporal clause definition to simd construct
simd nontemporal construct is represented as a list of variables
which have low locality accross simd iterations
Added verifier of nontemporal clause. MLIR tests were updated to test
correctness of MLIR definition of nontemporal clause.
Differential Revision: https://reviews.llvm.org/D140553
Reviewed By: kiranchandramohan
Added:
Modified:
flang/lib/Lower/OpenMP.cpp
mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
mlir/test/Dialect/OpenMP/invalid.mlir
mlir/test/Dialect/OpenMP/ops.mlir
mlir/test/Target/LLVMIR/openmp-llvm.mlir
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 7abb7c967373f..8e13c24ff9364 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -1054,7 +1054,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
mlir::Location currentLocation = converter.getCurrentLocation();
llvm::SmallVector<mlir::Value> lowerBound, upperBound, step, linearVars,
- linearStepVars, reductionVars, alignedVars;
+ linearStepVars, reductionVars, alignedVars, nontemporalVars;
mlir::Value scheduleChunkClauseOperand, ifClauseOperand;
mlir::Attribute scheduleClauseOperand, noWaitClauseOperand,
orderedClauseOperand, orderClauseOperand;
@@ -1214,7 +1214,7 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
TypeRange resultType;
auto SimdLoopOp = firOpBuilder.create<mlir::omp::SimdLoopOp>(
currentLocation, resultType, lowerBound, upperBound, step, alignedVars,
- nullptr, ifClauseOperand,
+ nullptr, ifClauseOperand, nontemporalVars,
orderClauseOperand.dyn_cast_or_null<omp::ClauseOrderKindAttr>(),
simdlenClauseOperand, safelenClauseOperand,
/*inclusive=*/firOpBuilder.getUnitAttr());
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
index 6bb111b81b87c..af02e79dd6950 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td
@@ -394,6 +394,9 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
iterations to be executed concurrently is one, regardless of whether
a simdlen clause is speciļ¬ed.
+ The optional `nontemporal` attribute specifies variables which have low
+ temporal locality across the iterations where they are accessed.
+
The optional `order` attribute specifies which order the iterations of the
associate loops are executed in. Currently the only option for this
attribute is "concurrent".
@@ -420,6 +423,7 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
Variadic<OpenMP_PointerLikeType>:$aligned_vars,
OptionalAttr<I64ArrayAttr>:$alignment_values,
Optional<I1>:$if_expr,
+ Variadic<OpenMP_PointerLikeType>:$nontemporal_vars,
OptionalAttr<OrderKindAttr>:$order_val,
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$simdlen,
ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$safelen,
@@ -432,6 +436,7 @@ def SimdLoopOp : OpenMP_Op<"simdloop", [AttrSizedOperandSegments,
custom<AlignedClause>($aligned_vars, type($aligned_vars),
$alignment_values) `)`
|`if` `(` $if_expr `)`
+ |`nontemporal` `(` $nontemporal_vars `:` type($nontemporal_vars) `)`
|`order` `(` custom<ClauseAttr>($order_val) `)`
|`simdlen` `(` $simdlen `)`
|`safelen` `(` $safelen `)`
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 0ae13e412924b..daa7ff8091c6d 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -170,6 +170,22 @@ static void printLinearClause(OpAsmPrinter &p, Operation *op,
}
}
+//===----------------------------------------------------------------------===//
+// Verifier for Nontemporal Clause
+//===----------------------------------------------------------------------===//
+
+static LogicalResult
+verifyNontemporalClause(Operation *op, OperandRange nontemporalVariables) {
+
+ // Check if each var is unique - OpenMP 5.0 -> 2.9.3.1 section
+ DenseSet<Value> nontemporalItems;
+ for (const auto &it : nontemporalVariables)
+ if (!nontemporalItems.insert(it).second)
+ return op->emitOpError() << "nontemporal variable used more than once";
+
+ return success();
+}
+
//===----------------------------------------------------------------------===//
// Parser, verifier and printer for Aligned Clause
//===----------------------------------------------------------------------===//
@@ -658,8 +674,13 @@ LogicalResult SimdLoopOp::verify() {
<< "simdlen clause and safelen clause are both present, but the "
"simdlen value is not less than or equal to safelen value";
}
- return verifyAlignedClause(*this, this->getAlignmentValues(),
- this->getAlignedVars());
+ if (verifyAlignedClause(*this, this->getAlignmentValues(),
+ this->getAlignedVars())
+ .failed())
+ return failure();
+ if (verifyNontemporalClause(*this, this->getNontemporalVars()).failed())
+ return failure();
+ return success();
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/OpenMP/invalid.mlir b/mlir/test/Dialect/OpenMP/invalid.mlir
index 58d6a28c7a7e9..9d6999db12ab7 100644
--- a/mlir/test/Dialect/OpenMP/invalid.mlir
+++ b/mlir/test/Dialect/OpenMP/invalid.mlir
@@ -197,7 +197,7 @@ func.func @omp_simdloop(%lb : index, %ub : index, %step : i32) -> () {
"omp.simdloop" (%lb, %ub, %step) ({
^bb0(%iv: index):
omp.yield
- }) {operand_segment_sizes = array<i32: 1,1,1,0,0>} :
+ }) {operand_segment_sizes = array<i32: 1,1,1,0,0,0>} :
(index, index, i32) -> ()
return
@@ -225,7 +225,7 @@ func.func @omp_simdloop_aligned_mismatch(%arg0 : index, %arg1 : index,
^bb0(%arg5: index):
"omp.yield"() : () -> ()
}) {alignment_values = [128],
- operand_segment_sizes = array<i32: 1, 1, 1, 2, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
+ operand_segment_sizes = array<i32: 1, 1, 1, 2, 0, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
return
}
@@ -238,7 +238,7 @@ func.func @omp_simdloop_aligned_negative(%arg0 : index, %arg1 : index,
"omp.simdloop"(%arg0, %arg1, %arg2, %arg3, %arg4) ({
^bb0(%arg5: index):
"omp.yield"() : () -> ()
- }) {alignment_values = [-1, 128], operand_segment_sizes = array<i32: 1, 1, 1,2, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
+ }) {alignment_values = [-1, 128], operand_segment_sizes = array<i32: 1, 1, 1,2, 0, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
return
}
@@ -251,7 +251,7 @@ func.func @omp_simdloop_unexpected_alignment(%arg0 : index, %arg1 : index,
"omp.simdloop"(%arg0, %arg1, %arg2) ({
^bb0(%arg5: index):
"omp.yield"() : () -> ()
- }) {alignment_values = [1, 128], operand_segment_sizes = array<i32: 1, 1, 1, 0, 0>} : (index, index, index) -> ()
+ }) {alignment_values = [1, 128], operand_segment_sizes = array<i32: 1, 1, 1, 0, 0, 0>} : (index, index, index) -> ()
return
}
@@ -264,7 +264,7 @@ func.func @omp_simdloop_aligned_float(%arg0 : index, %arg1 : index,
"omp.simdloop"(%arg0, %arg1, %arg2, %arg3, %arg4) ({
^bb0(%arg5: index):
"omp.yield"() : () -> ()
- }) {alignment_values = [1.5, 128], operand_segment_sizes = array<i32: 1, 1, 1,2, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
+ }) {alignment_values = [1.5, 128], operand_segment_sizes = array<i32: 1, 1, 1,2, 0, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
return
}
@@ -277,7 +277,21 @@ func.func @omp_simdloop_aligned_the_same_var(%arg0 : index, %arg1 : index,
"omp.simdloop"(%arg0, %arg1, %arg2, %arg3, %arg3) ({
^bb0(%arg5: index):
"omp.yield"() : () -> ()
- }) {alignment_values = [1, 128], operand_segment_sizes = array<i32: 1, 1, 1,2, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
+ }) {alignment_values = [1, 128], operand_segment_sizes = array<i32: 1, 1, 1,2, 0, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
+ return
+}
+
+// -----
+
+func.func @omp_simdloop_nontemporal_the_same_var(%arg0 : index,
+ %arg1 : index,
+ %arg2 : index,
+ %arg3 : memref<i32>) -> () {
+ // expected-error @below {{nontemporal variable used more than once}}
+ "omp.simdloop"(%arg0, %arg1, %arg2, %arg3, %arg3) ({
+ ^bb0(%arg5: index):
+ "omp.yield"() : () -> ()
+ }) {operand_segment_sizes = array<i32: 1, 1, 1, 0, 0, 2>} : (index, index, index, memref<i32>, memref<i32>) -> ()
return
}
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 0957fb5524b0d..44b489a6da34e 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -333,7 +333,7 @@ func.func @omp_simdloop(%lb : index, %ub : index, %step : index) -> () {
"omp.simdloop" (%lb, %ub, %step) ({
^bb0(%iv: index):
omp.yield
- }) {operand_segment_sizes = array<i32: 1,1,1,0,0>} :
+ }) {operand_segment_sizes = array<i32: 1,1,1,0,0,0>} :
(index, index, index) -> ()
return
@@ -349,7 +349,7 @@ func.func @omp_simdloop_aligned_list(%arg0 : index, %arg1 : index, %arg2 : index
^bb0(%arg5: index):
"omp.yield"() : () -> ()
}) {alignment_values = [32, 128],
- operand_segment_sizes = array<i32: 1, 1, 1,2, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
+ operand_segment_sizes = array<i32: 1, 1, 1, 2, 0, 0>} : (index, index, index, memref<i32>, memref<i32>) -> ()
return
}
@@ -362,7 +362,37 @@ func.func @omp_simdloop_aligned_single(%arg0 : index, %arg1 : index, %arg2 : ind
^bb0(%arg5: index):
"omp.yield"() : () -> ()
}) {alignment_values = [32],
- operand_segment_sizes = array<i32: 1, 1, 1,1, 0>} : (index, index, index, memref<i32>) -> ()
+ operand_segment_sizes = array<i32: 1, 1, 1, 1, 0, 0>} : (index, index, index, memref<i32>) -> ()
+ return
+}
+
+// CHECK-LABEL: omp_simdloop_nontemporal_list
+func.func @omp_simdloop_nontemporal_list(%arg0 : index,
+ %arg1 : index,
+ %arg2 : index,
+ %arg3 : memref<i32>,
+ %arg4 : memref<i64>) -> () {
+ // CHECK: omp.simdloop nontemporal(%{{.*}}, %{{.*}} : memref<i32>, memref<i64>)
+ // CHECK-SAME: for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {
+ "omp.simdloop"(%arg0, %arg1, %arg2, %arg3, %arg4) ({
+ ^bb0(%arg5: index):
+ "omp.yield"() : () -> ()
+ }) {operand_segment_sizes = array<i32: 1, 1, 1, 0, 0, 2>} : (index, index, index, memref<i32>, memref<i64>) -> ()
+ return
+}
+
+// CHECK-LABEL: omp_simdloop_nontemporal_single
+func.func @omp_simdloop_nontemporal_single(%arg0 : index,
+ %arg1 : index,
+ %arg2 : index,
+ %arg3 : memref<i32>,
+ %arg4 : memref<i64>) -> () {
+ // CHECK: omp.simdloop nontemporal(%{{.*}} : memref<i32>)
+ // CHECK-SAME: for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {
+ "omp.simdloop"(%arg0, %arg1, %arg2, %arg3) ({
+ ^bb0(%arg5: index):
+ "omp.yield"() : () -> ()
+ }) {operand_segment_sizes = array<i32: 1, 1, 1, 0, 0, 1>} : (index, index, index, memref<i32>) -> ()
return
}
@@ -398,6 +428,20 @@ func.func @omp_simdloop_pretty_if(%lb : index, %ub : index, %step : index, %if_c
return
}
+// CHECK-LABEL: func.func @omp_simdloop_pretty_nontemporal
+func.func @omp_simdloop_pretty_nontemporal(%lb : index,
+ %ub : index,
+ %step : index,
+ %data_var : memref<i32>,
+ %data_var1 : memref<i32>) -> () {
+ // CHECK: omp.simdloop nontemporal(%{{.*}}, %{{.*}} : memref<i32>, memref<i32>)
+ // CHECK-SAME: for (%{{.*}}) : index = (%{{.*}}) to (%{{.*}}) step (%{{.*}}) {
+ omp.simdloop nontemporal(%data_var, %data_var1 : memref<i32>, memref<i32>)
+ for (%iv) : index = (%lb) to (%ub) step (%step) {
+ omp.yield
+ }
+ return
+}
// CHECK-LABEL: omp_simdloop_pretty_order
func.func @omp_simdloop_pretty_order(%lb : index, %ub : index, %step : index) -> () {
// CHECK: omp.simdloop order(concurrent)
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index 31009e4a02ea0..ab2146329af51 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -628,7 +628,7 @@ llvm.func @simdloop_simple(%lb : i64, %ub : i64, %step : i64, %arg0: !llvm.ptr<f
%4 = llvm.getelementptr %arg0[%iv] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>
llvm.store %3, %4 : !llvm.ptr<f32>
omp.yield
- }) {operand_segment_sizes = array<i32: 1,1,1,0,0>} :
+ }) {operand_segment_sizes = array<i32: 1,1,1,0,0,0>} :
(i64, i64, i64) -> ()
llvm.return
More information about the flang-commits
mailing list