[llvm-branch-commits] [clang] [flang] [llvm] [openmp] [Clang][OpenMP] Add reverse and interchange directives (PR #92030)
Alexey Bataev via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue May 14 03:28:09 PDT 2024
================
@@ -15745,6 +15760,388 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
buildPreInits(Context, PreInits));
}
+StmtResult
+SemaOpenMP::ActOnOpenMPReverseDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ ASTContext &Context = getASTContext();
+ Scope *CurScope = SemaRef.getCurScope();
+ assert(Clauses.empty() && "reverse directive does not accept any clauses; "
+ "must have beed checked before");
+
+ // Empty statement should only be possible if there already was an error.
+ if (!AStmt)
+ return StmtError();
+
+ constexpr unsigned NumLoops = 1;
+ Stmt *Body = nullptr;
+ SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
+ NumLoops);
+ SmallVector<SmallVector<Stmt *, 0>, NumLoops + 1> OriginalInits;
+ if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
+ Body, OriginalInits))
+ return StmtError();
+
+ // Delay applying the transformation to when template is completely
+ // instantiated.
+ if (SemaRef.CurContext->isDependentContext())
+ return OMPReverseDirective::Create(Context, StartLoc, EndLoc, Clauses,
+ AStmt, nullptr, nullptr);
+
+ assert(LoopHelpers.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+ assert(OriginalInits.size() == NumLoops &&
+ "Expecting a single-dimensional loop iteration space");
+ OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
+
+ // Find the loop statement.
+ Stmt *LoopStmt = nullptr;
+ collectLoopStmts(AStmt, {LoopStmt});
+
+ // Determine the PreInit declarations.
+ SmallVector<Stmt *> PreInits;
+ addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
+
+ auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
+ QualType IVTy = IterationVarRef->getType();
+ uint64_t IVWidth = Context.getTypeSize(IVTy);
+ auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
+
+ // Iteration variable SourceLocations.
+ SourceLocation OrigVarLoc = OrigVar->getExprLoc();
+ SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
+ SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
+
+ // Locations pointing to the transformation.
+ SourceLocation TransformLoc = StartLoc;
+ SourceLocation TransformLocBegin = StartLoc;
+ SourceLocation TransformLocEnd = EndLoc;
+
+ // Internal variable names.
+ std::string OrigVarName = OrigVar->getNameInfo().getAsString();
+ std::string TripCountName = (Twine(".tripcount.") + OrigVarName).str();
+ std::string ForwardIVName = (Twine(".forward.iv.") + OrigVarName).str();
+ std::string ReversedIVName = (Twine(".reversed.iv.") + OrigVarName).str();
+
+ // LoopHelper.Updates will read the logical iteration number from
+ // LoopHelper.IterationVarRef, compute the value of the user loop counter of
+ // that logical iteration from it, then assign it to the user loop counter
+ // variable. We cannot directly use LoopHelper.IterationVarRef as the
+ // induction variable of the generated loop because it may cause an underflow:
+ // \code
+ // for (unsigned i = 0; i < n; ++i)
+ // body(i);
+ // \endcode
+ //
+ // Naive reversal:
+ // \code
+ // for (unsigned i = n-1; i >= 0; ++i)
----------------
alexey-bataev wrote:
```suggestion
// for (unsigned i = n-1; i >= 0; --i)
```
https://github.com/llvm/llvm-project/pull/92030
More information about the llvm-branch-commits
mailing list