[OPENMP] Simplified interface for codegen of tasks, NFC.
Reduced number of arguments in member functions of runtime support library for task-based directives. llvm-svn: 267863
This commit is contained in:
parent
2b19a6fe53
commit
24b5baed27
|
@ -3361,20 +3361,16 @@ static int array_pod_sort_comparator(const PrivateDataTy *P1,
|
||||||
return P1->first < P2->first ? 1 : (P2->first < P1->first ? -1 : 0);
|
return P1->first < P2->first ? 1 : (P2->first < P1->first ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit(
|
CGOpenMPRuntime::TaskResultTy
|
||||||
CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D,
|
CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
|
const OMPExecutableDirective &D,
|
||||||
unsigned NumberOfParts, llvm::Value *TaskFunction, QualType SharedsTy,
|
llvm::Value *TaskFunction, QualType SharedsTy,
|
||||||
Address Shareds, ArrayRef<const Expr *> PrivateVars,
|
Address Shareds, const OMPTaskDataTy &Data) {
|
||||||
ArrayRef<const Expr *> PrivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateVars,
|
|
||||||
ArrayRef<const Expr *> FirstprivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateInits) {
|
|
||||||
auto &C = CGM.getContext();
|
auto &C = CGM.getContext();
|
||||||
llvm::SmallVector<PrivateDataTy, 4> Privates;
|
llvm::SmallVector<PrivateDataTy, 4> Privates;
|
||||||
// Aggregate privates and sort them by the alignment.
|
// Aggregate privates and sort them by the alignment.
|
||||||
auto I = PrivateCopies.begin();
|
auto I = Data.PrivateCopies.begin();
|
||||||
for (auto *E : PrivateVars) {
|
for (auto *E : Data.PrivateVars) {
|
||||||
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
|
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
|
||||||
Privates.push_back(std::make_pair(
|
Privates.push_back(std::make_pair(
|
||||||
C.getDeclAlign(VD),
|
C.getDeclAlign(VD),
|
||||||
|
@ -3382,9 +3378,9 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit(
|
||||||
/*PrivateElemInit=*/nullptr)));
|
/*PrivateElemInit=*/nullptr)));
|
||||||
++I;
|
++I;
|
||||||
}
|
}
|
||||||
I = FirstprivateCopies.begin();
|
I = Data.FirstprivateCopies.begin();
|
||||||
auto IElemInitRef = FirstprivateInits.begin();
|
auto IElemInitRef = Data.FirstprivateInits.begin();
|
||||||
for (auto *E : FirstprivateVars) {
|
for (auto *E : Data.FirstprivateVars) {
|
||||||
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
|
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
|
||||||
Privates.push_back(std::make_pair(
|
Privates.push_back(std::make_pair(
|
||||||
C.getDeclAlign(VD),
|
C.getDeclAlign(VD),
|
||||||
|
@ -3424,8 +3420,9 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit(
|
||||||
->getType();
|
->getType();
|
||||||
if (!Privates.empty()) {
|
if (!Privates.empty()) {
|
||||||
auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
|
auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
|
||||||
TaskPrivatesMap = emitTaskPrivateMappingFunction(
|
TaskPrivatesMap = emitTaskPrivateMappingFunction(CGM, Loc, Data.PrivateVars,
|
||||||
CGM, Loc, PrivateVars, FirstprivateVars, FI->getType(), Privates);
|
Data.FirstprivateVars,
|
||||||
|
FI->getType(), Privates);
|
||||||
TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
||||||
TaskPrivatesMap, TaskPrivatesMapTy);
|
TaskPrivatesMap, TaskPrivatesMapTy);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3447,13 +3444,13 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit(
|
||||||
// description of kmp_tasking_flags struct.
|
// description of kmp_tasking_flags struct.
|
||||||
const unsigned TiedFlag = 0x1;
|
const unsigned TiedFlag = 0x1;
|
||||||
const unsigned FinalFlag = 0x2;
|
const unsigned FinalFlag = 0x2;
|
||||||
unsigned Flags = Tied ? TiedFlag : 0;
|
unsigned Flags = Data.Tied ? TiedFlag : 0;
|
||||||
auto *TaskFlags =
|
auto *TaskFlags =
|
||||||
Final.getPointer()
|
Data.Final.getPointer()
|
||||||
? CGF.Builder.CreateSelect(Final.getPointer(),
|
? CGF.Builder.CreateSelect(Data.Final.getPointer(),
|
||||||
CGF.Builder.getInt32(FinalFlag),
|
CGF.Builder.getInt32(FinalFlag),
|
||||||
CGF.Builder.getInt32(/*C=*/0))
|
CGF.Builder.getInt32(/*C=*/0))
|
||||||
: CGF.Builder.getInt32(Final.getInt() ? FinalFlag : 0);
|
: CGF.Builder.getInt32(Data.Final.getInt() ? FinalFlag : 0);
|
||||||
TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
|
TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
|
||||||
auto *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
|
auto *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
|
||||||
llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc),
|
llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc),
|
||||||
|
@ -3489,7 +3486,7 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit(
|
||||||
auto PrivatesBase = CGF.EmitLValueForField(Base, *FI);
|
auto PrivatesBase = CGF.EmitLValueForField(Base, *FI);
|
||||||
FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
|
FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
|
||||||
LValue SharedsBase;
|
LValue SharedsBase;
|
||||||
if (!FirstprivateVars.empty()) {
|
if (!Data.FirstprivateVars.empty()) {
|
||||||
SharedsBase = CGF.MakeAddrLValue(
|
SharedsBase = CGF.MakeAddrLValue(
|
||||||
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
||||||
KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
|
KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
|
||||||
|
@ -3569,41 +3566,35 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit(
|
||||||
CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
|
||||||
DestructorFn, KmpRoutineEntryPtrTy),
|
DestructorFn, KmpRoutineEntryPtrTy),
|
||||||
Destructor);
|
Destructor);
|
||||||
TaskDataTy Data;
|
TaskResultTy Result;
|
||||||
Data.NewTask = NewTask;
|
Result.NewTask = NewTask;
|
||||||
Data.TaskEntry = TaskEntry;
|
Result.TaskEntry = TaskEntry;
|
||||||
Data.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
|
Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
|
||||||
Data.TDBase = TDBase;
|
Result.TDBase = TDBase;
|
||||||
Data.KmpTaskTQTyRD = KmpTaskTQTyRD;
|
Result.KmpTaskTQTyRD = KmpTaskTQTyRD;
|
||||||
return Data;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntime::emitTaskCall(
|
void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D,
|
const OMPExecutableDirective &D,
|
||||||
bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
|
llvm::Value *TaskFunction,
|
||||||
unsigned NumberOfParts, llvm::Value *TaskFunction, QualType SharedsTy,
|
QualType SharedsTy, Address Shareds,
|
||||||
Address Shareds, const Expr *IfCond, ArrayRef<const Expr *> PrivateVars,
|
const Expr *IfCond,
|
||||||
ArrayRef<const Expr *> PrivateCopies,
|
const OMPTaskDataTy &Data) {
|
||||||
ArrayRef<const Expr *> FirstprivateVars,
|
|
||||||
ArrayRef<const Expr *> FirstprivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateInits,
|
|
||||||
ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences) {
|
|
||||||
if (!CGF.HaveInsertPoint())
|
if (!CGF.HaveInsertPoint())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TaskDataTy Data =
|
TaskResultTy Result =
|
||||||
emitTaskInit(CGF, Loc, D, Tied, Final, NumberOfParts, TaskFunction,
|
emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
|
||||||
SharedsTy, Shareds, PrivateVars, PrivateCopies,
|
llvm::Value *NewTask = Result.NewTask;
|
||||||
FirstprivateVars, FirstprivateCopies, FirstprivateInits);
|
llvm::Value *TaskEntry = Result.TaskEntry;
|
||||||
llvm::Value *NewTask = Data.NewTask;
|
llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
|
||||||
llvm::Value *TaskEntry = Data.TaskEntry;
|
LValue TDBase = Result.TDBase;
|
||||||
llvm::Value *NewTaskNewTaskTTy = Data.NewTaskNewTaskTTy;
|
RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
|
||||||
LValue TDBase = Data.TDBase;
|
|
||||||
RecordDecl *KmpTaskTQTyRD = Data.KmpTaskTQTyRD;
|
|
||||||
auto &C = CGM.getContext();
|
auto &C = CGM.getContext();
|
||||||
// Process list of dependences.
|
// Process list of dependences.
|
||||||
Address DependenciesArray = Address::invalid();
|
Address DependenciesArray = Address::invalid();
|
||||||
unsigned NumDependencies = Dependences.size();
|
unsigned NumDependencies = Data.Dependences.size();
|
||||||
if (NumDependencies) {
|
if (NumDependencies) {
|
||||||
// Dependence kind for RTL.
|
// Dependence kind for RTL.
|
||||||
enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
|
enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 };
|
||||||
|
@ -3620,9 +3611,8 @@ void CGOpenMPRuntime::emitTaskCall(
|
||||||
addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
|
addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
|
||||||
KmpDependInfoRD->completeDefinition();
|
KmpDependInfoRD->completeDefinition();
|
||||||
KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
|
KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
|
||||||
} else {
|
} else
|
||||||
KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
|
KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
|
||||||
}
|
|
||||||
CharUnits DependencySize = C.getTypeSizeInChars(KmpDependInfoTy);
|
CharUnits DependencySize = C.getTypeSizeInChars(KmpDependInfoTy);
|
||||||
// Define type kmp_depend_info[<Dependences.size()>];
|
// Define type kmp_depend_info[<Dependences.size()>];
|
||||||
QualType KmpDependInfoArrayTy = C.getConstantArrayType(
|
QualType KmpDependInfoArrayTy = C.getConstantArrayType(
|
||||||
|
@ -3632,7 +3622,7 @@ void CGOpenMPRuntime::emitTaskCall(
|
||||||
DependenciesArray =
|
DependenciesArray =
|
||||||
CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
|
CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
|
||||||
for (unsigned i = 0; i < NumDependencies; ++i) {
|
for (unsigned i = 0; i < NumDependencies; ++i) {
|
||||||
const Expr *E = Dependences[i].second;
|
const Expr *E = Data.Dependences[i].second;
|
||||||
auto Addr = CGF.EmitLValue(E);
|
auto Addr = CGF.EmitLValue(E);
|
||||||
llvm::Value *Size;
|
llvm::Value *Size;
|
||||||
QualType Ty = E->getType();
|
QualType Ty = E->getType();
|
||||||
|
@ -3662,7 +3652,7 @@ void CGOpenMPRuntime::emitTaskCall(
|
||||||
CGF.EmitStoreOfScalar(Size, LenLVal);
|
CGF.EmitStoreOfScalar(Size, LenLVal);
|
||||||
// deps[i].flags = <Dependences[i].first>;
|
// deps[i].flags = <Dependences[i].first>;
|
||||||
RTLDependenceKindTy DepKind;
|
RTLDependenceKindTy DepKind;
|
||||||
switch (Dependences[i].first) {
|
switch (Data.Dependences[i].first) {
|
||||||
case OMPC_DEPEND_in:
|
case OMPC_DEPEND_in:
|
||||||
DepKind = DepIn;
|
DepKind = DepIn;
|
||||||
break;
|
break;
|
||||||
|
@ -3705,10 +3695,10 @@ void CGOpenMPRuntime::emitTaskCall(
|
||||||
DepTaskArgs[5] = CGF.Builder.getInt32(0);
|
DepTaskArgs[5] = CGF.Builder.getInt32(0);
|
||||||
DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
|
DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
|
||||||
}
|
}
|
||||||
auto &&ThenCodeGen = [this, Tied, Loc, NumberOfParts, TDBase, KmpTaskTQTyRD,
|
auto &&ThenCodeGen = [this, Loc, &Data, TDBase, KmpTaskTQTyRD,
|
||||||
NumDependencies, &TaskArgs,
|
NumDependencies, &TaskArgs,
|
||||||
&DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
|
&DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||||
if (!Tied) {
|
if (!Data.Tied) {
|
||||||
auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
|
auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
|
||||||
auto PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
|
auto PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
|
||||||
CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
|
CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
|
||||||
|
@ -3775,22 +3765,16 @@ void CGOpenMPRuntime::emitTaskCall(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntime::emitTaskLoopCall(
|
void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
|
const OMPLoopDirective &D,
|
||||||
bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
|
llvm::Value *TaskFunction,
|
||||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule, bool Nogroup,
|
QualType SharedsTy, Address Shareds,
|
||||||
unsigned NumberOfParts, llvm::Value *TaskFunction, QualType SharedsTy,
|
const Expr *IfCond,
|
||||||
Address Shareds, const Expr *IfCond, ArrayRef<const Expr *> PrivateVars,
|
const OMPTaskDataTy &Data) {
|
||||||
ArrayRef<const Expr *> PrivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateVars,
|
|
||||||
ArrayRef<const Expr *> FirstprivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateInits) {
|
|
||||||
if (!CGF.HaveInsertPoint())
|
if (!CGF.HaveInsertPoint())
|
||||||
return;
|
return;
|
||||||
TaskDataTy Data =
|
TaskResultTy Result =
|
||||||
emitTaskInit(CGF, Loc, D, Tied, Final, NumberOfParts, TaskFunction,
|
emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
|
||||||
SharedsTy, Shareds, PrivateVars, PrivateCopies,
|
|
||||||
FirstprivateVars, FirstprivateCopies, FirstprivateInits);
|
|
||||||
// NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc()
|
// NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc()
|
||||||
// libcall.
|
// libcall.
|
||||||
// Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
|
// Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
|
||||||
|
@ -3806,37 +3790,37 @@ void CGOpenMPRuntime::emitTaskLoopCall(
|
||||||
IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
|
IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
|
||||||
|
|
||||||
LValue LBLVal = CGF.EmitLValueForField(
|
LValue LBLVal = CGF.EmitLValueForField(
|
||||||
Data.TDBase,
|
Result.TDBase,
|
||||||
*std::next(Data.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
|
*std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
|
||||||
auto *LBVar =
|
auto *LBVar =
|
||||||
cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
|
cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
|
||||||
CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(), LBLVal.getQuals(),
|
CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(), LBLVal.getQuals(),
|
||||||
/*IsInitializer=*/true);
|
/*IsInitializer=*/true);
|
||||||
LValue UBLVal = CGF.EmitLValueForField(
|
LValue UBLVal = CGF.EmitLValueForField(
|
||||||
Data.TDBase,
|
Result.TDBase,
|
||||||
*std::next(Data.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
|
*std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
|
||||||
auto *UBVar =
|
auto *UBVar =
|
||||||
cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
|
cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
|
||||||
CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(), UBLVal.getQuals(),
|
CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(), UBLVal.getQuals(),
|
||||||
/*IsInitializer=*/true);
|
/*IsInitializer=*/true);
|
||||||
LValue StLVal = CGF.EmitLValueForField(
|
LValue StLVal = CGF.EmitLValueForField(
|
||||||
Data.TDBase,
|
Result.TDBase,
|
||||||
*std::next(Data.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
|
*std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
|
||||||
auto *StVar =
|
auto *StVar =
|
||||||
cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
|
cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
|
||||||
CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(),
|
CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(),
|
||||||
/*IsInitializer=*/true);
|
/*IsInitializer=*/true);
|
||||||
enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
|
enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
|
||||||
llvm::Value *TaskArgs[] = {
|
llvm::Value *TaskArgs[] = {
|
||||||
UpLoc, ThreadID, Data.NewTask, IfVal, LBLVal.getPointer(),
|
UpLoc, ThreadID, Result.NewTask, IfVal, LBLVal.getPointer(),
|
||||||
UBLVal.getPointer(), CGF.EmitLoadOfScalar(StLVal, SourceLocation()),
|
UBLVal.getPointer(), CGF.EmitLoadOfScalar(StLVal, SourceLocation()),
|
||||||
llvm::ConstantInt::getSigned(CGF.IntTy, Nogroup ? 1 : 0),
|
llvm::ConstantInt::getSigned(CGF.IntTy, Data.Nogroup ? 1 : 0),
|
||||||
llvm::ConstantInt::getSigned(
|
llvm::ConstantInt::getSigned(
|
||||||
CGF.IntTy, Schedule.getPointer()
|
CGF.IntTy, Data.Schedule.getPointer()
|
||||||
? Schedule.getInt() ? NumTasks : Grainsize
|
? Data.Schedule.getInt() ? NumTasks : Grainsize
|
||||||
: NoSchedule),
|
: NoSchedule),
|
||||||
Schedule.getPointer()
|
Data.Schedule.getPointer()
|
||||||
? CGF.Builder.CreateIntCast(Schedule.getPointer(), CGF.Int64Ty,
|
? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
|
||||||
/*isSigned=*/false)
|
/*isSigned=*/false)
|
||||||
: llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
|
: llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
|
||||||
llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
|
llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
|
||||||
|
|
|
@ -87,6 +87,20 @@ public:
|
||||||
void operator()(CodeGenFunction &CGF) const;
|
void operator()(CodeGenFunction &CGF) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OMPTaskDataTy final {
|
||||||
|
SmallVector<const Expr *, 4> PrivateVars;
|
||||||
|
SmallVector<const Expr *, 4> PrivateCopies;
|
||||||
|
SmallVector<const Expr *, 4> FirstprivateVars;
|
||||||
|
SmallVector<const Expr *, 4> FirstprivateCopies;
|
||||||
|
SmallVector<const Expr *, 4> FirstprivateInits;
|
||||||
|
SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
|
||||||
|
llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
|
||||||
|
llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
|
||||||
|
unsigned NumberOfParts = 0;
|
||||||
|
bool Tied = true;
|
||||||
|
bool Nogroup = false;
|
||||||
|
};
|
||||||
|
|
||||||
class CGOpenMPRuntime {
|
class CGOpenMPRuntime {
|
||||||
protected:
|
protected:
|
||||||
CodeGenModule &CGM;
|
CodeGenModule &CGM;
|
||||||
|
@ -433,12 +447,12 @@ private:
|
||||||
///
|
///
|
||||||
llvm::Value *getCriticalRegionLock(StringRef CriticalName);
|
llvm::Value *getCriticalRegionLock(StringRef CriticalName);
|
||||||
|
|
||||||
struct TaskDataTy {
|
struct TaskResultTy {
|
||||||
llvm::Value *NewTask;
|
llvm::Value *NewTask = nullptr;
|
||||||
llvm::Value *TaskEntry;
|
llvm::Value *TaskEntry = nullptr;
|
||||||
llvm::Value *NewTaskNewTaskTTy;
|
llvm::Value *NewTaskNewTaskTTy = nullptr;
|
||||||
LValue TDBase;
|
LValue TDBase;
|
||||||
RecordDecl *KmpTaskTQTyRD;
|
RecordDecl *KmpTaskTQTyRD = nullptr;
|
||||||
};
|
};
|
||||||
/// Emit task region for the task directive. The task region is emitted in
|
/// Emit task region for the task directive. The task region is emitted in
|
||||||
/// several steps:
|
/// several steps:
|
||||||
|
@ -455,39 +469,17 @@ private:
|
||||||
/// 3. Copy a pointer to destructions function to field destructions of the
|
/// 3. Copy a pointer to destructions function to field destructions of the
|
||||||
/// resulting structure kmp_task_t.
|
/// resulting structure kmp_task_t.
|
||||||
/// \param D Current task directive.
|
/// \param D Current task directive.
|
||||||
/// \param Tied true if the task is tied (the task is tied to the thread that
|
|
||||||
/// can suspend its task region), false - untied (the task is not tied to any
|
|
||||||
/// thread).
|
|
||||||
/// \param Final Contains either constant bool value, or llvm::Value * of i1
|
|
||||||
/// type for final clause. If the value is true, the task forces all of its
|
|
||||||
/// child tasks to become final and included tasks.
|
|
||||||
/// \param NumberOfParts Number of parts in untied tasks.
|
|
||||||
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
|
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
|
||||||
/// /*part_id*/, captured_struct */*__context*/);
|
/// /*part_id*/, captured_struct */*__context*/);
|
||||||
/// \param SharedsTy A type which contains references the shared variables.
|
/// \param SharedsTy A type which contains references the shared variables.
|
||||||
/// \param Shareds Context with the list of shared variables from the \p
|
/// \param Shareds Context with the list of shared variables from the \p
|
||||||
/// TaskFunction.
|
/// TaskFunction.
|
||||||
/// \param PrivateVars List of references to private variables for the task
|
/// \param Data Additional data for task generation like tiednsee, final
|
||||||
/// directive.
|
/// state, list of privates etc.
|
||||||
/// \param PrivateCopies List of private copies for each private variable in
|
TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
/// \p PrivateVars.
|
const OMPExecutableDirective &D,
|
||||||
/// \param FirstprivateVars List of references to private variables for the
|
llvm::Value *TaskFunction, QualType SharedsTy,
|
||||||
/// task directive.
|
Address Shareds, const OMPTaskDataTy &Data);
|
||||||
/// \param FirstprivateCopies List of private copies for each private variable
|
|
||||||
/// in \p FirstprivateVars.
|
|
||||||
/// \param FirstprivateInits List of references to auto generated variables
|
|
||||||
/// used for initialization of a single array element. Used if firstprivate
|
|
||||||
/// variable is of array type.
|
|
||||||
TaskDataTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
|
|
||||||
const OMPExecutableDirective &D, bool Tied,
|
|
||||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
|
|
||||||
unsigned NumberOfParts, llvm::Value *TaskFunction,
|
|
||||||
QualType SharedsTy, Address Shareds,
|
|
||||||
ArrayRef<const Expr *> PrivateVars,
|
|
||||||
ArrayRef<const Expr *> PrivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateVars,
|
|
||||||
ArrayRef<const Expr *> FirstprivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateInits);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CGOpenMPRuntime(CodeGenModule &CGM);
|
explicit CGOpenMPRuntime(CodeGenModule &CGM);
|
||||||
|
@ -794,13 +786,6 @@ public:
|
||||||
/// kmp_task_t *new_task), where new_task is a resulting structure from
|
/// kmp_task_t *new_task), where new_task is a resulting structure from
|
||||||
/// previous items.
|
/// previous items.
|
||||||
/// \param D Current task directive.
|
/// \param D Current task directive.
|
||||||
/// \param Tied true if the task is tied (the task is tied to the thread that
|
|
||||||
/// can suspend its task region), false - untied (the task is not tied to any
|
|
||||||
/// thread).
|
|
||||||
/// \param NumberOfParts Number of parts for untied task.
|
|
||||||
/// \param Final Contains either constant bool value, or llvm::Value * of i1
|
|
||||||
/// type for final clause. If the value is true, the task forces all of its
|
|
||||||
/// child tasks to become final and included tasks.
|
|
||||||
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
|
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
|
||||||
/// /*part_id*/, captured_struct */*__context*/);
|
/// /*part_id*/, captured_struct */*__context*/);
|
||||||
/// \param SharedsTy A type which contains references the shared variables.
|
/// \param SharedsTy A type which contains references the shared variables.
|
||||||
|
@ -808,29 +793,13 @@ public:
|
||||||
/// TaskFunction.
|
/// TaskFunction.
|
||||||
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
|
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
|
||||||
/// otherwise.
|
/// otherwise.
|
||||||
/// \param PrivateVars List of references to private variables for the task
|
/// \param Data Additional data for task generation like tiednsee, final
|
||||||
/// directive.
|
/// state, list of privates etc.
|
||||||
/// \param PrivateCopies List of private copies for each private variable in
|
virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
/// \p PrivateVars.
|
const OMPExecutableDirective &D,
|
||||||
/// \param FirstprivateVars List of references to private variables for the
|
llvm::Value *TaskFunction, QualType SharedsTy,
|
||||||
/// task directive.
|
Address Shareds, const Expr *IfCond,
|
||||||
/// \param FirstprivateCopies List of private copies for each private variable
|
const OMPTaskDataTy &Data);
|
||||||
/// in \p FirstprivateVars.
|
|
||||||
/// \param FirstprivateInits List of references to auto generated variables
|
|
||||||
/// used for initialization of a single array element. Used if firstprivate
|
|
||||||
/// variable is of array type.
|
|
||||||
/// \param Dependences List of dependences for the 'task' construct, including
|
|
||||||
/// original expression and dependency type.
|
|
||||||
virtual void emitTaskCall(
|
|
||||||
CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D,
|
|
||||||
bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
|
|
||||||
unsigned NumberOfParts, llvm::Value *TaskFunction, QualType SharedsTy,
|
|
||||||
Address Shareds, const Expr *IfCond, ArrayRef<const Expr *> PrivateVars,
|
|
||||||
ArrayRef<const Expr *> PrivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateVars,
|
|
||||||
ArrayRef<const Expr *> FirstprivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateInits,
|
|
||||||
ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences);
|
|
||||||
|
|
||||||
/// Emit task region for the taskloop directive. The taskloop region is
|
/// Emit task region for the taskloop directive. The taskloop region is
|
||||||
/// emitted in several steps:
|
/// emitted in several steps:
|
||||||
|
@ -852,17 +821,6 @@ public:
|
||||||
/// is a resulting structure from
|
/// is a resulting structure from
|
||||||
/// previous items.
|
/// previous items.
|
||||||
/// \param D Current task directive.
|
/// \param D Current task directive.
|
||||||
/// \param Tied true if the task is tied (the task is tied to the thread that
|
|
||||||
/// can suspend its task region), false - untied (the task is not tied to any
|
|
||||||
/// thread).
|
|
||||||
/// \param Final Contains either constant bool value, or llvm::Value * of i1
|
|
||||||
/// type for final clause. If the value is true, the task forces all of its
|
|
||||||
/// child tasks to become final and included tasks.
|
|
||||||
/// \param Schedule If Pointer is nullptr, no grainsize/num_tasks clauses were
|
|
||||||
/// specified. If IntVal is false - it is for grainsize clause, true - for
|
|
||||||
/// num_tasks clause.
|
|
||||||
/// \param Nogroup true if nogroup clause was specified, false otherwise.
|
|
||||||
/// \param NumberOfParts Number of parts in untied taskloops.
|
|
||||||
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
|
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
|
||||||
/// /*part_id*/, captured_struct */*__context*/);
|
/// /*part_id*/, captured_struct */*__context*/);
|
||||||
/// \param SharedsTy A type which contains references the shared variables.
|
/// \param SharedsTy A type which contains references the shared variables.
|
||||||
|
@ -870,27 +828,12 @@ public:
|
||||||
/// TaskFunction.
|
/// TaskFunction.
|
||||||
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
|
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
|
||||||
/// otherwise.
|
/// otherwise.
|
||||||
/// \param PrivateVars List of references to private variables for the task
|
/// \param Data Additional data for task generation like tiednsee, final
|
||||||
/// directive.
|
/// state, list of privates etc.
|
||||||
/// \param PrivateCopies List of private copies for each private variable in
|
|
||||||
/// \p PrivateVars.
|
|
||||||
/// \param FirstprivateVars List of references to private variables for the
|
|
||||||
/// task directive.
|
|
||||||
/// \param FirstprivateCopies List of private copies for each private variable
|
|
||||||
/// in \p FirstprivateVars.
|
|
||||||
/// \param FirstprivateInits List of references to auto generated variables
|
|
||||||
/// used for initialization of a single array element. Used if firstprivate
|
|
||||||
/// variable is of array type.
|
|
||||||
virtual void emitTaskLoopCall(
|
virtual void emitTaskLoopCall(
|
||||||
CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
|
CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
|
||||||
bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
|
llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
|
||||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule, bool Nogroup,
|
const Expr *IfCond, const OMPTaskDataTy &Data);
|
||||||
unsigned NumberOfParts, llvm::Value *TaskFunction, QualType SharedsTy,
|
|
||||||
Address Shareds, const Expr *IfCond, ArrayRef<const Expr *> PrivateVars,
|
|
||||||
ArrayRef<const Expr *> PrivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateVars,
|
|
||||||
ArrayRef<const Expr *> FirstprivateCopies,
|
|
||||||
ArrayRef<const Expr *> FirstprivateInits);
|
|
||||||
|
|
||||||
/// \brief Emit code for the directive that does not require outlining.
|
/// \brief Emit code for the directive that does not require outlining.
|
||||||
///
|
///
|
||||||
|
|
|
@ -2312,18 +2312,30 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective(
|
||||||
void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
|
void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
|
||||||
const RegionCodeGenTy &BodyGen,
|
const RegionCodeGenTy &BodyGen,
|
||||||
const TaskGenTy &TaskGen,
|
const TaskGenTy &TaskGen,
|
||||||
bool Tied) {
|
OMPTaskDataTy &Data) {
|
||||||
// Emit outlined function for task construct.
|
// Emit outlined function for task construct.
|
||||||
auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
|
auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
|
||||||
auto *I = CS->getCapturedDecl()->param_begin();
|
auto *I = CS->getCapturedDecl()->param_begin();
|
||||||
auto *PartId = std::next(I);
|
auto *PartId = std::next(I);
|
||||||
auto *TaskT = std::next(I, 4);
|
auto *TaskT = std::next(I, 4);
|
||||||
|
// Check if the task is final
|
||||||
|
if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
|
||||||
|
// If the condition constant folds and can be elided, try to avoid emitting
|
||||||
|
// the condition and the dead arm of the if/else.
|
||||||
|
auto *Cond = Clause->getCondition();
|
||||||
|
bool CondConstant;
|
||||||
|
if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
|
||||||
|
Data.Final.setInt(CondConstant);
|
||||||
|
else
|
||||||
|
Data.Final.setPointer(EvaluateExprAsBool(Cond));
|
||||||
|
} else {
|
||||||
|
// By default the task is not final.
|
||||||
|
Data.Final.setInt(/*IntVal=*/false);
|
||||||
|
}
|
||||||
// The first function argument for tasks is a thread id, the second one is a
|
// The first function argument for tasks is a thread id, the second one is a
|
||||||
// part id (0 for tied tasks, >=0 for untied task).
|
// part id (0 for tied tasks, >=0 for untied task).
|
||||||
llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
|
llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
|
||||||
// Get list of private variables.
|
// Get list of private variables.
|
||||||
OMPPrivateDataTy Data;
|
|
||||||
Data.Tied = Tied;
|
|
||||||
for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
|
for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
|
||||||
auto IRef = C->varlist_begin();
|
auto IRef = C->varlist_begin();
|
||||||
for (auto *IInit : C->private_copies()) {
|
for (auto *IInit : C->private_copies()) {
|
||||||
|
@ -2406,23 +2418,6 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
||||||
// Emit outlined function for task construct.
|
// Emit outlined function for task construct.
|
||||||
auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
|
auto CS = cast<CapturedStmt>(S.getAssociatedStmt());
|
||||||
auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
|
auto CapturedStruct = GenerateCapturedStmtArgument(*CS);
|
||||||
// Check if we should emit tied or untied task.
|
|
||||||
bool Tied = !S.getSingleClause<OMPUntiedClause>();
|
|
||||||
// Check if the task is final
|
|
||||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
|
|
||||||
if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
|
|
||||||
// If the condition constant folds and can be elided, try to avoid emitting
|
|
||||||
// the condition and the dead arm of the if/else.
|
|
||||||
auto *Cond = Clause->getCondition();
|
|
||||||
bool CondConstant;
|
|
||||||
if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
|
|
||||||
Final.setInt(CondConstant);
|
|
||||||
else
|
|
||||||
Final.setPointer(EvaluateExprAsBool(Cond));
|
|
||||||
} else {
|
|
||||||
// By default the task is not final.
|
|
||||||
Final.setInt(/*IntVal=*/false);
|
|
||||||
}
|
|
||||||
auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
|
auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
|
||||||
const Expr *IfCond = nullptr;
|
const Expr *IfCond = nullptr;
|
||||||
for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
|
for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
|
||||||
|
@ -2433,19 +2428,20 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OMPTaskDataTy Data;
|
||||||
|
// Check if we should emit tied or untied task.
|
||||||
|
Data.Tied = !S.getSingleClause<OMPUntiedClause>();
|
||||||
auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
|
auto &&BodyGen = [CS](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||||
CGF.EmitStmt(CS->getCapturedStmt());
|
CGF.EmitStmt(CS->getCapturedStmt());
|
||||||
};
|
};
|
||||||
auto &&TaskGen = [&S, &Final, SharedsTy, CapturedStruct,
|
auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
|
||||||
IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
|
IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
|
||||||
const OMPPrivateDataTy &Data) {
|
const OMPTaskDataTy &Data) {
|
||||||
CGF.CGM.getOpenMPRuntime().emitTaskCall(
|
CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getLocStart(), S, OutlinedFn,
|
||||||
CGF, S.getLocStart(), S, Data.Tied, Final, Data.NumberOfParts,
|
SharedsTy, CapturedStruct, IfCond,
|
||||||
OutlinedFn, SharedsTy, CapturedStruct, IfCond, Data.PrivateVars,
|
Data);
|
||||||
Data.PrivateCopies, Data.FirstprivateVars, Data.FirstprivateCopies,
|
|
||||||
Data.FirstprivateInits, Data.Dependences);
|
|
||||||
};
|
};
|
||||||
EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Tied);
|
EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenFunction::EmitOMPTaskyieldDirective(
|
void CodeGenFunction::EmitOMPTaskyieldDirective(
|
||||||
|
@ -3345,34 +3341,21 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool Nogroup = S.getSingleClause<OMPNogroupClause>();
|
|
||||||
|
OMPTaskDataTy Data;
|
||||||
|
// Check if taskloop must be emitted without taskgroup.
|
||||||
|
Data.Nogroup = S.getSingleClause<OMPNogroupClause>();
|
||||||
// TODO: Check if we should emit tied or untied task.
|
// TODO: Check if we should emit tied or untied task.
|
||||||
// Check if the task is final
|
Data.Tied = true;
|
||||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
|
// Set scheduling for taskloop
|
||||||
if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
|
|
||||||
// If the condition constant folds and can be elided, try to avoid emitting
|
|
||||||
// the condition and the dead arm of the if/else.
|
|
||||||
auto *Cond = Clause->getCondition();
|
|
||||||
bool CondConstant;
|
|
||||||
if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
|
|
||||||
Final.setInt(CondConstant);
|
|
||||||
else
|
|
||||||
Final.setPointer(EvaluateExprAsBool(Cond));
|
|
||||||
} else {
|
|
||||||
// By default the task is not final.
|
|
||||||
Final.setInt(/*IntVal=*/false);
|
|
||||||
}
|
|
||||||
llvm::PointerIntPair<llvm::Value * /*no grainsize/num_tasks=nullptr*/, 1,
|
|
||||||
bool /*Grainsize=false, NumTasks=true*/>
|
|
||||||
Schedule;
|
|
||||||
if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
|
if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) {
|
||||||
// grainsize clause
|
// grainsize clause
|
||||||
Schedule.setInt(/*IntVal=*/false);
|
Data.Schedule.setInt(/*IntVal=*/false);
|
||||||
Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
|
Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize()));
|
||||||
} else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
|
} else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) {
|
||||||
// num_tasks clause
|
// num_tasks clause
|
||||||
Schedule.setInt(/*IntVal=*/true);
|
Data.Schedule.setInt(/*IntVal=*/true);
|
||||||
Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
|
Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
|
auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||||
|
@ -3445,21 +3428,19 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
|
||||||
CGF.EmitBlock(ContBlock, true);
|
CGF.EmitBlock(ContBlock, true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
auto &&TaskGen = [&S, SharedsTy, CapturedStruct, IfCond, &Final, &Schedule,
|
auto &&TaskGen = [&S, SharedsTy, CapturedStruct,
|
||||||
Nogroup](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
|
IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn,
|
||||||
const OMPPrivateDataTy &Data) {
|
const OMPTaskDataTy &Data) {
|
||||||
auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) {
|
auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||||
OMPLoopScope PreInitScope(CGF, S);
|
OMPLoopScope PreInitScope(CGF, S);
|
||||||
CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(
|
CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getLocStart(), S,
|
||||||
CGF, S.getLocStart(), S, Data.Tied, Final, Schedule, Nogroup,
|
OutlinedFn, SharedsTy,
|
||||||
Data.NumberOfParts, OutlinedFn, SharedsTy, CapturedStruct, IfCond,
|
CapturedStruct, IfCond, Data);
|
||||||
Data.PrivateVars, Data.PrivateCopies, Data.FirstprivateVars,
|
|
||||||
Data.FirstprivateCopies, Data.FirstprivateInits);
|
|
||||||
};
|
};
|
||||||
CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
|
CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop,
|
||||||
CodeGen);
|
CodeGen);
|
||||||
};
|
};
|
||||||
EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, /*Tied=*/true);
|
EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
|
void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) {
|
||||||
|
|
|
@ -87,6 +87,7 @@ class BlockFlags;
|
||||||
class BlockFieldFlags;
|
class BlockFieldFlags;
|
||||||
class RegionCodeGenTy;
|
class RegionCodeGenTy;
|
||||||
class TargetCodeGenInfo;
|
class TargetCodeGenInfo;
|
||||||
|
struct OMPTaskDataTy;
|
||||||
|
|
||||||
/// The kind of evaluation to perform on values of a particular
|
/// The kind of evaluation to perform on values of a particular
|
||||||
/// type. Basically, is the code in CGExprScalar, CGExprComplex, or
|
/// type. Basically, is the code in CGExprScalar, CGExprComplex, or
|
||||||
|
@ -2346,23 +2347,13 @@ public:
|
||||||
/// \param D Directive (possibly) with the 'linear' clause.
|
/// \param D Directive (possibly) with the 'linear' clause.
|
||||||
void EmitOMPLinearClauseInit(const OMPLoopDirective &D);
|
void EmitOMPLinearClauseInit(const OMPLoopDirective &D);
|
||||||
|
|
||||||
struct OMPPrivateDataTy {
|
|
||||||
bool Tied;
|
|
||||||
unsigned NumberOfParts;
|
|
||||||
SmallVector<const Expr *, 4> PrivateVars;
|
|
||||||
SmallVector<const Expr *, 4> PrivateCopies;
|
|
||||||
SmallVector<const Expr *, 4> FirstprivateVars;
|
|
||||||
SmallVector<const Expr *, 4> FirstprivateCopies;
|
|
||||||
SmallVector<const Expr *, 4> FirstprivateInits;
|
|
||||||
SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
|
|
||||||
};
|
|
||||||
typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
|
typedef const llvm::function_ref<void(CodeGenFunction & /*CGF*/,
|
||||||
llvm::Value * /*OutlinedFn*/,
|
llvm::Value * /*OutlinedFn*/,
|
||||||
const OMPPrivateDataTy & /*Data*/)>
|
const OMPTaskDataTy & /*Data*/)>
|
||||||
TaskGenTy;
|
TaskGenTy;
|
||||||
void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
|
void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
|
||||||
const RegionCodeGenTy &BodyGen,
|
const RegionCodeGenTy &BodyGen,
|
||||||
const TaskGenTy &TaskGen, bool Tied);
|
const TaskGenTy &TaskGen, OMPTaskDataTy &Data);
|
||||||
|
|
||||||
void EmitOMPParallelDirective(const OMPParallelDirective &S);
|
void EmitOMPParallelDirective(const OMPParallelDirective &S);
|
||||||
void EmitOMPSimdDirective(const OMPSimdDirective &S);
|
void EmitOMPSimdDirective(const OMPSimdDirective &S);
|
||||||
|
|
Loading…
Reference in New Issue