From: Alexey Bataev Date: Wed, 16 May 2018 13:36:30 +0000 (+0000) Subject: [OPENMP, NVPTX] Add check for SPMD mode in orphaned parallel directives. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b168e230125d2e58503309017b6f6addbcb225a3;p=clang [OPENMP, NVPTX] Add check for SPMD mode in orphaned parallel directives. If the orphaned directive is executed in SPMD mode, we need to emit the check for the SPMD mode and run the orphaned parallel directive in sequential mode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@332467 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp index 1f5bfee41b..559a26f6f3 100644 --- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -96,6 +96,8 @@ enum OpenMPRTLFunctionNVPTX { /// Call to uint16_t __kmpc_parallel_level(ident_t *loc, kmp_int32 /// global_tid); OMPRTL_NVPTX__kmpc_parallel_level, + /// Call to int8_t __kmpc_is_spmd_exec_mode(); + OMPRTL_NVPTX__kmpc_is_spmd_exec_mode, }; /// Pre(post)-action for different OpenMP constructs specialized for NVPTX. @@ -220,8 +222,7 @@ class CheckVarsEscapingDeclContext final "Parameter captured by value with variably modified type"); EscapedParameters.insert(VD); } - } else if (VD->getType()->isAnyPointerType() || - VD->getType()->isReferenceType()) + } else if (VD->getType()->isReferenceType()) // Do not globalize variables with reference or pointer type. return; if (VD->getType()->isVariablyModifiedType()) @@ -317,8 +318,18 @@ public: return; if (D->hasAssociatedStmt()) { if (const auto *S = - dyn_cast_or_null(D->getAssociatedStmt())) + dyn_cast_or_null(D->getAssociatedStmt())) { + // Do not analyze directives that do not actually require capturing, + // like `omp for` or `omp simd` directives. + llvm::SmallVector CaptureRegions; + getOpenMPCaptureRegions(CaptureRegions, D->getDirectiveKind()); + if (CaptureRegions.size() == 1 && + CaptureRegions.back() == OMPD_unknown) { + VisitStmt(S->getCapturedStmt()); + return; + } VisitOpenMPCapturedStmt(S); + } } } void VisitCapturedStmt(const CapturedStmt *S) { @@ -1411,6 +1422,12 @@ CGOpenMPRuntimeNVPTX::createNVPTXRuntimeFunction(unsigned Function) { RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_parallel_level"); break; } + case OMPRTL_NVPTX__kmpc_is_spmd_exec_mode: { + // Build int8_t __kmpc_is_spmd_exec_mode(); + auto *FnTy = llvm::FunctionType::get(CGM.Int8Ty, /*isVarArg=*/false); + RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_is_spmd_exec_mode"); + break; + } } return RTLFn; } @@ -1828,7 +1845,9 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDParallelCall( RCG(CGF); } else { // Check for master and then parallelism: - // if (is_master) { + // if (__kmpc_is_spmd_exec_mode()) { + // Serialized execution. + // } else if (is_master) { // Worker call. // } else if (__kmpc_parallel_level(loc, gtid)) { // Serialized execution. @@ -1837,13 +1856,22 @@ void CGOpenMPRuntimeNVPTX::emitNonSPMDParallelCall( // } CGBuilderTy &Bld = CGF.Builder; llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".exit"); + llvm::BasicBlock *SPMDCheckBB = CGF.createBasicBlock(".spmdcheck"); llvm::BasicBlock *MasterCheckBB = CGF.createBasicBlock(".mastercheck"); llvm::BasicBlock *ParallelCheckBB = CGF.createBasicBlock(".parallelcheck"); + llvm::Value *IsSPMD = Bld.CreateIsNotNull(CGF.EmitNounwindRuntimeCall( + createNVPTXRuntimeFunction(OMPRTL_NVPTX__kmpc_is_spmd_exec_mode))); + Bld.CreateCondBr(IsSPMD, SPMDCheckBB, MasterCheckBB); + CGF.EmitBlock(SPMDCheckBB); + SeqGen(CGF, Action); + CGF.EmitBranch(ExitBB); + CGF.EmitBlock(MasterCheckBB); + llvm::BasicBlock *MasterThenBB = CGF.createBasicBlock("master.then"); llvm::Value *IsMaster = Bld.CreateICmpEQ(getNVPTXThreadID(CGF), getMasterThreadID(CGF)); - Bld.CreateCondBr(IsMaster, MasterCheckBB, ParallelCheckBB); - CGF.EmitBlock(MasterCheckBB); + Bld.CreateCondBr(IsMaster, MasterThenBB, ParallelCheckBB); + CGF.EmitBlock(MasterThenBB); L0ParallelGen(CGF, Action); CGF.EmitBranch(ExitBB); // There is no need to emit line number for unconditional branch. diff --git a/test/OpenMP/nvptx_target_codegen.cpp b/test/OpenMP/nvptx_target_codegen.cpp index 0a8e56106e..23dd23e86c 100644 --- a/test/OpenMP/nvptx_target_codegen.cpp +++ b/test/OpenMP/nvptx_target_codegen.cpp @@ -561,6 +561,16 @@ int baz(int f, double &a) { // CHECK: [[F_PTR:%.+]] = getelementptr inbounds %struct._globalized_locals_ty, %struct._globalized_locals_ty* [[REC_ADDR]], i32 0, i32 0 // CHECK: store i32 %{{.+}}, i32* [[F_PTR]], // CHECK: store i32 [[GTID]], i32* [[GTID_ADDR]], + + // CHECK: [[RES:%.+]] = call i8 @__kmpc_is_spmd_exec_mode() + // CHECK: icmp ne i8 [[RES]], 0 + // CHECK: br i1 + + // CHECK: call void @__kmpc_serialized_parallel(%struct.ident_t* @{{.+}}, i32 [[GTID]]) + // CHECK: call void [[OUTLINED:@.+]](i32* [[GTID_ADDR]], i32* [[ZERO_ADDR]], i32* [[F_PTR]], double* %{{.+}}) + // CHECK: call void @__kmpc_end_serialized_parallel(%struct.ident_t* @{{.+}}, i32 [[GTID]]) + // CHECK: br label + // CHECK: icmp eq i32 // CHECK: br i1