summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2018-05-16 13:36:30 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2018-05-16 13:36:30 +0000
commit673110d5d5af03e43fda9c2f640e9a45518e5924 (patch)
treec7509fbfbb0da5c6ff8db39147b7ddbf368df811 /clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
parent2ba8fd4914a91beb116c39c008fc425e80f14a7c (diff)
downloadbcm5719-llvm-673110d5d5af03e43fda9c2f640e9a45518e5924.tar.gz
bcm5719-llvm-673110d5d5af03e43fda9c2f640e9a45518e5924.zip
[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. llvm-svn: 332467
Diffstat (limited to 'clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp')
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp40
1 files changed, 34 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 1f5bfee41bd..559a26f6f35 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/clang/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<CapturedStmt>(D->getAssociatedStmt()))
+ dyn_cast_or_null<CapturedStmt>(D->getAssociatedStmt())) {
+ // Do not analyze directives that do not actually require capturing,
+ // like `omp for` or `omp simd` directives.
+ llvm::SmallVector<OpenMPDirectiveKind, 4> 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.
OpenPOWER on IntegriCloud