Skip to content

[Flang] [OpenMP] Add LLVM lowering support for PRIORITY in TASK #120710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1264,12 +1264,14 @@ class OpenMPIRBuilder {
/// \param EventHandle If present, signifies the event handle as part of
/// the detach clause
/// \param Mergeable If the given task is `mergeable`
/// \param priority `priority-value' specifies the execution order of the
/// tasks that is generated by the construct
InsertPointOrErrorTy
createTask(const LocationDescription &Loc, InsertPointTy AllocaIP,
BodyGenCallbackTy BodyGenCB, bool Tied = true,
Value *Final = nullptr, Value *IfCondition = nullptr,
SmallVector<DependData> Dependencies = {}, bool Mergeable = false,
Value *EventHandle = nullptr);
Value *EventHandle = nullptr, Value *Priority = nullptr);

/// Generator for the taskgroup construct
///
Expand Down
36 changes: 34 additions & 2 deletions llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,8 @@ static Value *emitTaskDependencies(
OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
const LocationDescription &Loc, InsertPointTy AllocaIP,
BodyGenCallbackTy BodyGenCB, bool Tied, Value *Final, Value *IfCondition,
SmallVector<DependData> Dependencies, bool Mergeable, Value *EventHandle) {
SmallVector<DependData> Dependencies, bool Mergeable, Value *EventHandle,
Value *Priority) {

if (!updateToLocation(Loc))
return InsertPointTy();
Expand Down Expand Up @@ -1864,7 +1865,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
Builder, AllocaIP, ToBeDeleted, TaskAllocaIP, "global.tid", false));

