diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-05-30 09:06:50 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-05-30 09:06:50 +0000 |
commit | ad537bb8a0095757a1aea4b3e019d2e967a8714b (patch) | |
tree | 9c579d23b0641604a64cec815583d435ccacea84 /clang/lib | |
parent | f353a5e06d961cac8e5f9ae86572396d7a1ffac6 (diff) | |
download | bcm5719-llvm-ad537bb8a0095757a1aea4b3e019d2e967a8714b.tar.gz bcm5719-llvm-ad537bb8a0095757a1aea4b3e019d2e967a8714b.zip |
[OPENMP 4.5] Fixed codegen for 'priority' and destructors in task-based
directives.
'kmp_task_t' record type added a new field for 'priority' clause and
changed the representation of pointer to destructors for privates used
within loop-based directives.
Old representation:
typedef struct kmp_task { /* GEH: Shouldn't this be
aligned somehow? */
void *shareds; /**< pointer to block of
pointers to shared vars */
kmp_routine_entry_t routine; /**< pointer to routine
to call for executing task */
kmp_int32 part_id; /**< part id for the
task */
kmp_routine_entry_t destructors; /* pointer to function to
invoke deconstructors of firstprivate C++ objects */
/* private vars */
} kmp_task_t;
New representation:
typedef struct kmp_task { /* GEH: Shouldn't this be
aligned somehow? */
void *shareds; /**< pointer to block of
pointers to shared vars */
kmp_routine_entry_t routine; /**< pointer to routine
to call for executing task */
kmp_int32 part_id; /**< part id for the
task */
kmp_cmplrdata_t data1; /* Two known
optional additions: destructors and priority */
kmp_cmplrdata_t data2; /* Process
destructors first, priority second */
/* future data */
/* private vars */
} kmp_task_t;
Also excessive initialization of 'destructors' fields to 'null' was
removed from codegen if it is known that no destructors shal be used.
Currently a special bit is used in 'kmp_tasking_flags_t' bitfields
('destructors_thunk' bitfield).
llvm-svn: 271201
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 52 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 4 |
2 files changed, 41 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 50ee50b7a16..dd07d0f3433 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2653,8 +2653,10 @@ enum KmpTaskTFields { KmpTaskTRoutine, /// \brief Partition id for the untied tasks. KmpTaskTPartId, - /// \brief Function with call of destructors for private variables. - KmpTaskTDestructors, + /// Function with call of destructors for private variables. + Data1, + /// Task priority. + Data2, /// (Taskloops only) Lower bound. KmpTaskTLowerBound, /// (Taskloops only) Upper bound. @@ -3178,19 +3180,27 @@ createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind, // void * shareds; // kmp_routine_entry_t routine; // kmp_int32 part_id; - // kmp_routine_entry_t destructors; + // kmp_cmplrdata_t data1; + // kmp_cmplrdata_t data2; // For taskloops additional fields: // kmp_uint64 lb; // kmp_uint64 ub; // kmp_int64 st; // kmp_int32 liter; // }; + auto *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union); + UD->startDefinition(); + addFieldToRecordDecl(C, UD, KmpInt32Ty); + addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy); + UD->completeDefinition(); + QualType KmpCmplrdataTy = C.getRecordType(UD); auto *RD = C.buildImplicitRecord("kmp_task_t"); RD->startDefinition(); addFieldToRecordDecl(C, RD, C.VoidPtrTy); addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy); addFieldToRecordDecl(C, RD, KmpInt32Ty); - addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy); + addFieldToRecordDecl(C, RD, KmpCmplrdataTy); + addFieldToRecordDecl(C, RD, KmpCmplrdataTy); if (isOpenMPTaskLoopDirective(Kind)) { QualType KmpUInt64Ty = CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); @@ -3805,18 +3815,30 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc, /*WithLastIter=*/!Data.LastprivateVars.empty()); } } + // Fields of union "kmp_cmplrdata_t" for destructors and priority. + enum { Priority = 0, Destructors = 1 }; // Provide pointer to function with destructors for privates. - llvm::Value *DestructorFn = - NeedsCleanup ? emitDestructorsFunction(CGM, Loc, KmpInt32Ty, - KmpTaskTWithPrivatesPtrQTy, - KmpTaskTWithPrivatesQTy) - : llvm::ConstantPointerNull::get( - cast<llvm::PointerType>(KmpRoutineEntryPtrTy)); - LValue Destructor = CGF.EmitLValueForField( - TDBase, *std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTDestructors)); - CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( - DestructorFn, KmpRoutineEntryPtrTy), - Destructor); + auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1); + auto *KmpCmplrdataUD = (*FI)->getType()->getAsUnionType()->getDecl(); + if (NeedsCleanup) { + llvm::Value *DestructorFn = emitDestructorsFunction( + CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy, + KmpTaskTWithPrivatesQTy); + LValue Data1LV = CGF.EmitLValueForField(TDBase, *FI); + LValue DestructorsLV = CGF.EmitLValueForField( + Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors)); + CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( + DestructorFn, KmpRoutineEntryPtrTy), + DestructorsLV); + } + // Set priority. + if (Data.Priority.getInt()) { + LValue Data2LV = CGF.EmitLValueForField( + TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2)); + LValue PriorityLV = CGF.EmitLValueForField( + Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority)); + CGF.EmitStoreOfScalar(Data.Priority.getPointer(), PriorityLV); + } Result.NewTask = NewTask; Result.TaskEntry = TaskEntry; Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy; diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 2f4a2c7f7b6..89d47e567c2 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -2371,6 +2371,10 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S, // TODO: Add codegen for priority clause arg when runtime lib support it. auto *Prio = Clause->getPriority(); Data.Priority.setInt(Prio); + Data.Priority.setPointer(EmitScalarConversion( + EmitScalarExpr(Prio), Prio->getType(), + getContext().getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1), + Prio->getExprLoc())); } // 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). |