================ @@ -14853,6 +14861,158 @@ StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt, buildPreInits(Context, PreInits)); } +StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc) { + ASTContext &Context = getASTContext(); + DeclContext *CurContext = SemaRef.CurContext; + Scope *CurScope = SemaRef.getCurScope(); + + // Empty statement should only be possible if there already was an error. + if (!AStmt) + return StmtError(); + + // interchange without permutation clause swaps two loops. + constexpr size_t NumLoops = 2; + + // Verify and diagnose loop nest. + SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); + Stmt *Body = nullptr; + SmallVector<SmallVector<Stmt *, 0>, 2> OriginalInits; + if (!checkTransformableLoopNest(OMPD_interchange, AStmt, NumLoops, + LoopHelpers, Body, OriginalInits)) + return StmtError(); + + // Delay interchange to when template is completely instantiated. + if (CurContext->isDependentContext()) + return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses, + NumLoops, AStmt, nullptr, nullptr); + + assert(LoopHelpers.size() == NumLoops && + "Expecting loop iteration space dimensionaly to match number of " + "affected loops"); + assert(OriginalInits.size() == NumLoops && + "Expecting loop iteration space dimensionaly to match number of " + "affected loops"); + + // Decode the permutation clause. + constexpr uint64_t Permutation[] = {1, 0}; + + // Find the affected loops. + SmallVector<Stmt *> LoopStmts(NumLoops, nullptr); + collectLoopStmts(AStmt, LoopStmts); + + // Collect pre-init statements on the order before the permuation. + SmallVector<Stmt *> PreInits; + for (auto I : llvm::seq<int>(NumLoops)) { + OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; + + assert(LoopHelper.Counters.size() == 1 && + "Single-dimensional loop iteration space expected"); + auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); + + std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); ---------------- Meinersbur wrote:
I don't get this. `getAsString` returns an `std::string` r-value. Assigning it to a `SmallString` will unpack that `std::string` and copy it over to `SmallString`'s buffer, compared to RVO where no additional copy happens. Furthermore, contemporary implementations of `std::string` are [already using a small-size buffer](https://devblogs.microsoft.com/oldnewthing/20240510-00/?p=109742). I guess I could call `OrigCntVar->getNameInfo().operator<<`, and pass a `raw_svector_ostream` instantiated using a `SmallString`. This would enable us to choose a larger small buffer size ourselves. Is that what you are asking for? If so, what should the small buffer size be? https://github.com/llvm/llvm-project/pull/93022 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits