Skip to content

Commit 1d890b0

Browse files
[Flang, OpenMP] Add LLVM lowering support for PRIORITY in TASK (#120710)
Implementation details: The PRIORITY clause is recognized by setting the flags = 32 to the `__kmpc_omp_task_alloc` runtime call. Also, store the priority-value to the `kmp_task_t` struct member
1 parent ec5d17b commit 1d890b0

File tree

5 files changed

+81
-16
lines changed

5 files changed

+81
-16
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1264,12 +1264,14 @@ class OpenMPIRBuilder {
12641264
/// \param EventHandle If present, signifies the event handle as part of
12651265
/// the detach clause
12661266
/// \param Mergeable If the given task is `mergeable`
1267+
/// \param priority `priority-value' specifies the execution order of the
1268+
/// tasks that is generated by the construct
12671269
InsertPointOrErrorTy
12681270
createTask(const LocationDescription &Loc, InsertPointTy AllocaIP,
12691271
BodyGenCallbackTy BodyGenCB, bool Tied = true,
12701272
Value *Final = nullptr, Value *IfCondition = nullptr,
12711273
SmallVector<DependData> Dependencies = {}, bool Mergeable = false,
1272-
Value *EventHandle = nullptr);
1274+
Value *EventHandle = nullptr, Value *Priority = nullptr);
12731275

12741276
/// Generator for the taskgroup construct
12751277
///

llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,8 @@ static Value *emitTaskDependencies(
18501850
OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
18511851
const LocationDescription &Loc, InsertPointTy AllocaIP,
18521852
BodyGenCallbackTy BodyGenCB, bool Tied, Value *Final, Value *IfCondition,
1853-
SmallVector<DependData> Dependencies, bool Mergeable, Value *EventHandle) {
1853+
SmallVector<DependData> Dependencies, bool Mergeable, Value *EventHandle,
1854+
Value *Priority) {
18541855

18551856
if (!updateToLocation(Loc))
18561857
return InsertPointTy();
@@ -1896,7 +1897,7 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
18961897
Builder, AllocaIP, ToBeDeleted, TaskAllocaIP, "global.tid", false));
18971898

