Skip to content

Commit 5eb942e

Browse files
[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.
1 parent 334a576 commit 5eb942e

File tree

8 files changed

+108
-25
lines changed

8 files changed

+108
-25
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,6 +2867,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
28672867
!std::holds_alternative<clause::UseDevicePtr>(clause.u) &&
28682868
!std::holds_alternative<clause::InReduction>(clause.u) &&
28692869
!std::holds_alternative<clause::Mergeable>(clause.u) &&
2870+
!std::holds_alternative<clause::Untied>(clause.u) &&
28702871
!std::holds_alternative<clause::TaskReduction>(clause.u) &&
28712872
!std::holds_alternative<clause::Detach>(clause.u)) {
28722873
std::string name =

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,29 @@ class AssociatedLoopChecker {
213213
std::map<std::string, std::int64_t> constructNamesAndLevels_;
214214
};
215215

216+
// `OmpDesignatorChecker` is used to check if the designator
217+
// can appear within the OpenMP construct
218+
class OmpDesignatorChecker {
219+
public:
220+
OmpDesignatorChecker(SemanticsContext &context) : context_{context} {}
221+
222+
template <typename T> bool Pre(const T &) { return true; }
223+
template <typename T> void Post(const T &) {}
224+
225+
bool Pre(const parser::Name &name) {
226+
if (name.symbol->test(Symbol::Flag::OmpThreadprivate)) {
227+
// OpenMP 5.2: 5.2 threadprivate directive restriction
228+
context_.Say(name.source,
229+
"A THREADPRIVATE variable `%s` cannot appear in a UNTIED TASK region"_err_en_US,
230+
name.source);
231+
}
232+
return true;
233+
}
234+
235+
private:
236+
SemanticsContext &context_;
237+
};
238+
216239
bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) {
217240
unsigned version{context_.langOptions().OpenMPVersion};
218241
DirectiveContext &dirCtx = GetContext();
@@ -1164,6 +1187,16 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
11641187
HasInvalidWorksharingNesting(
11651188
beginDir.source, llvm::omp::nestedWorkshareErrSet);
11661189
break;
1190+
case llvm::omp::Directive::OMPD_task: {
1191+
const auto &clauses{std::get<parser::OmpClauseList>(beginBlockDir.t)};
1192+
for (const auto &clause : clauses.v) {
1193+
if (std::get_if<parser::OmpClause::Untied>(&clause.u)) {
1194+
OmpDesignatorChecker ompDesignatorChecker{context_};
1195+
parser::Walk(block, ompDesignatorChecker);
1196+
}
1197+
}
1198+
break;
1199+
}
11671200
default:
11681201
break;
11691202
}

flang/test/Lower/OpenMP/Todo/task_untied.f90

Lines changed: 0 additions & 13 deletions
This file was deleted.

flang/test/Lower/OpenMP/task.f90

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,27 @@ subroutine task_multiple_clauses()
235235
!$omp end task
236236
end subroutine task_multiple_clauses
237237

238+
!===============================================================================
239+
! `mergeable` clause
240+
!===============================================================================
241+
238242
subroutine task_mergeable()
239243
!CHECK: omp.task mergeable {
240244
!CHECK: omp.terminator
241245
!CHECK: }
242246
!$omp task mergeable
243247
!$omp end task
244248
end subroutine
249+
250+
!===============================================================================
251+
! `untied` clause
252+
!===============================================================================
253+
254+
!CHECK-LABEL: func.func @_QPomp_task_untied() {
255+
subroutine omp_task_untied()
256+
!CHECK: omp.task untied {
257+
!$omp task untied
258+
call foo()
259+
!CHECK: omp.terminator
260+
!$omp end task
261+
end subroutine omp_task_untied
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
! RUN: %python %S/../test_errors.py %s %flang %openmp_flags
2+
!
3+
! OpenMP 5.2: 5.2 threadprivate directive restriction
4+
5+
subroutine task_united01()
6+
integer, save :: var_01, var_02(2)
7+
real :: var_03
8+
common /c/ var_03
9+
10+
!$omp threadprivate(var_01, var_02)
11+
!$omp threadprivate(/c/)
12+
13+
!$omp task untied
14+
!ERROR: A THREADPRIVATE variable `var_01` cannot appear in a UNTIED TASK region
15+
var_01 = 10
16+
!ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region
17+
!ERROR: A THREADPRIVATE variable `var_01` cannot appear in a UNTIED TASK region
18+
var_02(1) = sum([var_01, 20])
19+
!$omp end task
20+
21+
!$omp task untied
22+
!ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region
23+
!ERROR: A THREADPRIVATE variable `var_02` cannot appear in a UNTIED TASK region
24+
var_02(2) = product(var_02)
25+
!ERROR: A THREADPRIVATE variable `var_03` cannot appear in a UNTIED TASK region
26+
var_03 = 3.14
27+
!$omp end task
28+
end subroutine task_united01

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
258258
checkAllocate(op, result);
259259
checkInReduction(op, result);
260260
checkPriority(op, result);
261-
checkUntied(op, result);
262261
})
263262
.Case([&](omp::TaskgroupOp op) {
264263
checkAllocate(op, result);
@@ -268,6 +267,10 @@ static LogicalResult checkImplementationStatus(Operation &op) {
268267
checkDepend(op, result);
269268
checkNowait(op, result);
270269
})
270+
.Case([&](omp::TaskloopOp op) {
271+
// TODO: Add other clauses check
272+
checkUntied(op, result);
273+
})
271274
.Case([&](omp::WsloopOp op) {
272275
checkAllocate(op, result);
273276
checkLinear(op, result);

mlir/test/Target/LLVMIR/openmp-llvm.mlir

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3020,6 +3020,18 @@ module attributes {omp.is_target_device = true} {
30203020

30213021
// -----
30223022

3023+
llvm.func @omp_task_untied() {
3024+
// The third argument is 0: which signifies the united task
3025+
// CHECK: {{.*}} = call ptr @__kmpc_omp_task_alloc(ptr @1, i32 %{{.*}}, i32 0,
3026+
// CHECK-SAME: i64 40, i64 0, ptr @{{.*}})
3027+
omp.task untied {
3028+
omp.terminator
3029+
}
3030+
llvm.return
3031+
}
3032+
3033+
// -----
3034+
30233035
// Third argument is 5: essentially (4 || 1)
30243036
// signifying this task is TIED and MERGEABLE
30253037

mlir/test/Target/LLVMIR/openmp-todo.mlir

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -440,17 +440,6 @@ llvm.func @task_priority(%x : i32) {
440440

441441
// -----
442442

443-
llvm.func @task_untied() {
444-
// expected-error@below {{not yet implemented: Unhandled clause untied in omp.task operation}}
445-
// expected-error@below {{LLVM Translation failed for operation: omp.task}}
446-
omp.task untied {
447-
omp.terminator
448-
}
449-
llvm.return
450-
}
451-
452-
// -----
453-
454443
llvm.func @taskgroup_allocate(%x : !llvm.ptr) {
455444
// expected-error@below {{not yet implemented: Unhandled clause allocate in omp.taskgroup operation}}
456445
// expected-error@below {{LLVM Translation failed for operation: omp.taskgroup}}
@@ -503,6 +492,19 @@ llvm.func @taskloop(%lb : i32, %ub : i32, %step : i32) {
503492

504493
// -----
505494

495+
llvm.func @taskloop_untied(%lb : i32, %ub : i32, %step : i32) {
496+
// expected-error@below {{not yet implemented: omp.taskloop}}
497+
// expected-error@below {{LLVM Translation failed for operation: omp.taskloop}}
498+
omp.taskloop untied {
499+
omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
500+
omp.yield
501+
}
502+
}
503+
llvm.return
504+
}
505+
506+
// -----
507+
506508
llvm.func @taskwait_depend(%x: !llvm.ptr) {
507509
// expected-error@below {{not yet implemented: Unhandled clause depend in omp.taskwait operation}}
508510
// expected-error@below {{LLVM Translation failed for operation: omp.taskwait}}

0 commit comments

Comments
 (0)