[flang-commits] [flang] [mlir] [Flang][OpenMP] Add LLVM translation support for UNTIED clause in Task (PR #121052)
Thirumalai Shaktivel via flang-commits
flang-commits at lists.llvm.org
Tue Dec 24 07:33:41 PST 2024
https://github.com/Thirumalai-Shaktivel updated https://github.com/llvm/llvm-project/pull/121052
>From 5eb942e4c56de1ce7666a080900496d8c67b85b3 Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Tue, 24 Dec 2024 15:14:44 +0000
Subject: [PATCH 1/2] [Flang] Add a semantic check and LLVM Lowering support
for UNTIED TASK
Implementation details:
The UNTIED clause is recognized by setting the flag=0 for the default
case or performing logical OR to flag if other clauses are specified,
and this flag is passed as an argument to the `__kmpc_omp_task_alloc`
runtime call.
---
flang/lib/Lower/OpenMP/OpenMP.cpp | 1 +
flang/lib/Semantics/check-omp-structure.cpp | 33 +++++++++++++++++++
flang/test/Lower/OpenMP/Todo/task_untied.f90 | 13 --------
flang/test/Lower/OpenMP/task.f90 | 17 ++++++++++
flang/test/Semantics/OpenMP/task-united01.f90 | 28 ++++++++++++++++
.../OpenMP/OpenMPToLLVMIRTranslation.cpp | 5 ++-
mlir/test/Target/LLVMIR/openmp-llvm.mlir | 12 +++++++
mlir/test/Target/LLVMIR/openmp-todo.mlir | 24 +++++++-------
8 files changed, 108 insertions(+), 25 deletions(-)
delete mode 100644 flang/test/Lower/OpenMP/Todo/task_untied.f90
create mode 100644 flang/test/Semantics/OpenMP/task-united01.f90
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index b07e89d201d198..4de5ecf187a4cb 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -2867,6 +2867,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
!std::holds_alternative<clause::UseDevicePtr>(clause.u) &&
!std::holds_alternative<clause::InReduction>(clause.u) &&
!std::holds_alternative<clause::Mergeable>(clause.u) &&
+ !std::holds_alternative<clause::Untied>(clause.u) &&
!std::holds_alternative<clause::TaskReduction>(clause.u) &&
!std::holds_alternative<clause::Detach>(clause.u)) {
std::string name =
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 95b962f5daf57c..5fbe8f8a577cfd 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -213,6 +213,29 @@ class AssociatedLoopChecker {
std::map<std::string, std::int64_t> constructNamesAndLevels_;
};
+// `OmpDesignatorChecker` is used to check if the designator
+// can appear within the OpenMP construct
+class OmpDesignatorChecker {
+public:
+ OmpDesignatorChecker(SemanticsContext &context) : context_{context} {}
+
+ template <typename T> bool Pre(const T &) { return true; }
+ template <typename T> void Post(const T &) {}
+
+ bool Pre(const parser::Name &name) {
+ if (name.symbol->test(Symbol::Flag::OmpThreadprivate)) {
+ // OpenMP 5.2: 5.2 threadprivate directive restriction
+ context_.Say(name.source,
+ "A THREADPRIVATE variable `%s` cannot appear in a UNTIED TASK region"_err_en_US,
+ name.source);
+ }
+ return true;
+ }
+
+private:
+ SemanticsContext &context_;
+};
+
bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
unsigned version{context_.langOptions().OpenMPVersion};
DirectiveContext &dirCtx = GetContext();
@@ -1164,6 +1187,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginDir.source, llvm::omp::nestedWorkshareErrSet);
break;
+ case llvm::omp::Directive::OMPD_task: {
+ const auto &clauses{std::get<parser::OmpClauseList>(beginBlockDir.t)};
+ for (const auto &clause : clauses.v) {
+ if (std::get_if<parser::OmpClause::Untied>(&clause.u)) {
+ OmpDesignatorChecker ompDesignatorChecker{context_};
+ parser::Walk(block, ompDesignatorChecker);
+ }
+ }
+ break;
+ }
default:
break;
}
diff --git a/flang/test/Lower/OpenMP/Todo/task_untied.f90 b/flang/test/Lower/OpenMP/Todo/task_untied.f90
deleted file mode 100644
index 87d242ba3e9d21..00000000000000
--- a/flang/test/Lower/OpenMP/Todo/task_untied.f90
+++ /dev/null
@@ -1,13 +0,0 @@
-! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s
-
-!===============================================================================
-! `untied` clause
-!===============================================================================
-
-! CHECK: not yet implemented: UNTIED clause is not implemented yet
-subroutine omp_task_untied()
- !$omp task untied
- call foo()
- !$omp end task
-end subroutine omp_task_untied
diff --git a/flang/test/Lower/OpenMP/task.f90 b/flang/test/Lower/OpenMP/task.f90
index 6e525a044b011e..a8cc16c540c9c8 100644
--- a/flang/test/Lower/OpenMP/task.f90
+++ b/flang/test/Lower/OpenMP/task.f90
@@ -235,6 +235,10 @@ subroutine task_multiple_clauses()
!$omp end task
end subroutine task_multiple_clauses
+!===============================================================================
+! `mergeable` clause
+!===============================================================================
+
subroutine task_mergeable()
!CHECK: omp.task mergeable {
!CHECK: omp.terminator
@@ -242,3 +246,16 @@ subroutine task_mergeable()
!$omp task mergeable
!$omp end task
end subroutine
+
+!===============================================================================
+! `untied` clause
+!===============================================================================
+
+!CHECK-LABEL: func.func @_QPomp_task_untied() {
+subroutine omp_task_untied()
+ !CHECK: omp.task untied {
+ !$omp task untied
+ call foo()
+ !CHECK: omp.terminator
+ !$omp end task
+end subroutine omp_task_untied
diff --git a/flang/test/Semantics/OpenMP/task-united01.f90 b/flang/test/Semantics/OpenMP/task-united01.f90
new file mode 100644
index 00000000000000..11227c0e919aa5
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/task-united01.f90
@@ -0,0 +1,28 @@
+! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
+!
+! OpenMP 5.2: 5.2 threadprivate directive restriction
+
+subroutine task_united01()
+ integer, save :: var_01, var_02(2)
+ real :: var_03
+ common /c/ var_03
+
+ !$omp threadprivate(var_01, var_02)
+ !$omp threadprivate(/c/)
+
+ !$omp task untied
+ !ERROR: A THREADPRIVATE variable `var_01` cannot appear in a UNTIED TASK region
+ var_01 = 10
+ !ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region
+ !ERROR: A THREADPRIVATE variable `var_01` cannot appear in a UNTIED TASK region
+ var_02(1) = sum([var_01, 20])
+ !$omp end task
+
+ !$omp task untied
+ !ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region
+ !ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region
+ var_02(2) = product(var_02)
+ !ERROR: A THREADPRIVATE variable `var_03` cannot appear in a UNTIED TASK region
+ var_03 = 3.14
+ !$omp end task
+end subroutine task_united01
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index 060113c4123241..d591c98a5497f8 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -258,7 +258,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
checkAllocate(op, result);
checkInReduction(op, result);
checkPriority(op, result);
- checkUntied(op, result);
})
.Case([&](omp::TaskgroupOp op) {
checkAllocate(op, result);
@@ -268,6 +267,10 @@ static LogicalResult checkImplementationStatus(Operation &op) {
checkDepend(op, result);
checkNowait(op, result);
})
+ .Case([&](omp::TaskloopOp op) {
+ // TODO: Add other clauses check
+ checkUntied(op, result);
+ })
.Case([&](omp::WsloopOp op) {
checkAllocate(op, result);
checkLinear(op, result);
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index 5f8bdf8afdf783..8903bf283b5c75 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -3020,6 +3020,18 @@ module attributes {omp.is_target_device = true} {
// -----
+llvm.func @omp_task_untied() {
+ // The third argument is 0: which signifies the united task
+ // CHECK: {{.*}} = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 %{{.*}}, i32 0,
+ // CHECK-SAME: i64 40, i64 0, ptr @{{.*}})
+ omp.task untied {
+ omp.terminator
+ }
+ llvm.return
+}
+
+// -----
+
// Third argument is 5: essentially (4 || 1)
// signifying this task is TIED and MERGEABLE
diff --git a/mlir/test/Target/LLVMIR/openmp-todo.mlir b/mlir/test/Target/LLVMIR/openmp-todo.mlir
index 8f3e466cfbbeb6..8ae795ec1ec6b0 100644
--- a/mlir/test/Target/LLVMIR/openmp-todo.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-todo.mlir
@@ -440,17 +440,6 @@ llvm.func @task_priority(%x : i32) {
// -----
-llvm.func @task_untied() {
- // expected-error at below {{not yet implemented: Unhandled clause untied in omp.task operation}}
- // expected-error at below {{LLVM Translation failed for operation: omp.task}}
- omp.task untied {
- omp.terminator
- }
- llvm.return
-}
-
-// -----
-
llvm.func @taskgroup_allocate(%x : !llvm.ptr) {
// expected-error at below {{not yet implemented: Unhandled clause allocate in omp.taskgroup operation}}
// expected-error at below {{LLVM Translation failed for operation: omp.taskgroup}}
@@ -503,6 +492,19 @@ llvm.func @taskloop(%lb : i32, %ub : i32, %step : i32) {
// -----
+llvm.func @taskloop_untied(%lb : i32, %ub : i32, %step : i32) {
+ // expected-error at below {{not yet implemented: omp.taskloop}}
+ // expected-error at below {{LLVM Translation failed for operation: omp.taskloop}}
+ omp.taskloop untied {
+ omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
+ omp.yield
+ }
+ }
+ llvm.return
+}
+
+// -----
+
llvm.func @taskwait_depend(%x: !llvm.ptr) {
// expected-error at below {{not yet implemented: Unhandled clause depend in omp.taskwait operation}}
// expected-error at below {{LLVM Translation failed for operation: omp.taskwait}}
>From d77eae01c1ec6bb0b857a36bf835cf1e6ad985df Mon Sep 17 00:00:00 2001
From: Thirumalai-Shaktivel <thirumalaishaktivel at gmail.com>
Date: Tue, 24 Dec 2024 15:33:10 +0000
Subject: [PATCH 2/2] Add `!REQUIRES: openmp_runtime` for the test
---
flang/test/Semantics/OpenMP/task-united01.f90 | 1 +
1 file changed, 1 insertion(+)
diff --git a/flang/test/Semantics/OpenMP/task-united01.f90 b/flang/test/Semantics/OpenMP/task-united01.f90
index 11227c0e919aa5..e192327bee281b 100644
--- a/flang/test/Semantics/OpenMP/task-united01.f90
+++ b/flang/test/Semantics/OpenMP/task-united01.f90
@@ -1,3 +1,4 @@
+! REQUIRES: openmp_runtime
! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
!
! OpenMP 5.2: 5.2 threadprivate directive restriction
More information about the flang-commits
mailing list