summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp178
1 files changed, 100 insertions, 78 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 873c7525830..45f07a8406f 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -138,6 +138,10 @@ public:
} // namespace
+static void emitCommonOMPTargetDirective(CodeGenFunction &CGF,
+ const OMPExecutableDirective &S,
+ const RegionCodeGenTy &CodeGen);
+
LValue CodeGenFunction::EmitOMPSharedLValue(const Expr *E) {
if (auto *OrigDRE = dyn_cast<DeclRefExpr>(E)) {
if (auto *OrigVD = dyn_cast<VarDecl>(OrigDRE->getDecl())) {
@@ -1536,83 +1540,90 @@ static void emitOMPLoopBodyWithStopPoint(CodeGenFunction &CGF,
CGF.EmitStopPoint(&S);
}
-void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
- auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
- OMPLoopScope PreInitScope(CGF, S);
- // if (PreCond) {
- // for (IV in 0..LastIteration) BODY;
- // <Final counter/linear vars updates>;
- // }
- //
+static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
+ PrePostActionTy &Action) {
+ Action.Enter(CGF);
+ assert(isOpenMPSimdDirective(S.getDirectiveKind()) &&
+ "Expected simd directive");
+ OMPLoopScope PreInitScope(CGF, S);
+ // if (PreCond) {
+ // for (IV in 0..LastIteration) BODY;
+ // <Final counter/linear vars updates>;
+ // }
+ //
- // Emit: if (PreCond) - begin.
- // If the condition constant folds and can be elided, avoid emitting the
- // whole loop.
- bool CondConstant;
- llvm::BasicBlock *ContBlock = nullptr;
- if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
- if (!CondConstant)
- return;
- } else {
- auto *ThenBlock = CGF.createBasicBlock("simd.if.then");
- ContBlock = CGF.createBasicBlock("simd.if.end");
- emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
- CGF.getProfileCount(&S));
- CGF.EmitBlock(ThenBlock);
- CGF.incrementProfileCounter(&S);
- }
+ // Emit: if (PreCond) - begin.
+ // If the condition constant folds and can be elided, avoid emitting the
+ // whole loop.
+ bool CondConstant;
+ llvm::BasicBlock *ContBlock = nullptr;
+ if (CGF.ConstantFoldsToSimpleInteger(S.getPreCond(), CondConstant)) {
+ if (!CondConstant)
+ return;
+ } else {
+ auto *ThenBlock = CGF.createBasicBlock("simd.if.then");
+ ContBlock = CGF.createBasicBlock("simd.if.end");
+ emitPreCond(CGF, S, S.getPreCond(), ThenBlock, ContBlock,
+ CGF.getProfileCount(&S));
+ CGF.EmitBlock(ThenBlock);
+ CGF.incrementProfileCounter(&S);
+ }
- // Emit the loop iteration variable.
- const Expr *IVExpr = S.getIterationVariable();
- const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
- CGF.EmitVarDecl(*IVDecl);
- CGF.EmitIgnoredExpr(S.getInit());
+ // Emit the loop iteration variable.
+ const Expr *IVExpr = S.getIterationVariable();
+ const VarDecl *IVDecl = cast<VarDecl>(cast<DeclRefExpr>(IVExpr)->getDecl());
+ CGF.EmitVarDecl(*IVDecl);
+ CGF.EmitIgnoredExpr(S.getInit());
- // Emit the iterations count variable.
- // If it is not a variable, Sema decided to calculate iterations count on
- // each iteration (e.g., it is foldable into a constant).
- if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
- CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
- // Emit calculation of the iterations count.
- CGF.EmitIgnoredExpr(S.getCalcLastIteration());
- }
+ // Emit the iterations count variable.
+ // If it is not a variable, Sema decided to calculate iterations count on
+ // each iteration (e.g., it is foldable into a constant).
+ if (auto LIExpr = dyn_cast<DeclRefExpr>(S.getLastIteration())) {
+ CGF.EmitVarDecl(*cast<VarDecl>(LIExpr->getDecl()));
+ // Emit calculation of the iterations count.
+ CGF.EmitIgnoredExpr(S.getCalcLastIteration());
+ }
- CGF.EmitOMPSimdInit(S);
+ CGF.EmitOMPSimdInit(S);
- emitAlignedClause(CGF, S);
- (void)CGF.EmitOMPLinearClauseInit(S);
- {
- OMPPrivateScope LoopScope(CGF);
- CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
- CGF.EmitOMPLinearClause(S, LoopScope);
- CGF.EmitOMPPrivateClause(S, LoopScope);
- CGF.EmitOMPReductionClauseInit(S, LoopScope);
- bool HasLastprivateClause =
- CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
- (void)LoopScope.Privatize();
- CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
- S.getInc(),
- [&S](CodeGenFunction &CGF) {
- CGF.EmitOMPLoopBody(S, JumpDest());
- CGF.EmitStopPoint(&S);
- },
- [](CodeGenFunction &) {});
- CGF.EmitOMPSimdFinal(
- S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
- // Emit final copy of the lastprivate variables at the end of loops.
- if (HasLastprivateClause)
- CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
- CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
- emitPostUpdateForReductionClause(
- CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
- }
- CGF.EmitOMPLinearClauseFinal(
+ emitAlignedClause(CGF, S);
+ (void)CGF.EmitOMPLinearClauseInit(S);
+ {
+ CodeGenFunction::OMPPrivateScope LoopScope(CGF);
+ CGF.EmitOMPPrivateLoopCounters(S, LoopScope);
+ CGF.EmitOMPLinearClause(S, LoopScope);
+ CGF.EmitOMPPrivateClause(S, LoopScope);
+ CGF.EmitOMPReductionClauseInit(S, LoopScope);
+ bool HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
+ (void)LoopScope.Privatize();
+ CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
+ S.getInc(),
+ [&S](CodeGenFunction &CGF) {
+ CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
+ CGF.EmitStopPoint(&S);
+ },
+ [](CodeGenFunction &) {});
+ CGF.EmitOMPSimdFinal(
S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
- // Emit: if (PreCond) - end.
- if (ContBlock) {
- CGF.EmitBranch(ContBlock);
- CGF.EmitBlock(ContBlock, true);
- }
+ // Emit final copy of the lastprivate variables at the end of loops.
+ if (HasLastprivateClause)
+ CGF.EmitOMPLastprivateClauseFinal(S, /*NoFinals=*/true);
+ CGF.EmitOMPReductionClauseFinal(S, /*ReductionKind=*/OMPD_simd);
+ emitPostUpdateForReductionClause(
+ CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
+ }
+ CGF.EmitOMPLinearClauseFinal(
+ S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
+ // Emit: if (PreCond) - end.
+ if (ContBlock) {
+ CGF.EmitBranch(ContBlock);
+ CGF.EmitBlock(ContBlock, true);
+ }
+}
+
+void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
+ auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+ emitOMPSimdRegion(CGF, S, Action);
};
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
@@ -2027,15 +2038,26 @@ void CodeGenFunction::EmitOMPDistributeSimdDirective(
});
}
+void CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
+ CodeGenModule &CGM, StringRef ParentName, const OMPTargetSimdDirective &S) {
+ // Emit SPMD target parallel for region as a standalone region.
+ auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+ emitOMPSimdRegion(CGF, S, Action);
+ };
+ llvm::Function *Fn;
+ llvm::Constant *Addr;
+ // Emit target region as a standalone region.
+ CGM.getOpenMPRuntime().emitTargetOutlinedFunction(
+ S, ParentName, Fn, Addr, /*IsOffloadEntry=*/true, CodeGen);
+ assert(Fn && Addr && "Target device function emission failed.");
+}
+
void CodeGenFunction::EmitOMPTargetSimdDirective(
const OMPTargetSimdDirective &S) {
- OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
- CGM.getOpenMPRuntime().emitInlinedDirective(
- *this, OMPD_target_simd, [&S](CodeGenFunction &CGF, PrePostActionTy &) {
- OMPLoopScope PreInitScope(CGF, S);
- CGF.EmitStmt(
- cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
- });
+ auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &Action) {
+ emitOMPSimdRegion(CGF, S, Action);
+ };
+ emitCommonOMPTargetDirective(*this, S, CodeGen);
}
void CodeGenFunction::EmitOMPTeamsDistributeSimdDirective(
OpenPOWER on IntegriCloud