Skip to content

Commit f26a373

Browse files
committed
[mlir][llvm] Translation support for task detach
1 parent 20c653c commit f26a373

File tree

9 files changed

+85
-13
lines changed

9 files changed

+85
-13
lines changed

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1262,12 +1262,15 @@ class OpenMPIRBuilder {
12621262
/// cannot be resumed until execution of the structured
12631263
/// block that is associated with the generated task is
12641264
/// completed.
1265+
/// \param EventHandle If present, signifies the event handle as part of
1266+
/// the detach clause
12651267
InsertPointOrErrorTy createTask(const LocationDescription &Loc,
12661268
InsertPointTy AllocaIP,
12671269
BodyGenCallbackTy BodyGenCB, bool Tied = true,
12681270
Value *Final = nullptr,
12691271
Value *IfCondition = nullptr,
1270-
SmallVector<DependData> Dependencies = {});
1272+
SmallVector<DependData> Dependencies = {},
1273+
Value *EventHandle = nullptr);
12711274

12721275
/// Generator for the taskgroup construct
12731276
///

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,11 +1816,10 @@ static Value *emitTaskDependencies(
18161816
return DepArray;
18171817
}
18181818

1819-
OpenMPIRBuilder::InsertPointOrErrorTy
1820-
OpenMPIRBuilder::createTask(const LocationDescription &Loc,
1821-
InsertPointTy AllocaIP, BodyGenCallbackTy BodyGenCB,
1822-
bool Tied, Value *Final, Value *IfCondition,
1823-
SmallVector<DependData> Dependencies) {
1819+
OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
1820+
const LocationDescription &Loc, InsertPointTy AllocaIP,
1821+
BodyGenCallbackTy BodyGenCB, bool Tied, Value *Final, Value *IfCondition,
1822+
SmallVector<DependData> Dependencies, Value *EventHandle) {
18241823

18251824
if (!updateToLocation(Loc))
18261825
return InsertPointTy();
@@ -1866,7 +1865,8 @@ OpenMPIRBuilder::createTask(const LocationDescription &Loc,
18661865
Builder, AllocaIP, ToBeDeleted, TaskAllocaIP, "global.tid", false));
18671866

18681867
OI.PostOutlineCB = [this, Ident, Tied, Final, IfCondition, Dependencies,
1869-
TaskAllocaBB, ToBeDeleted](Function &OutlinedFn) mutable {
1868+
EventHandle, TaskAllocaBB,
1869+
ToBeDeleted](Function &OutlinedFn) mutable {
18701870
// Replace the Stale CI by appropriate RTL function call.
18711871
assert(OutlinedFn.getNumUses() == 1 &&
18721872
"there must be a single user for the outlined function");
@@ -1930,6 +1930,20 @@ OpenMPIRBuilder::createTask(const LocationDescription &Loc,
19301930
TaskAllocFn, {/*loc_ref=*/Ident, /*gtid=*/ThreadID, /*flags=*/Flags,
19311931
/*sizeof_task=*/TaskSize, /*sizeof_shared=*/SharedsSize,
19321932
/*task_func=*/&OutlinedFn});
1933+
// Emit detach clause initialization.
1934+
// evt = (typeof(evt))__kmpc_task_allow_completion_event(loc, tid,
1935+
// task_descriptor);
1936+
if (EventHandle) {
1937+
Function *TaskDetachFn = getOrCreateRuntimeFunctionPtr(
1938+
OMPRTL___kmpc_task_allow_completion_event);
1939+
llvm::Value *EventVal =
1940+
Builder.CreateCall(TaskDetachFn, {Ident, ThreadID, TaskData});
1941+
llvm::Value *EventHandleAddr =
1942+
Builder.CreatePointerBitCastOrAddrSpaceCast(EventHandle,
1943+
Builder.getPtrTy(0));
1944+
EventVal = Builder.CreatePtrToInt(EventVal, Builder.getInt64Ty());
1945+
Builder.CreateStore(EventVal, EventHandleAddr);
1946+
}
19331947

19341948
// Copy the arguments for outlined function
19351949
if (HasShareds) {

mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,37 @@ class OpenMP_ParallelizationLevelClauseSkip<
909909

910910
def OpenMP_ParallelizationLevelClause : OpenMP_ParallelizationLevelClauseSkip<>;
911911

912+
//===----------------------------------------------------------------------===//
913+
// OpenMPV5.2: [12.5.2] `detach` clause
914+
//===----------------------------------------------------------------------===//
915+
916+
class OpenMP_DetachClauseSkip<
917+
bit traits = false, bit arguments = false, bit assemblyFormat = false,
918+
bit description = false, bit extraClassDeclaration = false
919+
> : OpenMP_Clause<traits, arguments, assemblyFormat, description, extraClassDeclaration> {
920+
921+
let traits = [
922+
BlockArgOpenMPOpInterface
923+
];
924+
925+
let arguments = (ins
926+
Optional<OpenMP_PointerLikeType>:$event_handle
927+
);
928+
929+
let optAssemblyFormat = [{
930+
`detach` `(` $event_handle `:` type($event_handle) `)`
931+
}];
932+
933+
let description = [{
934+
The detach clause specifies that the task generated by the construct on which it appears is a
935+
detachable task. A new allow-completion event is created and connected to the completion of the
936+
associated task region. The original event-handle is updated to represent that allow-completion
937+
event before the task data environment is created.
938+
}];
939+
}
940+
941+
def OpenMP_DetachClause : OpenMP_DetachClauseSkip<>;
942+
912943
//===----------------------------------------------------------------------===//
913944
// V5.2: [12.4] `priority` clause
914945
//===----------------------------------------------------------------------===//

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ def TaskOp : OpenMP_Op<"task", traits = [
621621
// TODO: Complete clause list (affinity, detach).
622622
OpenMP_AllocateClause, OpenMP_DependClause, OpenMP_FinalClause,
623623
OpenMP_IfClause, OpenMP_InReductionClause, OpenMP_MergeableClause,
624-
OpenMP_PriorityClause, OpenMP_PrivateClause, OpenMP_UntiedClause
624+
OpenMP_PriorityClause, OpenMP_PrivateClause, OpenMP_UntiedClause, OpenMP_DetachClause
625625
], singleRegion = true> {
626626
let summary = "task construct";
627627
let description = [{

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2215,7 +2215,7 @@ void TaskOp::build(OpBuilder &builder, OperationState &state,
22152215
makeArrayAttr(ctx, clauses.inReductionSyms), clauses.mergeable,
22162216
clauses.priority, /*private_vars=*/clauses.privateVars,
22172217
/*private_syms=*/makeArrayAttr(ctx, clauses.privateSyms),
2218-
clauses.untied);
2218+
clauses.untied, clauses.eventHandle);
22192219
}
22202220

22212221
LogicalResult TaskOp::verify() {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,8 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
16651665
moduleTranslation.getOpenMPBuilder()->createTask(
16661666
ompLoc, allocaIP, bodyCB, !taskOp.getUntied(),
16671667
moduleTranslation.lookupValue(taskOp.getFinal()),
1668-
moduleTranslation.lookupValue(taskOp.getIfExpr()), dds);
1668+
moduleTranslation.lookupValue(taskOp.getIfExpr()), dds,
1669+
moduleTranslation.lookupValue(taskOp.getEventHandle()));
16691670

16701671
if (failed(handleError(afterIP, *taskOp)))
16711672
return failure();

mlir/test/Dialect/OpenMP/invalid.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1634,7 +1634,7 @@ func.func @omp_single_copyprivate(%data_var : memref<i32>) -> () {
16341634
// -----
16351635

16361636
func.func @omp_task_depend(%data_var: memref<i32>) {
1637-
// expected-error @below {{op expected as many depend values as depend variables}}
1637+
// expected-error @below {{'omp.task' op operand count (1) does not match with the total size (0) specified in attribute 'operandSegmentSizes'}}
16381638
"omp.task"(%data_var) ({
16391639
"omp.terminator"() : () -> ()
16401640
}) {depend_kinds = [], operandSegmentSizes = array<i32: 0, 0, 1, 0, 0, 0, 0, 0>} : (memref<i32>) -> ()

mlir/test/Dialect/OpenMP/ops.mlir

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,8 +1975,8 @@ func.func @omp_single_copyprivate(%data_var: memref<i32>) {
19751975
}
19761976

19771977
// CHECK-LABEL: @omp_task
1978-
// CHECK-SAME: (%[[bool_var:.*]]: i1, %[[i64_var:.*]]: i64, %[[i32_var:.*]]: i32, %[[data_var:.*]]: memref<i32>)
1979-
func.func @omp_task(%bool_var: i1, %i64_var: i64, %i32_var: i32, %data_var: memref<i32>) {
1978+
// CHECK-SAME: (%[[bool_var:.*]]: i1, %[[i64_var:.*]]: i64, %[[i32_var:.*]]: i32, %[[data_var:.*]]: memref<i32>, %[[event_handle:.*]]: !llvm.ptr)
1979+
func.func @omp_task(%bool_var: i1, %i64_var: i64, %i32_var: i32, %data_var: memref<i32>, %event_handle : !llvm.ptr) {
19801980

19811981
// Checking simple task
19821982
// CHECK: omp.task {
@@ -2055,6 +2055,12 @@ func.func @omp_task(%bool_var: i1, %i64_var: i64, %i32_var: i32, %data_var: memr
20552055
omp.terminator
20562056
}
20572057

2058+
// Checking detach clause
2059+
// CHECK: omp.task detach(%[[event_handle]] : !llvm.ptr)
2060+
omp.task detach(%event_handle : !llvm.ptr){
2061+
omp.terminator
2062+
}
2063+
20582064
// Checking multiple clauses
20592065
// CHECK: omp.task allocate(%[[data_var]] : memref<i32> -> %[[data_var]] : memref<i32>)
20602066
omp.task allocate(%data_var : memref<i32> -> %data_var : memref<i32>)

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,6 +2505,23 @@ llvm.mlir.global internal @_QFsubEx() : i32
25052505

25062506
// -----
25072507

2508+
// CHECK-LABEL: define void @omp_task_detach
2509+
// CHECK-SAME: (ptr %[[event_handle:.*]])
2510+
llvm.func @omp_task_detach(%event_handle : !llvm.ptr){
2511+
// CHECK: %[[omp_global_thread_num:.+]] = call i32 @__kmpc_global_thread_num({{.+}})
2512+
// CHECK: %[[task_data:.+]] = call ptr @__kmpc_omp_task_alloc
2513+
// CHECK: %[[return_val:.*]] = call ptr @__kmpc_task_allow_completion_event(ptr {{.*}}, i32 %[[omp_global_thread_num]], ptr %[[task_data]])
2514+
// CHECK: %[[conv:.*]] = ptrtoint ptr %[[return_val]] to i64
2515+
// CHECK: store i64 %[[conv]], ptr %[[event_handle]], align 4
2516+
// CHECK: call i32 @__kmpc_omp_task(ptr @{{.+}}, i32 %[[omp_global_thread_num]], ptr %[[task_data]])
2517+
omp.task detach(%event_handle : !llvm.ptr){
2518+
omp.terminator
2519+
}
2520+
llvm.return
2521+
}
2522+
2523+
// -----
2524+
25082525
// CHECK-LABEL: define void @omp_task
25092526
// CHECK-SAME: (i32 %[[x:.+]], i32 %[[y:.+]], ptr %[[zaddr:.+]])
25102527
llvm.func @omp_task(%x: i32, %y: i32, %zaddr: !llvm.ptr) {

0 commit comments

Comments
 (0)