OI.PostOutlineCB = [this, Ident, Tied, Final, IfCondition, Dependencies,
Mergeable, EventHandle, TaskAllocaBB,
Mergeable, Priority, EventHandle, TaskAllocaBB,
ToBeDeleted](Function &OutlinedFn) mutable {
// Replace the Stale CI by appropriate RTL function call.
assert(OutlinedFn.getNumUses() == 1 &&
Expand Down Expand Up @@ -1892,6 +1893,8 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
// Task is not final iff (Flags & 2) == 0.
// Task is mergeable iff (Flags & 4) == 4.
// Task is not mergeable iff (Flags & 4) == 0.
// Task is priority iff (Flags & 32) == 32.
// Task is not priority iff (Flags & 32) == 0.
// TODO: Handle the other flags.
Value *Flags = Builder.getInt32(Tied);
if (Final) {
Expand All @@ -1902,6 +1905,8 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(

if (Mergeable)
Flags = Builder.CreateOr(Builder.getInt32(4), Flags);
if (Priority)
Flags = Builder.CreateOr(Builder.getInt32(32), Flags);

// Argument - `sizeof_kmp_task_t` (TaskSize)
// Tasksize refers to the size in bytes of kmp_task_t data structure
Expand Down Expand Up @@ -1958,6 +1963,33 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
SharedsSize);
}

if (Priority) {
//
// The return type of "__kmpc_omp_task_alloc" is "kmp_task_t *",
// we populate the priority information into the "kmp_task_t" here
//
// The struct "kmp_task_t" definition is available in kmp.h
// kmp_task_t = { shareds, routine, part_id, data1, data2 }
// data2 is used for priority
//
Type *Int32Ty = Builder.getInt32Ty();
Constant *Zero = ConstantInt::get(Int32Ty, 0);
// kmp_task_t* => { ptr }
Type *TaskPtr = StructType::get(VoidPtr);
Value *TaskGEP =
Builder.CreateInBoundsGEP(TaskPtr, TaskData, {Zero, Zero});
// kmp_task_t => { ptr, ptr, i32, ptr, ptr }
Type *TaskStructType = StructType::get(
VoidPtr, VoidPtr, Builder.getInt32Ty(), VoidPtr, VoidPtr);
Value *PriorityData = Builder.CreateInBoundsGEP(
TaskStructType, TaskGEP, {Zero, ConstantInt::get(Int32Ty, 4)});
// kmp_cmplrdata_t => { ptr, ptr }
Type *CmplrStructType = StructType::get(VoidPtr, VoidPtr);
Value *CmplrData = Builder.CreateInBoundsGEP(CmplrStructType,
PriorityData, {Zero, Zero});
Builder.CreateStore(Priority, CmplrData);
}

Value *DepArray = nullptr;
if (Dependencies.size()) {
InsertPointTy OldIP = Builder.saveIP();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
.Case([&](omp::TaskOp op) {
checkAllocate(op, result);
checkInReduction(op, result);
checkPriority(op, result);
checkUntied(op, result);
})
.Case([&](omp::TaskgroupOp op) {
Expand All @@ -268,6 +267,10 @@ static LogicalResult checkImplementationStatus(Operation &op) {
checkDepend(op, result);
checkNowait(op, result);
})
.Case([&](omp::TaskloopOp op) {
// TODO: Add other clauses check
checkPriority(op, result);
})
.Case([&](omp::WsloopOp op) {
checkAllocate(op, result);
checkLinear(op, result);
Expand Down Expand Up @@ -1775,7 +1778,8 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
moduleTranslation.lookupValue(taskOp.getFinal()),
moduleTranslation.lookupValue(taskOp.getIfExpr()), dds,
taskOp.getMergeable(),
moduleTranslation.lookupValue(taskOp.getEventHandle()));
moduleTranslation.lookupValue(taskOp.getEventHandle()),
moduleTranslation.lookupValue(taskOp.getPriority()));

if (failed(handleError(afterIP, *taskOp)))
return failure();
Expand Down
38 changes: 38 additions & 0 deletions mlir/test/Target/LLVMIR/openmp-llvm.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -2834,6 +2834,44 @@ llvm.func @omp_taskgroup_task(%x: i32, %y: i32, %zaddr: !llvm.ptr) {

// -----

llvm.func @test_01() attributes {sym_visibility = "private"}
llvm.func @test_02() attributes {sym_visibility = "private"}
// CHECK-LABEL: define void @_QPomp_task_priority() {
llvm.func @_QPomp_task_priority() {
%0 = llvm.mlir.constant(1 : i64) : i64
%1 = llvm.alloca %0 x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
%2 = llvm.mlir.constant(4 : i32) : i32
%3 = llvm.mlir.constant(true) : i1
%4 = llvm.load %1 : !llvm.ptr -> i32
// CHECK: %[[GID_01:.*]] = call i32 @__kmpc_global_thread_num(ptr {{.*}})
// CHECK: %[[I_01:.*]] = call ptr @__kmpc_omp_task_alloc(ptr {{.*}}, i32 %[[GID_01]], i32 33, i64 40, i64 0, ptr @{{.*}})
// CHECK: %[[I_02:.*]] = getelementptr inbounds { ptr }, ptr %[[I_01]], i32 0, i32 0
// CHECK: %[[I_03:.*]] = getelementptr inbounds { ptr, ptr, i32, ptr, ptr }, ptr %[[I_02]], i32 0, i32 4
// CHECK: %[[I_04:.*]] = getelementptr inbounds { ptr, ptr }, ptr %[[I_03]], i32 0, i32 0
// CHECK: store i32 {{.*}}, ptr %[[I_04]], align 4
// CHECK: %{{.*}} = call i32 @__kmpc_omp_task(ptr {{.*}}, i32 %[[GID_01]], ptr %[[I_01]])
omp.task priority(%4 : i32) {
llvm.call @test_01() : () -> ()
omp.terminator
}
// CHECK: %[[GID_02:.*]] = call i32 @__kmpc_global_thread_num(ptr {{.*}})
// CHECK: %[[I_05:.*]] = call ptr @__kmpc_omp_task_alloc(ptr {{.*}}, i32 %[[GID_02]], i32 35, i64 40, i64 0, ptr @{{.*}})
// CHECK: %[[I_06:.*]] = getelementptr inbounds { ptr }, ptr %[[I_05]], i32 0, i32 0
// CHECK: %[[I_07:.*]] = getelementptr inbounds { ptr, ptr, i32, ptr, ptr }, ptr %[[I_06]], i32 0, i32 4
// CHECK: %[[I_08:.*]] = getelementptr inbounds { ptr, ptr }, ptr %[[I_07]], i32 0, i32 0
// CHECK: store i32 4, ptr %[[I_08]], align 4
// CHECK: %{{.*}} = call i32 @__kmpc_omp_task(ptr {{.*}}, i32 %[[GID_02]], ptr %[[I_05]])
omp.task final(%3) priority(%2 : i32) {
llvm.call @test_02() : () -> ()
omp.terminator
}
llvm.return
// CHECK: ret void
// CHECK: }
}

// -----

// CHECK-LABEL: @omp_opaque_pointers
// CHECK-SAME: (ptr %[[ARG0:.*]], ptr %[[ARG1:.*]], i32 %[[EXPR:.*]])
llvm.func @omp_opaque_pointers(%arg0 : !llvm.ptr, %arg1: !llvm.ptr, %expr: i32) -> () {
Expand Down
11 changes: 0 additions & 11 deletions mlir/test/Target/LLVMIR/openmp-todo.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -429,17 +429,6 @@ llvm.func @task_in_reduction(%x : !llvm.ptr) {

// -----

llvm.func @task_priority(%x : i32) {
// expected-error@below {{not yet implemented: Unhandled clause priority in omp.task operation}}
// expected-error@below {{LLVM Translation failed for operation: omp.task}}
omp.task priority(%x : i32) {
omp.terminator
}
llvm.return
}

// -----

llvm.func @task_untied() {
// expected-error@below {{not yet implemented: Unhandled clause untied in omp.task operation}}
// expected-error@below {{LLVM Translation failed for operation: omp.task}}
Expand Down
Loading