18981899
OI.PostOutlineCB = [this, Ident, Tied, Final, IfCondition, Dependencies,
1899-
Mergeable, EventHandle, TaskAllocaBB,
1900+
Mergeable, Priority, EventHandle, TaskAllocaBB,
19001901
ToBeDeleted](Function &OutlinedFn) mutable {
19011902
// Replace the Stale CI by appropriate RTL function call.
19021903
assert(OutlinedFn.getNumUses() == 1 &&
@@ -1924,6 +1925,8 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
19241925
// Task is not final iff (Flags & 2) == 0.
19251926
// Task is mergeable iff (Flags & 4) == 4.
19261927
// Task is not mergeable iff (Flags & 4) == 0.
1928+
// Task is priority iff (Flags & 32) == 32.
1929+
// Task is not priority iff (Flags & 32) == 0.
19271930
// TODO: Handle the other flags.
19281931
Value *Flags = Builder.getInt32(Tied);
19291932
if (Final) {
@@ -1934,6 +1937,8 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
19341937

19351938
if (Mergeable)
19361939
Flags = Builder.CreateOr(Builder.getInt32(4), Flags);
1940+
if (Priority)
1941+
Flags = Builder.CreateOr(Builder.getInt32(32), Flags);
19371942

19381943
// Argument - `sizeof_kmp_task_t` (TaskSize)
19391944
// Tasksize refers to the size in bytes of kmp_task_t data structure
@@ -1990,6 +1995,33 @@ OpenMPIRBuilder::InsertPointOrErrorTy OpenMPIRBuilder::createTask(
19901995
SharedsSize);
19911996
}
19921997

1998+
if (Priority) {
1999+
//
2000+
// The return type of "__kmpc_omp_task_alloc" is "kmp_task_t *",
2001+
// we populate the priority information into the "kmp_task_t" here
2002+
//
2003+
// The struct "kmp_task_t" definition is available in kmp.h
2004+
// kmp_task_t = { shareds, routine, part_id, data1, data2 }
2005+
// data2 is used for priority
2006+
//
2007+
Type *Int32Ty = Builder.getInt32Ty();
2008+
Constant *Zero = ConstantInt::get(Int32Ty, 0);
2009+
// kmp_task_t* => { ptr }
2010+
Type *TaskPtr = StructType::get(VoidPtr);
2011+
Value *TaskGEP =
2012+
Builder.CreateInBoundsGEP(TaskPtr, TaskData, {Zero, Zero});
2013+
// kmp_task_t => { ptr, ptr, i32, ptr, ptr }
2014+
Type *TaskStructType = StructType::get(
2015+
VoidPtr, VoidPtr, Builder.getInt32Ty(), VoidPtr, VoidPtr);
2016+
Value *PriorityData = Builder.CreateInBoundsGEP(
2017+
TaskStructType, TaskGEP, {Zero, ConstantInt::get(Int32Ty, 4)});
2018+
// kmp_cmplrdata_t => { ptr, ptr }
2019+
Type *CmplrStructType = StructType::get(VoidPtr, VoidPtr);
2020+
Value *CmplrData = Builder.CreateInBoundsGEP(CmplrStructType,
2021+
PriorityData, {Zero, Zero});
2022+
Builder.CreateStore(Priority, CmplrData);
2023+
}
2024+
19932025
Value *DepArray = nullptr;
19942026
if (Dependencies.size()) {
19952027
InsertPointTy OldIP = Builder.saveIP();

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
270270
.Case([&](omp::TaskOp op) {
271271
checkAllocate(op, result);
272272
checkInReduction(op, result);
273-
checkPriority(op, result);
274273
checkUntied(op, result);
275274
})
276275
.Case([&](omp::TaskgroupOp op) {
@@ -281,6 +280,10 @@ static LogicalResult checkImplementationStatus(Operation &op) {
281280
checkDepend(op, result);
282281
checkNowait(op, result);
283282
})
283+
.Case([&](omp::TaskloopOp op) {
284+
// TODO: Add other clauses check
285+
checkPriority(op, result);
286+
})
284287
.Case([&](omp::WsloopOp op) {
285288
checkAllocate(op, result);
286289
checkLinear(op, result);
@@ -1797,7 +1800,8 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
17971800
moduleTranslation.lookupValue(taskOp.getFinal()),
17981801
moduleTranslation.lookupValue(taskOp.getIfExpr()), dds,
17991802
taskOp.getMergeable(),
1800-
moduleTranslation.lookupValue(taskOp.getEventHandle()));
1803+
moduleTranslation.lookupValue(taskOp.getEventHandle()),
1804+
moduleTranslation.lookupValue(taskOp.getPriority()));
18011805

18021806
if (failed(handleError(afterIP, *taskOp)))
18031807
return failure();

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2874,6 +2874,44 @@ llvm.func @omp_taskgroup_task(%x: i32, %y: i32, %zaddr: !llvm.ptr) {
28742874

28752875
// -----
28762876

2877+
llvm.func @test_01() attributes {sym_visibility = "private"}
2878+
llvm.func @test_02() attributes {sym_visibility = "private"}
2879+
// CHECK-LABEL: define void @_QPomp_task_priority() {
2880+
llvm.func @_QPomp_task_priority() {
2881+
%0 = llvm.mlir.constant(1 : i64) : i64
2882+
%1 = llvm.alloca %0 x i32 {bindc_name = "x"} : (i64) -> !llvm.ptr
2883+
%2 = llvm.mlir.constant(4 : i32) : i32
2884+
%3 = llvm.mlir.constant(true) : i1
2885+
%4 = llvm.load %1 : !llvm.ptr -> i32
2886+
// CHECK: %[[GID_01:.*]] = call i32 @__kmpc_global_thread_num(ptr {{.*}})
2887+
// CHECK: %[[I_01:.*]] = call ptr @__kmpc_omp_task_alloc(ptr {{.*}}, i32 %[[GID_01]], i32 33, i64 40, i64 0, ptr @{{.*}})
2888+
// CHECK: %[[I_02:.*]] = getelementptr inbounds { ptr }, ptr %[[I_01]], i32 0, i32 0
2889+
// CHECK: %[[I_03:.*]] = getelementptr inbounds { ptr, ptr, i32, ptr, ptr }, ptr %[[I_02]], i32 0, i32 4
2890+
// CHECK: %[[I_04:.*]] = getelementptr inbounds { ptr, ptr }, ptr %[[I_03]], i32 0, i32 0
2891+
// CHECK: store i32 {{.*}}, ptr %[[I_04]], align 4
2892+
// CHECK: %{{.*}} = call i32 @__kmpc_omp_task(ptr {{.*}}, i32 %[[GID_01]], ptr %[[I_01]])
2893+
omp.task priority(%4 : i32) {
2894+
llvm.call @test_01() : () -> ()
2895+
omp.terminator
2896+
}
2897+
// CHECK: %[[GID_02:.*]] = call i32 @__kmpc_global_thread_num(ptr {{.*}})
2898+
// CHECK: %[[I_05:.*]] = call ptr @__kmpc_omp_task_alloc(ptr {{.*}}, i32 %[[GID_02]], i32 35, i64 40, i64 0, ptr @{{.*}})
2899+
// CHECK: %[[I_06:.*]] = getelementptr inbounds { ptr }, ptr %[[I_05]], i32 0, i32 0
2900+
// CHECK: %[[I_07:.*]] = getelementptr inbounds { ptr, ptr, i32, ptr, ptr }, ptr %[[I_06]], i32 0, i32 4
2901+
// CHECK: %[[I_08:.*]] = getelementptr inbounds { ptr, ptr }, ptr %[[I_07]], i32 0, i32 0
2902+
// CHECK: store i32 4, ptr %[[I_08]], align 4
2903+
// CHECK: %{{.*}} = call i32 @__kmpc_omp_task(ptr {{.*}}, i32 %[[GID_02]], ptr %[[I_05]])
2904+
omp.task final(%3) priority(%2 : i32) {
2905+
llvm.call @test_02() : () -> ()
2906+
omp.terminator
2907+
}
2908+
llvm.return
2909+
// CHECK: ret void
2910+
// CHECK: }
2911+
}
2912+
2913+
// -----
2914+
28772915
// CHECK-LABEL: @omp_opaque_pointers
28782916
// CHECK-SAME: (ptr %[[ARG0:.*]], ptr %[[ARG1:.*]], i32 %[[EXPR:.*]])
28792917
llvm.func @omp_opaque_pointers(%arg0 : !llvm.ptr, %arg1: !llvm.ptr, %expr: i32) -> () {

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -400,17 +400,6 @@ llvm.func @task_in_reduction(%x : !llvm.ptr) {
400400

401401
// -----
402402

403-
llvm.func @task_priority(%x : i32) {
404-
// expected-error@below {{not yet implemented: Unhandled clause priority in omp.task operation}}
405-
// expected-error@below {{LLVM Translation failed for operation: omp.task}}
406-
omp.task priority(%x : i32) {
407-
omp.terminator
408-
}
409-
llvm.return
410-
}
411-
412-
// -----
413-
414403
llvm.func @task_untied() {
415404
// expected-error@below {{not yet implemented: Unhandled clause untied in omp.task operation}}
416405
// expected-error@below {{LLVM Translation failed for operation: omp.task}}

0 commit comments

Comments
 (0)