Skip to content

Commit e584299

Browse files
committed
Make cost() and priority() runtime evaluated
- Make depend() gathering info and compute_dep func creation a bit more generic to be used with these clauses too Closes llvm#130
1 parent d2d451f commit e584299

File tree

11 files changed

+655
-346
lines changed

11 files changed

+655
-346
lines changed

clang/lib/CodeGen/CGOmpSsRuntime.cpp

Lines changed: 175 additions & 153 deletions
Large diffs are not rendered by default.

clang/lib/CodeGen/CGOmpSsRuntime.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ class CGOmpSsRuntime {
170170
// List of OmpSs-2 specific metadata to be added to llvm.module.flags
171171
SmallVector<llvm::Metadata *, 4> MetadataList;
172172

173+
// This is used by cost/priority clauses to build a bundle with the form
174+
// (func_ptr, arg0, arg1... argN)
175+
void EmitWrapperCallBundle(
176+
std::string Name, std::string FuncName,
177+
CodeGenFunction &CGF, const Expr *E,
178+
SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo);
179+
173180
void EmitDSAShared(
174181
CodeGenFunction &CGF, const Expr *E,
175182
SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo,
@@ -258,10 +265,18 @@ class CGOmpSsRuntime {
258265
// returns the innermost nested task NormalCleanupDestSlot address
259266
void setTaskNormalCleanupDestSlot(Address Addr);
260267

261-
262268
llvm::AllocaInst *createTaskAwareAlloca(
263269
CodeGenFunction &CGF, llvm::Type *Ty, const Twine &Name, llvm::Value *ArraySize);
264270

271+
llvm::Function *createCallWrapperFunc(
272+
CodeGenFunction &CGF,
273+
const llvm::MapVector<const VarDecl *, LValue> &ExprInvolvedVarList,
274+
const llvm::MapVector<const Expr *, llvm::Value *> &VLASizeInvolvedMap,
275+
const llvm::DenseMap<const VarDecl *, Address> &CaptureInvolvedMap,
276+
ArrayRef<QualType> RetTypes,
277+
bool HasThis, std::string FuncName, std::string RetName,
278+
llvm::function_ref<void(CodeGenFunction &)> Body);
279+
265280
RValue emitTaskFunction(CodeGenFunction &CGF,
266281
const FunctionDecl *FD,
267282
const CallExpr *CE,

clang/lib/Sema/SemaOmpSs.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,31 @@ void Sema::ActOnOmpSsAfterClauseGathering(SmallVectorImpl<OSSClause *>& Clauses)
840840
OSSClauseChecker.getImplicitFirstprivate().begin(),
841841
OSSClauseChecker.getImplicitFirstprivate().end());
842842

843+
// TODO: Can we just put this in the previous
844+
// loop over clauses?
845+
// I think no, here is an example:
846+
// void foo(int a) {
847+
// #pragma oss task cost(a) in(a)
848+
// }
849+
// Here we expect 'a' to be shared because of the dependency
850+
// but as we find cost before we register firstprivate
851+
for (auto *Clause : Clauses) {
852+
if (isa<OSSCostClause>(Clause) || isa<OSSPriorityClause>(Clause)) {
853+
// TODO: Stmt is not used, remove
854+
DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
855+
DSAChecker.VisitOSSClause(Clause);
856+
// FIXME: how to handle an error?
857+
if (DSAChecker.isErrorFound())
858+
ErrorFound = true;
859+
ImplicitShared.append(
860+
DSAChecker.getImplicitShared().begin(),
861+
DSAChecker.getImplicitShared().end());
862+
ImplicitFirstprivate.append(
863+
DSAChecker.getImplicitFirstprivate().begin(),
864+
DSAChecker.getImplicitFirstprivate().end());
865+
}
866+
}
867+
843868
if (!ImplicitShared.empty()) {
844869
if (OSSClause *Implicit = ActOnOmpSsSharedClause(
845870
ImplicitShared, SourceLocation(), SourceLocation(),

clang/test/OmpSs/IR/task_cost.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,48 @@ void bar(int n) {
1919
foo2(n);
2020
}
2121

22-
// CHECK: %3 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.COST"(i32 %call), "QUAL.OSS.CAPTURED"(i32 %call) ]
23-
// CHECK: %5 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.COST"(i32 %4), "QUAL.OSS.CAPTURED"(i32 %4) ]
24-
// CHECK: %7 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.COST"(i32 %6), "QUAL.OSS.CAPTURED"(i32 %6) ]
22+
// CHECK: %3 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.COST"(i32 ()* @compute_cost) ]
23+
// CHECK: %4 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %n.addr), "QUAL.OSS.COST"(i32 (i32*)* @compute_cost.1, i32* %n.addr) ]
24+
// CHECK: %5 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %vla), "QUAL.OSS.VLA.DIMS"(i32* %vla, i64 %1), "QUAL.OSS.COST"(i32 (i32*, i64)* @compute_cost.2, i32* %vla), "QUAL.OSS.CAPTURED"(i64 %1) ]
25+
// CHECK: %6 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.COST"(i32 ()* @compute_cost.3), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo1:5:9\00") ]
26+
// CHECK: %8 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %call_arg), "QUAL.OSS.COST"(i32 (i32*)* @compute_cost.4, i32* %call_arg), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo2:7:9\00") ]
27+
28+
// CHECK: define internal i32 @compute_cost()
29+
// CHECK-NEXT: entry:
30+
// CHECK-NEXT: %call = call i32 @_Z3fooIiET_v()
31+
// CHECK-NEXT: ret i32 %call
32+
// CHECK-NEXT: }
33+
34+
// CHECK: define internal i32 @compute_cost.1(i32* %n)
35+
// CHECK-NEXT: entry:
36+
// CHECK-NEXT: %n.addr = alloca i32*, align 8
37+
// CHECK-NEXT: store i32* %n, i32** %n.addr, align 8
38+
// CHECK-NEXT: %0 = load i32, i32* %n, align 4
39+
// CHECK-NEXT: ret i32 %0
40+
// CHECK-NEXT: }
41+
42+
// CHECK: define internal i32 @compute_cost.2(i32* %vla, i64 %0)
43+
// CHECK-NEXT: entry:
44+
// CHECK-NEXT: %vla.addr = alloca i32*, align 8
45+
// CHECK-NEXT: %.addr = alloca i64, align 8
46+
// CHECK-NEXT: store i32* %vla, i32** %vla.addr, align 8
47+
// CHECK-NEXT: store i64 %0, i64* %.addr, align 8
48+
// CHECK-NEXT: %arrayidx = getelementptr inbounds i32, i32* %vla, i64 1
49+
// CHECK-NEXT: %1 = load i32, i32* %arrayidx, align 4
50+
// CHECK-NEXT: ret i32 %1
51+
// CHECK-NEXT: }
52+
53+
// CHECK: define internal i32 @compute_cost.3()
54+
// CHECK-NEXT: entry:
55+
// CHECK-NEXT: %call = call i32 @_Z3fooIiET_v()
56+
// CHECK-NEXT: ret i32 %call
57+
// CHECK-NEXT: }
58+
59+
// CHECK: define internal i32 @compute_cost.4(i32* %n)
60+
// CHECK-NEXT: entry:
61+
// CHECK-NEXT: %n.addr = alloca i32*, align 8
62+
// CHECK-NEXT: store i32* %n, i32** %n.addr, align 8
63+
// CHECK-NEXT: %0 = load i32, i32* %n, align 4
64+
// CHECK-NEXT: ret i32 %0
65+
// CHECK-NEXT: }
2566

26-
// CHECK: %8 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.COST"(i32 %call1), "QUAL.OSS.CAPTURED"(i32 %call1), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo1:5:9\00") ]
27-
// CHECK: %11 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %call_arg), "QUAL.OSS.COST"(i32 %10), "QUAL.OSS.CAPTURED"(i32 %10), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo2:7:9\00") ]

clang/test/OmpSs/IR/task_priority.cpp

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,42 @@ void bar(int n) {
1919
foo2(n);
2020
}
2121

22-
// CHECK: %3 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.PRIORITY"(i32 %call), "QUAL.OSS.CAPTURED"(i32 %call) ]
23-
// CHECK: %5 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.PRIORITY"(i32 %4), "QUAL.OSS.CAPTURED"(i32 %4) ]
24-
// CHECK: %7 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.PRIORITY"(i32 %6), "QUAL.OSS.CAPTURED"(i32 %6) ]
22+
// CHECK: %3 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.PRIORITY"(i32 ()* @compute_priority) ]
23+
// CHECK: %4 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %n.addr), "QUAL.OSS.PRIORITY"(i32 (i32*)* @compute_priority.1, i32* %n.addr) ]
24+
// CHECK: %5 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %vla), "QUAL.OSS.VLA.DIMS"(i32* %vla, i64 %1), "QUAL.OSS.PRIORITY"(i32 (i32*, i64)* @compute_priority.2, i32* %vla), "QUAL.OSS.CAPTURED"(i64 %1) ]
25+
// CHECK: %6 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.PRIORITY"(i32 ()* @compute_priority.3), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo1:5:9\00") ]
26+
// CHECK: %8 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %call_arg), "QUAL.OSS.PRIORITY"(i32 (i32*)* @compute_priority.4, i32* %call_arg), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo2:7:9\00") ]
2527

26-
// CHECK: %8 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.PRIORITY"(i32 %call1), "QUAL.OSS.CAPTURED"(i32 %call1), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo1:5:9\00") ]
27-
// CHECK: %11 = call token @llvm.directive.region.entry() [ "DIR.OSS"([5 x i8] c"TASK\00"), "QUAL.OSS.FIRSTPRIVATE"(i32* %call_arg), "QUAL.OSS.PRIORITY"(i32 %10), "QUAL.OSS.CAPTURED"(i32 %10), "QUAL.OSS.DECL.SOURCE"([9 x i8] c"foo2:7:9\00") ]
28+
// CHECK: define internal i32 @compute_priority.1(i32* %n)
29+
// CHECK-NEXT: entry:
30+
// CHECK-NEXT: %n.addr = alloca i32*, align 8
31+
// CHECK-NEXT: store i32* %n, i32** %n.addr, align 8
32+
// CHECK-NEXT: %0 = load i32, i32* %n, align 4
33+
// CHECK-NEXT: ret i32 %0
34+
// CHECK-NEXT: }
35+
36+
// CHECK: define internal i32 @compute_priority.2(i32* %vla, i64 %0)
37+
// CHECK-NEXT: entry:
38+
// CHECK-NEXT: %vla.addr = alloca i32*, align 8
39+
// CHECK-NEXT: %.addr = alloca i64, align 8
40+
// CHECK-NEXT: store i32* %vla, i32** %vla.addr, align 8
41+
// CHECK-NEXT: store i64 %0, i64* %.addr, align 8
42+
// CHECK-NEXT: %arrayidx = getelementptr inbounds i32, i32* %vla, i64 1
43+
// CHECK-NEXT: %1 = load i32, i32* %arrayidx, align 4
44+
// CHECK-NEXT: ret i32 %1
45+
// CHECK-NEXT: }
46+
47+
// CHECK: define internal i32 @compute_priority.3()
48+
// CHECK-NEXT: entry:
49+
// CHECK-NEXT: %call = call i32 @_Z3fooIiET_v()
50+
// CHECK-NEXT: ret i32 %call
51+
// CHECK-NEXT: }
52+
53+
// CHECK: define internal i32 @compute_priority.4(i32* %n)
54+
// CHECK-NEXT: entry:
55+
// CHECK-NEXT: %n.addr = alloca i32*, align 8
56+
// CHECK-NEXT: store i32* %n, i32** %n.addr, align 8
57+
// CHECK-NEXT: %0 = load i32, i32* %n, align 4
58+
// CHECK-NEXT: ret i32 %0
59+
// CHECK-NEXT: }
2860

llvm/include/llvm/Analysis/OmpSsRegionAnalysis.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,18 @@ struct ReductionInitCombInfo {
132132

133133
using DirectiveReductionsInitCombInfo = MapVector<Value *, ReductionInitCombInfo>;
134134

135+
struct DirectiveCostInfo {
136+
Function *Fun = nullptr;
137+
// The arguments of the call to function.
138+
SmallVector<Value *, 4> Args;
139+
};
140+
141+
struct DirectivePriorityInfo {
142+
Function *Fun = nullptr;
143+
// The arguments of the call to function.
144+
SmallVector<Value *, 4> Args;
145+
};
146+
135147
struct DirectiveLoopInfo {
136148
enum {
137149
LT, // <
@@ -179,11 +191,11 @@ struct DirectiveEnvironment {
179191
DirectiveVLADimsInfo VLADimsInfo;
180192
DirectiveDependsInfo DependsInfo;
181193
DirectiveReductionsInitCombInfo ReductionsInitCombInfo;
194+
DirectiveCostInfo CostInfo;
195+
DirectivePriorityInfo PriorityInfo;
182196
Value *Final = nullptr;
183197
Value *If = nullptr;
184-
Value *Priority = nullptr;
185198
Value *Label = nullptr;
186-
Value *Cost = nullptr;
187199
Value *Wait = nullptr;
188200
DirectiveCapturedInfo CapturedInfo;
189201
DirectiveNonPODsInfo NonPODsInfo;
@@ -227,6 +239,8 @@ struct DirectiveEnvironment {
227239
void verifyVLADimsInfo();
228240
void verifyDependInfo();
229241
void verifyReductionInitCombInfo();
242+
void verifyCostInfo();
243+
void verifyPriorityInfo();
230244
void verifyNonPODInfo();
231245
void verifyLoopInfo();
232246
void verifyMultiDependInfo();

llvm/lib/Analysis/OmpSsRegionAnalysis.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,15 +269,21 @@ void DirectiveEnvironment::gatherIfInfo(OperandBundleDef &OB) {
269269
}
270270

271271
void DirectiveEnvironment::gatherCostInfo(OperandBundleDef &OB) {
272-
assert(!Cost && "Only allowed one OperandBundle with this Id");
273-
assert(OB.input_size() == 1 && "Only allowed one Value per OperandBundle");
274-
Cost = OB.inputs()[0];
272+
assert(OB.input_size() > 0 &&
273+
"Cost OperandBundle must have at least function");
274+
ArrayRef<Value *> OBArgs = OB.inputs();
275+
CostInfo.Fun = cast<Function>(OBArgs[0]);
276+
for (size_t i = 1; i < OBArgs.size(); ++i)
277+
CostInfo.Args.push_back(OBArgs[i]);
275278
}
276279

277280
void DirectiveEnvironment::gatherPriorityInfo(OperandBundleDef &OB) {
278-
assert(!Priority && "Only allowed one OperandBundle with this Id");
279-
assert(OB.input_size() == 1 && "Only allowed one Value per OperandBundle");
280-
Priority = OB.inputs()[0];
281+
assert(OB.input_size() > 0 &&
282+
"Priority OperandBundle must have at least function");
283+
ArrayRef<Value *> OBArgs = OB.inputs();
284+
PriorityInfo.Fun = cast<Function>(OBArgs[0]);
285+
for (size_t i = 1; i < OBArgs.size(); ++i)
286+
PriorityInfo.Args.push_back(OBArgs[i]);
281287
}
282288

283289
void DirectiveEnvironment::gatherLabelInfo(OperandBundleDef &OB) {
@@ -449,6 +455,22 @@ void DirectiveEnvironment::verifyReductionInitCombInfo() {
449455
}
450456
}
451457

458+
void DirectiveEnvironment::verifyCostInfo() {
459+
for (auto *V : CostInfo.Args) {
460+
if (!valueInDSABundles(DSAInfo, V)
461+
&& !valueInCapturedBundle(CapturedInfo, V))
462+
llvm_unreachable("Cost function argument has no associated DSA or capture");
463+
}
464+
}
465+
466+
void DirectiveEnvironment::verifyPriorityInfo() {
467+
for (auto *V : PriorityInfo.Args) {
468+
if (!valueInDSABundles(DSAInfo, V)
469+
&& !valueInCapturedBundle(CapturedInfo, V))
470+
llvm_unreachable("Priority function argument has no associated DSA or capture");
471+
}
472+
}
473+
452474
void DirectiveEnvironment::verifyNonPODInfo() {
453475
for (const auto &InitMap : NonPODsInfo.Inits) {
454476
// INIT may only be in private clauses

llvm/lib/Transforms/OmpSs/OmpSsTransform.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ struct OmpSs {
936936
}
937937
}
938938

939-
void unpackCostAndRewrite(Module &M, Value *Cost, Function *F,
939+
void unpackCostAndRewrite(Module &M, const DirectiveCostInfo &CostInfo, Function *F,
940940
const MapVector<Value *, size_t> &StructToIdxMap) {
941941
BasicBlock::Create(M.getContext(), "entry", F);
942942
BasicBlock &Entry = F->getEntryBlock();
@@ -949,6 +949,7 @@ struct OmpSs {
949949

950950
Value *GEPConstraints = BBBuilder.CreateGEP(
951951
Constraints, Idx, "gep_" + Constraints->getName());
952+
Value *Cost = BBBuilder.CreateCall(CostInfo.Fun, CostInfo.Args);
952953
Value *CostCast = BBBuilder.CreateZExt(Cost, Nanos6TaskConstraints::getInstance(M).getType()->getElementType(0));
953954
BBBuilder.CreateStore(CostCast, GEPConstraints);
954955
for (Instruction &I : Entry) {
@@ -961,13 +962,16 @@ struct OmpSs {
961962
}
962963
}
963964

964-
void unpackPriorityAndRewrite(Module &M, Value *Priority, Function *F,
965-
const MapVector<Value *, size_t> &StructToIdxMap) {
965+
void unpackPriorityAndRewrite(
966+
Module &M, const DirectivePriorityInfo &PriorityInfo, Function *F,
967+
const MapVector<Value *, size_t> &StructToIdxMap) {
966968
BasicBlock::Create(M.getContext(), "entry", F);
967969
BasicBlock &Entry = F->getEntryBlock();
968970
F->getEntryBlock().getInstList().push_back(ReturnInst::Create(M.getContext()));
969971
IRBuilder<> BBBuilder(&F->getEntryBlock().back());
970972
Value *PriorityArg = &*(F->arg_end() - 1);
973+
974+
Value *Priority = BBBuilder.CreateCall(PriorityInfo.Fun, PriorityInfo.Args);
971975
Value *PrioritySExt = BBBuilder.CreateSExt(Priority, Type::getInt64Ty(M.getContext()));
972976
BBBuilder.CreateStore(PrioritySExt, PriorityArg);
973977
for (Instruction &I : Entry) {
@@ -1728,8 +1732,9 @@ struct OmpSs {
17281732
ArrayRef<Type *> TaskTypeList, ArrayRef<StringRef> TaskNameList) {
17291733

17301734
const DirectiveEnvironment &DirEnv = DirInfo.DirEnv;
1735+
const DirectiveCostInfo &CostInfo = DirEnv.CostInfo;
17311736

1732-
if (!DirEnv.Cost)
1737+
if (!CostInfo.Fun)
17331738
return nullptr;
17341739

17351740
SmallVector<Type *, 4> TaskExtraTypeList;
@@ -1743,7 +1748,7 @@ struct OmpSs {
17431748
("nanos6_unpacked_constraints_" + F.getName() + Twine(taskNum)).str(),
17441749
TaskTypeList, TaskNameList,
17451750
TaskExtraTypeList, TaskExtraNameList);
1746-
unpackCostAndRewrite(M, DirEnv.Cost, UnpackConstraintsFuncVar, TaskArgsToStructIdxMap);
1751+
unpackCostAndRewrite(M, CostInfo, UnpackConstraintsFuncVar, TaskArgsToStructIdxMap);
17471752

17481753
Function *OlConstraintsFuncVar
17491754
= createUnpackOlFunction(M, F,
@@ -1782,8 +1787,9 @@ struct OmpSs {
17821787
ArrayRef<Type *> TaskTypeList, ArrayRef<StringRef> TaskNameList) {
17831788

17841789
const DirectiveEnvironment &DirEnv = DirInfo.DirEnv;
1790+
const DirectivePriorityInfo &PriorityInfo = DirEnv.PriorityInfo;
17851791

1786-
if (!DirEnv.Priority)
1792+
if (!PriorityInfo.Fun)
17871793
return nullptr;
17881794

17891795
SmallVector<Type *, 4> TaskExtraTypeList;
@@ -1798,7 +1804,7 @@ struct OmpSs {
17981804
("nanos6_unpacked_priority_" + F.getName() + Twine(taskNum)).str(),
17991805
TaskTypeList, TaskNameList,
18001806
TaskExtraTypeList, TaskExtraNameList);
1801-
unpackPriorityAndRewrite(M, DirEnv.Priority, UnpackPriorityFuncVar, TaskArgsToStructIdxMap);
1807+
unpackPriorityAndRewrite(M, PriorityInfo, UnpackPriorityFuncVar, TaskArgsToStructIdxMap);
18021808

18031809
Function *OlPriorityFuncVar
18041810
= createUnpackOlFunction(M, F,

0 commit comments

Comments
 (0)