[PATCH] D111124: [Clang][OpenMP] Allow loop-transformations with template parameters.
Meinersbur created this revision. Meinersbur added reviewers: ABataev, jdenny. Meinersbur added projects: OpenMP, clang. Herald added subscribers: zzheng, guansong, yaxunl. Meinersbur requested review of this revision. Herald added a reviewer: jdoerfert. Herald added a subscriber: sstefan1. Clang would reject #pragma omp for #pragma omp tile sizes(P) for (int i = 0; i < 128; ++i) {} where P is a template parameter, but the loop itself is not template-dependent. Because P context-dependent, the TransformedStmt cannot be generated and therefore nullptr (until the template is instantiated). The OMPForDirective would still expect the a loop is the dependent context and trigger an error. Fix by introducing a NumGeneratedLoops field to OMPLoopTransformation. This is used to distinguish the case where no TransformedStmt will be generated at all (e.g. `#pragma omp unroll full`) and template instantiation is needed. In the later case, delay resolving the iteration space like when the for-loop itself is template-dependent until the template instatiation. A more radical solution would always delay the iteration space analysis until template instantiation, but would also break many test cases. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D24 Files: clang/include/clang/AST/StmtOpenMP.h clang/lib/AST/StmtOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/test/OpenMP/tile_ast_print.cpp clang/test/OpenMP/unroll_ast_print.cpp Index: clang/test/OpenMP/unroll_ast_print.cpp === --- clang/test/OpenMP/unroll_ast_print.cpp +++ clang/test/OpenMP/unroll_ast_print.cpp @@ -124,4 +124,26 @@ unroll_templated(); } + +// PRINT-LABEL: template void unroll_templated_factor(int start, int stop, int step) { +// DUMP-LABEL: FunctionTemplateDecl {{.*}} unroll_templated_factor +template +void unroll_templated_factor(int start, int stop, int step) { + // PRINT: #pragma omp unroll partial(Factor) + // DUMP: OMPUnrollDirective + // DUMP-NEXT: OMPPartialClause + // DUMP-NEXT: DeclRefExpr {{.*}} 'Factor' 'int' + #pragma omp unroll partial(Factor) +// PRINT-NEXT: for (int i = start; i < stop; i += step) +// DUMP-NEXT: ForStmt +for (int i = start; i < stop; i += step) + // PRINT-NEXT: body(i); + // DUMP: CallExpr + body(i); +} +void unroll_template_factor() { + unroll_templated_factor<4>(0, 42, 2); +} + + #endif Index: clang/test/OpenMP/tile_ast_print.cpp === --- clang/test/OpenMP/tile_ast_print.cpp +++ clang/test/OpenMP/tile_ast_print.cpp @@ -162,4 +162,25 @@ } +// PRINT-LABEL: template void foo7(int start, int stop, int step) { +// DUMP-LABEL: FunctionTemplateDecl {{.*}} foo7 +template +void foo7(int start, int stop, int step) { + // PRINT: #pragma omp tile sizes(Tile) + // DUMP: OMPTileDirective + // DUMP-NEXT: OMPSizesClause + // DUMP-NEXT: DeclRefExpr {{.*}} 'Tile' 'int' + #pragma omp tile sizes(Tile) +// PRINT-NEXT: for (int i = start; i < stop; i += step) +// DUMP-NEXT: ForStmt +for (int i = start; i < stop; i += step) + // PRINT-NEXT: body(i); + // DUMP: CallExpr + body(i); +} +void tfoo7() { + foo7<5>(0, 42, 2); +} + + #endif Index: clang/lib/Serialization/ASTWriterStmt.cpp === --- clang/lib/Serialization/ASTWriterStmt.cpp +++ clang/lib/Serialization/ASTWriterStmt.cpp @@ -2227,6 +2227,7 @@ void ASTStmtWriter::VisitOMPLoopTransformationDirective( OMPLoopTransformationDirective *D) { VisitOMPLoopBasedDirective(D); + Record.writeUInt32(D->getNumGeneratedLoops()); } void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) { Index: clang/lib/Serialization/ASTReaderStmt.cpp === --- clang/lib/Serialization/ASTReaderStmt.cpp +++ clang/lib/Serialization/ASTReaderStmt.cpp @@ -2327,6 +2327,7 @@ void ASTStmtReader::VisitOMPLoopTransformationDirective( OMPLoopTransformationDirective *D) { VisitOMPLoopBasedDirective(D); + D->setNumGeneratedLoops(Record.readUInt32()); } void ASTStmtReader::VisitOMPTileDirective(OMPTileDirective *D) { Index: clang/lib/Sema/SemaOpenMP.cpp === --- clang/lib/Sema/SemaOpenMP.cpp +++ clang/lib/Sema/SemaOpenMP.cpp @@ -12919,10 +12919,12 @@ Body, OriginalInits)) return StmtError(); + unsigned NumGeneratedLoops = PartialClause ? 1 : 0; + // Delay unrolling to when template is completely instantiated. if (CurContext->isDependentContext()) return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, - nullptr, nullptr); +
[PATCH] D111124: [Clang][OpenMP] Allow loop-transformations with template parameters.
ABataev accepted this revision. ABataev added a comment. This revision is now accepted and ready to land. LG Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D24/new/ https://reviews.llvm.org/D24 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D111124: [Clang][OpenMP] Allow loop-transformations with template parameters.
This revision was automatically updated to reflect the committed changes. Closed by commit rG2130117f92e5: [Clang][OpenMP] Allow loop-transformations with template parameters. (authored by Meinersbur). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D24/new/ https://reviews.llvm.org/D24 Files: clang/include/clang/AST/StmtOpenMP.h clang/lib/AST/StmtOpenMP.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/test/OpenMP/tile_ast_print.cpp clang/test/OpenMP/unroll_ast_print.cpp Index: clang/test/OpenMP/unroll_ast_print.cpp === --- clang/test/OpenMP/unroll_ast_print.cpp +++ clang/test/OpenMP/unroll_ast_print.cpp @@ -124,4 +124,26 @@ unroll_templated(); } + +// PRINT-LABEL: template void unroll_templated_factor(int start, int stop, int step) { +// DUMP-LABEL: FunctionTemplateDecl {{.*}} unroll_templated_factor +template +void unroll_templated_factor(int start, int stop, int step) { + // PRINT: #pragma omp unroll partial(Factor) + // DUMP: OMPUnrollDirective + // DUMP-NEXT: OMPPartialClause + // DUMP-NEXT: DeclRefExpr {{.*}} 'Factor' 'int' + #pragma omp unroll partial(Factor) +// PRINT-NEXT: for (int i = start; i < stop; i += step) +// DUMP-NEXT: ForStmt +for (int i = start; i < stop; i += step) + // PRINT-NEXT: body(i); + // DUMP: CallExpr + body(i); +} +void unroll_template_factor() { + unroll_templated_factor<4>(0, 42, 2); +} + + #endif Index: clang/test/OpenMP/tile_ast_print.cpp === --- clang/test/OpenMP/tile_ast_print.cpp +++ clang/test/OpenMP/tile_ast_print.cpp @@ -162,4 +162,25 @@ } +// PRINT-LABEL: template void foo7(int start, int stop, int step) { +// DUMP-LABEL: FunctionTemplateDecl {{.*}} foo7 +template +void foo7(int start, int stop, int step) { + // PRINT: #pragma omp tile sizes(Tile) + // DUMP: OMPTileDirective + // DUMP-NEXT: OMPSizesClause + // DUMP-NEXT: DeclRefExpr {{.*}} 'Tile' 'int' + #pragma omp tile sizes(Tile) +// PRINT-NEXT: for (int i = start; i < stop; i += step) +// DUMP-NEXT: ForStmt +for (int i = start; i < stop; i += step) + // PRINT-NEXT: body(i); + // DUMP: CallExpr + body(i); +} +void tfoo7() { + foo7<5>(0, 42, 2); +} + + #endif Index: clang/lib/Serialization/ASTWriterStmt.cpp === --- clang/lib/Serialization/ASTWriterStmt.cpp +++ clang/lib/Serialization/ASTWriterStmt.cpp @@ -2226,6 +2226,7 @@ void ASTStmtWriter::VisitOMPLoopTransformationDirective( OMPLoopTransformationDirective *D) { VisitOMPLoopBasedDirective(D); + Record.writeUInt32(D->getNumGeneratedLoops()); } void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) { Index: clang/lib/Serialization/ASTReaderStmt.cpp === --- clang/lib/Serialization/ASTReaderStmt.cpp +++ clang/lib/Serialization/ASTReaderStmt.cpp @@ -2327,6 +2327,7 @@ void ASTStmtReader::VisitOMPLoopTransformationDirective( OMPLoopTransformationDirective *D) { VisitOMPLoopBasedDirective(D); + D->setNumGeneratedLoops(Record.readUInt32()); } void ASTStmtReader::VisitOMPTileDirective(OMPTileDirective *D) { Index: clang/lib/Sema/SemaOpenMP.cpp === --- clang/lib/Sema/SemaOpenMP.cpp +++ clang/lib/Sema/SemaOpenMP.cpp @@ -12919,10 +12919,12 @@ Body, OriginalInits)) return StmtError(); + unsigned NumGeneratedLoops = PartialClause ? 1 : 0; + // Delay unrolling to when template is completely instantiated. if (CurContext->isDependentContext()) return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, - nullptr, nullptr); + NumGeneratedLoops, nullptr, nullptr); OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); @@ -12941,9 +12943,9 @@ // The generated loop may only be passed to other loop-associated directive // when a partial clause is specified. Without the requirement it is // sufficient to generate loop unroll metadata at code-generation. - if (!PartialClause) + if (NumGeneratedLoops == 0) return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, - nullptr, nullptr); + NumGeneratedLoops, nullptr, nullptr); // Otherwise, we need to provide a de-sugared/transformed AST that can be // associated with another loop directive. @@ -13164,7 +13166,8 @@ LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses,