diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index ec939dd9db3336d2a1002d83062d43187eda7b7a..70057551d91573897a3f01e659522ab0a03e6932 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -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); } -CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::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) { +CGOpenMPRuntime::TaskResultTy +CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, + const OMPExecutableDirective &D, + llvm::Value *TaskFunction, QualType SharedsTy, + Address Shareds, const OMPTaskDataTy &Data) { auto &C = CGM.getContext(); llvm::SmallVector<PrivateDataTy, 4> Privates; // Aggregate privates and sort them by the alignment. - auto I = PrivateCopies.begin(); - for (auto *E : PrivateVars) { + auto I = Data.PrivateCopies.begin(); + for (auto *E : Data.PrivateVars) { auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); Privates.push_back(std::make_pair( C.getDeclAlign(VD), @@ -3382,9 +3378,9 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit( /*PrivateElemInit=*/nullptr))); ++I; } - I = FirstprivateCopies.begin(); - auto IElemInitRef = FirstprivateInits.begin(); - for (auto *E : FirstprivateVars) { + I = Data.FirstprivateCopies.begin(); + auto IElemInitRef = Data.FirstprivateInits.begin(); + for (auto *E : Data.FirstprivateVars) { auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); Privates.push_back(std::make_pair( C.getDeclAlign(VD), @@ -3424,8 +3420,9 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit( ->getType(); if (!Privates.empty()) { auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin()); - TaskPrivatesMap = emitTaskPrivateMappingFunction( - CGM, Loc, PrivateVars, FirstprivateVars, FI->getType(), Privates); + TaskPrivatesMap = emitTaskPrivateMappingFunction(CGM, Loc, Data.PrivateVars, + Data.FirstprivateVars, + FI->getType(), Privates); TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( TaskPrivatesMap, TaskPrivatesMapTy); } else { @@ -3447,13 +3444,13 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit( // description of kmp_tasking_flags struct. const unsigned TiedFlag = 0x1; const unsigned FinalFlag = 0x2; - unsigned Flags = Tied ? TiedFlag : 0; + unsigned Flags = Data.Tied ? TiedFlag : 0; auto *TaskFlags = - Final.getPointer() - ? CGF.Builder.CreateSelect(Final.getPointer(), + Data.Final.getPointer() + ? CGF.Builder.CreateSelect(Data.Final.getPointer(), CGF.Builder.getInt32(FinalFlag), 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)); auto *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy)); llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc), @@ -3489,7 +3486,7 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit( auto PrivatesBase = CGF.EmitLValueForField(Base, *FI); FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin(); LValue SharedsBase; - if (!FirstprivateVars.empty()) { + if (!Data.FirstprivateVars.empty()) { SharedsBase = CGF.MakeAddrLValue( CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)), @@ -3569,41 +3566,35 @@ CGOpenMPRuntime::TaskDataTy CGOpenMPRuntime::emitTaskInit( CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( DestructorFn, KmpRoutineEntryPtrTy), Destructor); - TaskDataTy Data; - Data.NewTask = NewTask; - Data.TaskEntry = TaskEntry; - Data.NewTaskNewTaskTTy = NewTaskNewTaskTTy; - Data.TDBase = TDBase; - Data.KmpTaskTQTyRD = KmpTaskTQTyRD; - return Data; + TaskResultTy Result; + Result.NewTask = NewTask; + Result.TaskEntry = TaskEntry; + Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy; + Result.TDBase = TDBase; + Result.KmpTaskTQTyRD = KmpTaskTQTyRD; + return Result; } -void CGOpenMPRuntime::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) { +void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, + const OMPExecutableDirective &D, + llvm::Value *TaskFunction, + QualType SharedsTy, Address Shareds, + const Expr *IfCond, + const OMPTaskDataTy &Data) { if (!CGF.HaveInsertPoint()) return; - TaskDataTy Data = - emitTaskInit(CGF, Loc, D, Tied, Final, NumberOfParts, TaskFunction, - SharedsTy, Shareds, PrivateVars, PrivateCopies, - FirstprivateVars, FirstprivateCopies, FirstprivateInits); - llvm::Value *NewTask = Data.NewTask; - llvm::Value *TaskEntry = Data.TaskEntry; - llvm::Value *NewTaskNewTaskTTy = Data.NewTaskNewTaskTTy; - LValue TDBase = Data.TDBase; - RecordDecl *KmpTaskTQTyRD = Data.KmpTaskTQTyRD; + TaskResultTy Result = + emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data); + llvm::Value *NewTask = Result.NewTask; + llvm::Value *TaskEntry = Result.TaskEntry; + llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy; + LValue TDBase = Result.TDBase; + RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD; auto &C = CGM.getContext(); // Process list of dependences. Address DependenciesArray = Address::invalid(); - unsigned NumDependencies = Dependences.size(); + unsigned NumDependencies = Data.Dependences.size(); if (NumDependencies) { // Dependence kind for RTL. enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3 }; @@ -3620,9 +3611,8 @@ void CGOpenMPRuntime::emitTaskCall( addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy); KmpDependInfoRD->completeDefinition(); KmpDependInfoTy = C.getRecordType(KmpDependInfoRD); - } else { + } else KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl()); - } CharUnits DependencySize = C.getTypeSizeInChars(KmpDependInfoTy); // Define type kmp_depend_info[<Dependences.size()>]; QualType KmpDependInfoArrayTy = C.getConstantArrayType( @@ -3632,7 +3622,7 @@ void CGOpenMPRuntime::emitTaskCall( DependenciesArray = CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr"); 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); llvm::Value *Size; QualType Ty = E->getType(); @@ -3662,7 +3652,7 @@ void CGOpenMPRuntime::emitTaskCall( CGF.EmitStoreOfScalar(Size, LenLVal); // deps[i].flags = <Dependences[i].first>; RTLDependenceKindTy DepKind; - switch (Dependences[i].first) { + switch (Data.Dependences[i].first) { case OMPC_DEPEND_in: DepKind = DepIn; break; @@ -3705,10 +3695,10 @@ void CGOpenMPRuntime::emitTaskCall( DepTaskArgs[5] = CGF.Builder.getInt32(0); DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy); } - auto &&ThenCodeGen = [this, Tied, Loc, NumberOfParts, TDBase, KmpTaskTQTyRD, + auto &&ThenCodeGen = [this, Loc, &Data, TDBase, KmpTaskTQTyRD, NumDependencies, &TaskArgs, &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) { - if (!Tied) { + if (!Data.Tied) { auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId); auto PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI); CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal); @@ -3775,22 +3765,16 @@ void CGOpenMPRuntime::emitTaskCall( } } -void CGOpenMPRuntime::emitTaskLoopCall( - CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D, - bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final, - llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule, bool Nogroup, - 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) { +void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc, + const OMPLoopDirective &D, + llvm::Value *TaskFunction, + QualType SharedsTy, Address Shareds, + const Expr *IfCond, + const OMPTaskDataTy &Data) { if (!CGF.HaveInsertPoint()) return; - TaskDataTy Data = - emitTaskInit(CGF, Loc, D, Tied, Final, NumberOfParts, TaskFunction, - SharedsTy, Shareds, PrivateVars, PrivateCopies, - FirstprivateVars, FirstprivateCopies, FirstprivateInits); + TaskResultTy Result = + emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data); // NOTE: routine and part_id fields are intialized by __kmpc_omp_task_alloc() // libcall. // 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); LValue LBLVal = CGF.EmitLValueForField( - Data.TDBase, - *std::next(Data.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound)); + Result.TDBase, + *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound)); auto *LBVar = cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl()); CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(), LBLVal.getQuals(), /*IsInitializer=*/true); LValue UBLVal = CGF.EmitLValueForField( - Data.TDBase, - *std::next(Data.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound)); + Result.TDBase, + *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound)); auto *UBVar = cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl()); CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(), UBLVal.getQuals(), /*IsInitializer=*/true); LValue StLVal = CGF.EmitLValueForField( - Data.TDBase, - *std::next(Data.KmpTaskTQTyRD->field_begin(), KmpTaskTStride)); + Result.TDBase, + *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride)); auto *StVar = cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl()); CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(), /*IsInitializer=*/true); enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 }; llvm::Value *TaskArgs[] = { - UpLoc, ThreadID, Data.NewTask, IfVal, LBLVal.getPointer(), + UpLoc, ThreadID, Result.NewTask, IfVal, LBLVal.getPointer(), 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( - CGF.IntTy, Schedule.getPointer() - ? Schedule.getInt() ? NumTasks : Grainsize + CGF.IntTy, Data.Schedule.getPointer() + ? Data.Schedule.getInt() ? NumTasks : Grainsize : NoSchedule), - Schedule.getPointer() - ? CGF.Builder.CreateIntCast(Schedule.getPointer(), CGF.Int64Ty, + Data.Schedule.getPointer() + ? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty, /*isSigned=*/false) : llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0), llvm::ConstantPointerNull::get(CGF.VoidPtrTy)}; diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h index 19eb3622f0a1851a171b5e0703a0b8915f19fc97..25d6909dc8ef0f430ee99da3c0e213f29c528027 100644 --- a/lib/CodeGen/CGOpenMPRuntime.h +++ b/lib/CodeGen/CGOpenMPRuntime.h @@ -87,6 +87,20 @@ public: 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 { protected: CodeGenModule &CGM; @@ -433,12 +447,12 @@ private: /// llvm::Value *getCriticalRegionLock(StringRef CriticalName); - struct TaskDataTy { - llvm::Value *NewTask; - llvm::Value *TaskEntry; - llvm::Value *NewTaskNewTaskTTy; + struct TaskResultTy { + llvm::Value *NewTask = nullptr; + llvm::Value *TaskEntry = nullptr; + llvm::Value *NewTaskNewTaskTTy = nullptr; LValue TDBase; - RecordDecl *KmpTaskTQTyRD; + RecordDecl *KmpTaskTQTyRD = nullptr; }; /// Emit task region for the task directive. The task region is emitted in /// several steps: @@ -455,39 +469,17 @@ private: /// 3. Copy a pointer to destructions function to field destructions of the /// resulting structure kmp_task_t. /// \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 /// /*part_id*/, captured_struct */*__context*/); /// \param SharedsTy A type which contains references the shared variables. /// \param Shareds Context with the list of shared variables from the \p /// TaskFunction. - /// \param PrivateVars List of references to private variables for the task - /// directive. - /// \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. - 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); + /// \param Data Additional data for task generation like tiednsee, final + /// state, list of privates etc. + TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, + const OMPExecutableDirective &D, + llvm::Value *TaskFunction, QualType SharedsTy, + Address Shareds, const OMPTaskDataTy &Data); public: explicit CGOpenMPRuntime(CodeGenModule &CGM); @@ -794,13 +786,6 @@ public: /// kmp_task_t *new_task), where new_task is a resulting structure from /// previous items. /// \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 /// /*part_id*/, captured_struct */*__context*/); /// \param SharedsTy A type which contains references the shared variables. @@ -808,29 +793,13 @@ public: /// TaskFunction. /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr /// otherwise. - /// \param PrivateVars List of references to private variables for the task - /// directive. - /// \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. - /// \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); + /// \param Data Additional data for task generation like tiednsee, final + /// state, list of privates etc. + virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc, + const OMPExecutableDirective &D, + llvm::Value *TaskFunction, QualType SharedsTy, + Address Shareds, const Expr *IfCond, + const OMPTaskDataTy &Data); /// Emit task region for the taskloop directive. The taskloop region is /// emitted in several steps: @@ -852,17 +821,6 @@ public: /// is a resulting structure from /// previous items. /// \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 /// /*part_id*/, captured_struct */*__context*/); /// \param SharedsTy A type which contains references the shared variables. @@ -870,27 +828,12 @@ public: /// TaskFunction. /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr /// otherwise. - /// \param PrivateVars List of references to private variables for the task - /// directive. - /// \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. + /// \param Data Additional data for task generation like tiednsee, final + /// state, list of privates etc. virtual void emitTaskLoopCall( CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D, - bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final, - llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule, bool Nogroup, - 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); + llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds, + const Expr *IfCond, const OMPTaskDataTy &Data); /// \brief Emit code for the directive that does not require outlining. /// diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index ae783f5dde74abce245268ec93892005f12fc76e..66641c2cacb03895593b9ec91141e13fcf7e538d 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -2312,18 +2312,30 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective( void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, const TaskGenTy &TaskGen, - bool Tied) { + OMPTaskDataTy &Data) { // Emit outlined function for task construct. auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); auto *I = CS->getCapturedDecl()->param_begin(); auto *PartId = std::next(I); 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 // part id (0 for tied tasks, >=0 for untied task). llvm::DenseSet<const VarDecl *> EmittedAsPrivate; // Get list of private variables. - OMPPrivateDataTy Data; - Data.Tied = Tied; for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { auto IRef = C->varlist_begin(); for (auto *IInit : C->private_copies()) { @@ -2406,23 +2418,6 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) { // Emit outlined function for task construct. auto CS = cast<CapturedStmt>(S.getAssociatedStmt()); 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()); const Expr *IfCond = nullptr; 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 &) { CGF.EmitStmt(CS->getCapturedStmt()); }; - auto &&TaskGen = [&S, &Final, SharedsTy, CapturedStruct, + auto &&TaskGen = [&S, SharedsTy, CapturedStruct, IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn, - const OMPPrivateDataTy &Data) { - CGF.CGM.getOpenMPRuntime().emitTaskCall( - CGF, S.getLocStart(), S, Data.Tied, Final, Data.NumberOfParts, - OutlinedFn, SharedsTy, CapturedStruct, IfCond, Data.PrivateVars, - Data.PrivateCopies, Data.FirstprivateVars, Data.FirstprivateCopies, - Data.FirstprivateInits, Data.Dependences); + const OMPTaskDataTy &Data) { + CGF.CGM.getOpenMPRuntime().emitTaskCall(CGF, S.getLocStart(), S, OutlinedFn, + SharedsTy, CapturedStruct, IfCond, + Data); }; - EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Tied); + EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data); } void CodeGenFunction::EmitOMPTaskyieldDirective( @@ -3345,34 +3341,21 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) { 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. - // 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); - } - llvm::PointerIntPair<llvm::Value * /*no grainsize/num_tasks=nullptr*/, 1, - bool /*Grainsize=false, NumTasks=true*/> - Schedule; + Data.Tied = true; + // Set scheduling for taskloop if (const auto* Clause = S.getSingleClause<OMPGrainsizeClause>()) { // grainsize clause - Schedule.setInt(/*IntVal=*/false); - Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize())); + Data.Schedule.setInt(/*IntVal=*/false); + Data.Schedule.setPointer(EmitScalarExpr(Clause->getGrainsize())); } else if (const auto* Clause = S.getSingleClause<OMPNumTasksClause>()) { // num_tasks clause - Schedule.setInt(/*IntVal=*/true); - Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks())); + Data.Schedule.setInt(/*IntVal=*/true); + Data.Schedule.setPointer(EmitScalarExpr(Clause->getNumTasks())); } auto &&BodyGen = [CS, &S](CodeGenFunction &CGF, PrePostActionTy &) { @@ -3445,21 +3428,19 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) { CGF.EmitBlock(ContBlock, true); } }; - auto &&TaskGen = [&S, SharedsTy, CapturedStruct, IfCond, &Final, &Schedule, - Nogroup](CodeGenFunction &CGF, llvm::Value *OutlinedFn, - const OMPPrivateDataTy &Data) { + auto &&TaskGen = [&S, SharedsTy, CapturedStruct, + IfCond](CodeGenFunction &CGF, llvm::Value *OutlinedFn, + const OMPTaskDataTy &Data) { auto &&CodeGen = [&](CodeGenFunction &CGF, PrePostActionTy &) { OMPLoopScope PreInitScope(CGF, S); - CGF.CGM.getOpenMPRuntime().emitTaskLoopCall( - CGF, S.getLocStart(), S, Data.Tied, Final, Schedule, Nogroup, - Data.NumberOfParts, OutlinedFn, SharedsTy, CapturedStruct, IfCond, - Data.PrivateVars, Data.PrivateCopies, Data.FirstprivateVars, - Data.FirstprivateCopies, Data.FirstprivateInits); + CGF.CGM.getOpenMPRuntime().emitTaskLoopCall(CGF, S.getLocStart(), S, + OutlinedFn, SharedsTy, + CapturedStruct, IfCond, Data); }; CGF.CGM.getOpenMPRuntime().emitInlinedDirective(CGF, OMPD_taskloop, CodeGen); }; - EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, /*Tied=*/true); + EmitOMPTaskBasedDirective(S, BodyGen, TaskGen, Data); } void CodeGenFunction::EmitOMPTaskLoopDirective(const OMPTaskLoopDirective &S) { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 8c725e267df8e0db8ce226f8d1bb79f20c5aa2e6..c1a892173f7df5043ec8656f91aec243409779f3 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -87,6 +87,7 @@ class BlockFlags; class BlockFieldFlags; class RegionCodeGenTy; class TargetCodeGenInfo; +struct OMPTaskDataTy; /// The kind of evaluation to perform on values of a particular /// type. Basically, is the code in CGExprScalar, CGExprComplex, or @@ -2346,23 +2347,13 @@ public: /// \param D Directive (possibly) with the 'linear' clause. 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*/, llvm::Value * /*OutlinedFn*/, - const OMPPrivateDataTy & /*Data*/)> + const OMPTaskDataTy & /*Data*/)> TaskGenTy; void EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, const RegionCodeGenTy &BodyGen, - const TaskGenTy &TaskGen, bool Tied); + const TaskGenTy &TaskGen, OMPTaskDataTy &Data); void EmitOMPParallelDirective(const OMPParallelDirective &S); void EmitOMPSimdDirective(const OMPSimdDirective &S);