forked from OSchip/llvm-project
[OPENMP] Codegen for 'omp barrier' directive.
Adds generation of call to "i32 kmpc_cancel_barrier(ident_t *, i32)" libcall for explicitly specified barriers (OMP_IDENT_BARRIER_EXPL flag is added to "flags" field of "ident_t" structure). Also this patch replaces all calls to "kmpc_barrier" function by calls of "__kmpc_cancel_barrier" function which provides additional functionality for OpenMP 4.0. Also, library specific enum OpenMPLocationFlags moved to private section of CGOpenMPRuntime class to make it more independent from library implementation. Differential Revision: http://reviews.llvm.org/D6447 llvm-svn: 223444
This commit is contained in:
parent
1d21a07ca1
commit
8f7c1b0b9d
|
@ -73,14 +73,10 @@ void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, Stmt *S) {
|
|||
CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
|
||||
CGF.EmitOMPPrivateClause(Directive, PrivateScope);
|
||||
CGF.EmitOMPFirstprivateClause(Directive, PrivateScope);
|
||||
if (PrivateScope.Privatize()) {
|
||||
if (PrivateScope.Privatize())
|
||||
// Emit implicit barrier to synchronize threads and avoid data races.
|
||||
auto Flags = static_cast<CGOpenMPRuntime::OpenMPLocationFlags>(
|
||||
CGOpenMPRuntime::OMP_IDENT_KMPC |
|
||||
CGOpenMPRuntime::OMP_IDENT_BARRIER_IMPL);
|
||||
CGF.CGM.getOpenMPRuntime().EmitOMPBarrierCall(CGF, Directive.getLocStart(),
|
||||
Flags);
|
||||
}
|
||||
/*IsExplicit=*/false);
|
||||
CGCapturedStmtInfo::EmitBody(CGF, S);
|
||||
}
|
||||
|
||||
|
@ -327,12 +323,13 @@ CGOpenMPRuntime::CreateRuntimeFunction(OpenMPRTLFunction Function) {
|
|||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_barrier: {
|
||||
// Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
|
||||
case OMPRTL__kmpc_cancel_barrier: {
|
||||
// Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
|
||||
llvm::FunctionType *FnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
|
||||
RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
|
||||
llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
|
||||
RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_push_num_threads: {
|
||||
|
@ -699,12 +696,20 @@ void CGOpenMPRuntime::EmitOMPMasterRegion(
|
|||
}
|
||||
|
||||
void CGOpenMPRuntime::EmitOMPBarrierCall(CodeGenFunction &CGF,
|
||||
SourceLocation Loc,
|
||||
OpenMPLocationFlags Flags) {
|
||||
// Build call __kmpc_barrier(loc, thread_id)
|
||||
SourceLocation Loc, bool IsExplicit) {
|
||||
// Build call __kmpc_cancel_barrier(loc, thread_id);
|
||||
auto Flags = static_cast<OpenMPLocationFlags>(
|
||||
OMP_IDENT_KMPC |
|
||||
(IsExplicit ? OMP_IDENT_BARRIER_EXPL : OMP_IDENT_BARRIER_IMPL));
|
||||
// Build call __kmpc_cancel_barrier(loc, thread_id);
|
||||
// Replace __kmpc_barrier() function by __kmpc_cancel_barrier() because this
|
||||
// one provides the same functionality and adds initial support for
|
||||
// cancellation constructs introduced in OpenMP 4.0. __kmpc_cancel_barrier()
|
||||
// is provided default by the runtime library so it safe to make such
|
||||
// replacement.
|
||||
llvm::Value *Args[] = {EmitOpenMPUpdateLocation(CGF, Loc, Flags),
|
||||
GetOpenMPThreadID(CGF, Loc)};
|
||||
auto RTLFn = CreateRuntimeFunction(OMPRTL__kmpc_barrier);
|
||||
auto RTLFn = CreateRuntimeFunction(OMPRTL__kmpc_cancel_barrier);
|
||||
CGF.EmitRuntimeCall(RTLFn, Args);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,46 @@ class CodeGenModule;
|
|||
|
||||
class CGOpenMPRuntime {
|
||||
public:
|
||||
|
||||
private:
|
||||
enum OpenMPRTLFunction {
|
||||
/// \brief Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
|
||||
/// kmpc_micro microtask, ...);
|
||||
OMPRTL__kmpc_fork_call,
|
||||
/// \brief Call to void *__kmpc_threadprivate_cached(ident_t *loc,
|
||||
/// kmp_int32 global_tid, void *data, size_t size, void ***cache);
|
||||
OMPRTL__kmpc_threadprivate_cached,
|
||||
/// \brief Call to void __kmpc_threadprivate_register( ident_t *,
|
||||
/// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
|
||||
OMPRTL__kmpc_threadprivate_register,
|
||||
// Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
|
||||
OMPRTL__kmpc_global_thread_num,
|
||||
// Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_critical,
|
||||
// Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_end_critical,
|
||||
// Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
OMPRTL__kmpc_cancel_barrier,
|
||||
// Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
OMPRTL__kmpc_serialized_parallel,
|
||||
// Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
OMPRTL__kmpc_end_serialized_parallel,
|
||||
// Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_int32 num_threads);
|
||||
OMPRTL__kmpc_push_num_threads,
|
||||
// Call to void __kmpc_flush(ident_t *loc, ...);
|
||||
OMPRTL__kmpc_flush,
|
||||
// Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_master,
|
||||
// Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_end_master,
|
||||
};
|
||||
|
||||
/// \brief Values for bit flags used in the ident_t to describe the fields.
|
||||
/// All enumeric elements are named and described in accordance with the code
|
||||
/// from http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
|
||||
|
@ -64,45 +104,6 @@ public:
|
|||
/// \brief Implicit barrier in 'single' directive.
|
||||
OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140
|
||||
};
|
||||
|
||||
private:
|
||||
enum OpenMPRTLFunction {
|
||||
/// \brief Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
|
||||
/// kmpc_micro microtask, ...);
|
||||
OMPRTL__kmpc_fork_call,
|
||||
/// \brief Call to void *__kmpc_threadprivate_cached(ident_t *loc,
|
||||
/// kmp_int32 global_tid, void *data, size_t size, void ***cache);
|
||||
OMPRTL__kmpc_threadprivate_cached,
|
||||
/// \brief Call to void __kmpc_threadprivate_register( ident_t *,
|
||||
/// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
|
||||
OMPRTL__kmpc_threadprivate_register,
|
||||
// Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
|
||||
OMPRTL__kmpc_global_thread_num,
|
||||
// Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_critical,
|
||||
// Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_critical_name *crit);
|
||||
OMPRTL__kmpc_end_critical,
|
||||
// Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_barrier,
|
||||
// Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
OMPRTL__kmpc_serialized_parallel,
|
||||
// Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
OMPRTL__kmpc_end_serialized_parallel,
|
||||
// Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
|
||||
// kmp_int32 num_threads);
|
||||
OMPRTL__kmpc_push_num_threads,
|
||||
// Call to void __kmpc_flush(ident_t *loc, ...);
|
||||
OMPRTL__kmpc_flush,
|
||||
// Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_master,
|
||||
// Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_end_master,
|
||||
};
|
||||
|
||||
CodeGenModule &CGM;
|
||||
/// \brief Default const ident_t object used for initialization of all other
|
||||
/// ident_t objects.
|
||||
|
@ -298,11 +299,11 @@ public:
|
|||
const std::function<void()> &MasterOpGen,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// \brief Emits a barrier for OpenMP threads.
|
||||
/// \param Flags Flags for the barrier.
|
||||
/// \brief Emits explicit barrier for OpenMP threads.
|
||||
/// \param IsExplicit true, if it is explicitly specified barrier.
|
||||
///
|
||||
virtual void EmitOMPBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||
OpenMPLocationFlags Flags);
|
||||
bool IsExplicit = true);
|
||||
|
||||
/// \brief Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32
|
||||
/// global_tid, kmp_int32 num_threads) to generate code for 'num_threads'
|
||||
|
|
|
@ -531,8 +531,8 @@ void CodeGenFunction::EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &) {
|
|||
llvm_unreachable("CodeGen for 'omp taskyield' is not supported yet.");
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &) {
|
||||
llvm_unreachable("CodeGen for 'omp barrier' is not supported yet.");
|
||||
void CodeGenFunction::EmitOMPBarrierDirective(const OMPBarrierDirective &S) {
|
||||
CGM.getOpenMPRuntime().EmitOMPBarrierCall(*this, S.getLocStart());
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &) {
|
||||
|
|
|
@ -112,7 +112,7 @@ int main() {
|
|||
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]]
|
||||
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK-DAG: call {{.*}} [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
|
||||
// CHECK: ret void
|
||||
|
@ -167,7 +167,7 @@ int main() {
|
|||
// CHECK: call {{.*}} [[ST_TY_DESTR]]([[ST_TY]]* [[ST_TY_TEMP]])
|
||||
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]]
|
||||
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK-DAG: call {{.*}} [[S_INT_TY_DESTR]]([[S_INT_TY]]*
|
||||
// CHECK: ret void
|
||||
|
|
|
@ -73,7 +73,7 @@ int main() {
|
|||
// CHECK: call {{.*}} [[S_FLOAT_TY_DEF_CONSTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]]
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]]
|
||||
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK-DAG: call void [[S_FLOAT_TY_DESTR]]([[S_FLOAT_TY]]*
|
||||
// CHECK: ret void
|
||||
|
@ -101,7 +101,7 @@ int main() {
|
|||
// CHECK: call {{.*}} [[S_INT_TY_DEF_CONSTR]]([[S_INT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}** [[GTID_ADDR_REF]]
|
||||
// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}* [[GTID_REF]]
|
||||
// CHECK: call void @__kmpc_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK: call i32 @__kmpc_cancel_barrier(%{{.+}}* [[IMPLICIT_BARRIER_LOC]], i{{[0-9]+}} [[GTID]])
|
||||
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]* [[VAR_PRIV]])
|
||||
// CHECK-DAG: call void [[S_INT_TY_DESTR]]([[S_INT_TY]]*
|
||||
// CHECK: ret void
|
||||
|
|
Loading…
Reference in New Issue