forked from OSchip/llvm-project
[OPENMP 4.5] Codegen for 'hint' clause of 'critical' directive
OpenMP 4.5 defines 'hint' clause for 'critical' directive. Patch adds codegen for this clause. llvm-svn: 255639
This commit is contained in:
parent
3ba9cf6020
commit
fc57d1601d
|
@ -557,6 +557,17 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
|
|||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_critical_with_hint: {
|
||||
// Build void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit, uintptr_t hint);
|
||||
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
|
||||
llvm::PointerType::getUnqual(KmpCriticalNameTy),
|
||||
CGM.IntPtrTy};
|
||||
llvm::FunctionType *FnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
|
||||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical_with_hint");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_threadprivate_register: {
|
||||
// Build void __kmpc_threadprivate_register(ident_t *, void *data,
|
||||
// kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
|
||||
|
@ -1369,22 +1380,29 @@ public:
|
|||
void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
|
||||
StringRef CriticalName,
|
||||
const RegionCodeGenTy &CriticalOpGen,
|
||||
SourceLocation Loc) {
|
||||
// __kmpc_critical(ident_t *, gtid, Lock);
|
||||
SourceLocation Loc, const Expr *Hint) {
|
||||
// __kmpc_critical[_with_hint](ident_t *, gtid, Lock[, hint]);
|
||||
// CriticalOpGen();
|
||||
// __kmpc_end_critical(ident_t *, gtid, Lock);
|
||||
// Prepare arguments and build a call to __kmpc_critical
|
||||
{
|
||||
CodeGenFunction::RunCleanupsScope Scope(CGF);
|
||||
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
|
||||
getCriticalRegionLock(CriticalName)};
|
||||
CodeGenFunction::RunCleanupsScope Scope(CGF);
|
||||
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
|
||||
getCriticalRegionLock(CriticalName)};
|
||||
if (Hint) {
|
||||
llvm::SmallVector<llvm::Value *, 8> ArgsWithHint(std::begin(Args),
|
||||
std::end(Args));
|
||||
auto *HintVal = CGF.EmitScalarExpr(Hint);
|
||||
ArgsWithHint.push_back(
|
||||
CGF.Builder.CreateIntCast(HintVal, CGM.IntPtrTy, /*isSigned=*/false));
|
||||
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_critical_with_hint),
|
||||
ArgsWithHint);
|
||||
} else
|
||||
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_critical), Args);
|
||||
// Build a call to __kmpc_end_critical
|
||||
CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
|
||||
NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_critical),
|
||||
llvm::makeArrayRef(Args));
|
||||
emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
|
||||
}
|
||||
// Build a call to __kmpc_end_critical
|
||||
CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
|
||||
NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_critical),
|
||||
llvm::makeArrayRef(Args));
|
||||
emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
|
||||
}
|
||||
|
||||
static void emitIfStmt(CodeGenFunction &CGF, llvm::Value *IfCond,
|
||||
|
|
|
@ -62,6 +62,9 @@ private:
|
|||
// Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_critical,
|
||||
// Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32
|
||||
// global_tid, kmp_critical_name *crit, uintptr_t hint);
|
||||
OMPRTL__kmpc_critical_with_hint,
|
||||
// Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_end_critical,
|
||||
|
@ -420,9 +423,11 @@ public:
|
|||
/// \param CriticalName Name of the critical region.
|
||||
/// \param CriticalOpGen Generator for the statement associated with the given
|
||||
/// critical region.
|
||||
/// \param Hint Value of the 'hint' clause (optional).
|
||||
virtual void emitCriticalRegion(CodeGenFunction &CGF, StringRef CriticalName,
|
||||
const RegionCodeGenTy &CriticalOpGen,
|
||||
SourceLocation Loc);
|
||||
SourceLocation Loc,
|
||||
const Expr *Hint = nullptr);
|
||||
|
||||
/// \brief Emits a master region.
|
||||
/// \param MasterOpGen Generator for the statement associated with the given
|
||||
|
|
|
@ -1831,8 +1831,12 @@ void CodeGenFunction::EmitOMPCriticalDirective(const OMPCriticalDirective &S) {
|
|||
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
|
||||
CGF.EnsureInsertPoint();
|
||||
};
|
||||
CGM.getOpenMPRuntime().emitCriticalRegion(
|
||||
*this, S.getDirectiveName().getAsString(), CodeGen, S.getLocStart());
|
||||
Expr *Hint = nullptr;
|
||||
if (auto *HintClause = S.getSingleClause<OMPHintClause>())
|
||||
Hint = HintClause->getHint();
|
||||
CGM.getOpenMPRuntime().emitCriticalRegion(*this,
|
||||
S.getDirectiveName().getAsString(),
|
||||
CodeGen, S.getLocStart(), Hint);
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPParallelForDirective(
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
|
||||
// CHECK: [[UNNAMED_LOCK:@.+]] = common global [8 x i32] zeroinitializer
|
||||
// CHECK: [[THE_NAME_LOCK:@.+]] = common global [8 x i32] zeroinitializer
|
||||
// CHECK: [[THE_NAME_LOCK1:@.+]] = common global [8 x i32] zeroinitializer
|
||||
|
||||
// CHECK: define {{.*}}void [[FOO:@.+]]()
|
||||
|
||||
|
@ -32,6 +33,11 @@ int main() {
|
|||
// CHECK: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK]])
|
||||
#pragma omp critical(the_name)
|
||||
foo();
|
||||
// CHECK: call {{.*}}void @__kmpc_critical_with_hint([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]], i64 23)
|
||||
// CHECK-NEXT: invoke {{.*}}void [[FOO]]()
|
||||
// CHECK: call {{.*}}void @__kmpc_end_critical([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]], [8 x i32]* [[THE_NAME_LOCK1]])
|
||||
#pragma omp critical(the_name1) hint(23)
|
||||
foo();
|
||||
// CHECK-NOT: call void @__kmpc_critical
|
||||
// CHECK-NOT: call void @__kmpc_end_critical
|
||||
return a;
|
||||
|
|
Loading…
Reference in New Issue