summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2019-10-07 18:54:57 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2019-10-07 18:54:57 +0000
commitbef93a98cd26012049b8e64bf27134885fcf9550 (patch)
tree570bd979ab05b9b5436561c794c9aa712a104eda /clang/lib/CodeGen/CGStmtOpenMP.cpp
parentb4cbf9862c415ab68725443c39c374573c7932e7 (diff)
downloadbcm5719-llvm-bef93a98cd26012049b8e64bf27134885fcf9550.tar.gz
bcm5719-llvm-bef93a98cd26012049b8e64bf27134885fcf9550.zip
[OPENMP50]Treat range-based for as canonical loop.
According to OpenMP 5.0, range-based for is also considered as a canonical form of loops. llvm-svn: 373939
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp33
1 files changed, 33 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 1ab6a8d963b..c70244d7794 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -142,6 +142,24 @@ class OMPLoopScope : public CodeGenFunction::RunCleanupsScope {
}
}
(void)PreCondVars.apply(CGF);
+ // Emit init, __range and __end variables for C++ range loops.
+ const Stmt *Body =
+ S.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
+ for (unsigned Cnt = 0; Cnt < S.getCollapsedNumber(); ++Cnt) {
+ Body = Body->IgnoreContainers();
+ if (auto *For = dyn_cast<ForStmt>(Body)) {
+ Body = For->getBody();
+ } else {
+ assert(isa<CXXForRangeStmt>(Body) &&
+ "Expected caonical for loop or range-based for loop.");
+ auto *CXXFor = cast<CXXForRangeStmt>(Body);
+ if (const Stmt *Init = CXXFor->getInit())
+ CGF.EmitStmt(Init);
+ CGF.EmitStmt(CXXFor->getRangeStmt());
+ CGF.EmitStmt(CXXFor->getEndStmt());
+ Body = CXXFor->getBody();
+ }
+ }
if (const auto *PreInits = cast_or_null<DeclStmt>(S.getPreInits())) {
for (const auto *I : PreInits->decls())
CGF.EmitVarDecl(cast<VarDecl>(*I));
@@ -1350,6 +1368,21 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
getProfileCount(D.getBody()));
EmitBlock(NextBB);
}
+ // Emit loop variables for C++ range loops.
+ const Stmt *Body =
+ D.getInnermostCapturedStmt()->getCapturedStmt()->IgnoreContainers();
+ for (unsigned Cnt = 0; Cnt < D.getCollapsedNumber(); ++Cnt) {
+ Body = Body->IgnoreContainers();
+ if (auto *For = dyn_cast<ForStmt>(Body)) {
+ Body = For->getBody();
+ } else {
+ assert(isa<CXXForRangeStmt>(Body) &&
+ "Expected caonical for loop or range-based for loop.");
+ auto *CXXFor = cast<CXXForRangeStmt>(Body);
+ EmitStmt(CXXFor->getLoopVarStmt());
+ Body = CXXFor->getBody();
+ }
+ }
// Emit loop body.
EmitStmt(D.getBody());
// The end (updates/cleanups).
OpenPOWER on IntegriCloud