diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -215,6 +215,7 @@ construct(construct()) || "FINAL" >> construct(construct( parenthesized(scalarLogicalExpr))) || + "FULL" >> construct(construct()) || "FIRSTPRIVATE" >> construct(construct( parenthesized(Parser{}))) || "FROM" >> construct(construct( @@ -251,6 +252,8 @@ parenthesized(scalarIntExpr))) || "ORDERED" >> construct(construct( maybe(parenthesized(scalarIntConstantExpr)))) || + "PARTIAL" >> construct(construct( + maybe(parenthesized(scalarIntConstantExpr)))) || "PRIORITY" >> construct(construct( parenthesized(scalarIntExpr))) || "PRIVATE" >> construct(construct( @@ -337,7 +340,8 @@ "TEAMS DISTRIBUTE SIMD" >> pure(llvm::omp::Directive::OMPD_teams_distribute_simd), "TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute), - "TILE" >> pure(llvm::omp::Directive::OMPD_tile))))) + "TILE" >> pure(llvm::omp::Directive::OMPD_tile), + "UNROLL" >> pure(llvm::omp::Directive::OMPD_unroll))))) TYPE_PARSER(sourced(construct( sourced(Parser{}), Parser{}))) diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2153,6 +2153,9 @@ case llvm::omp::Directive::OMPD_tile: Word("TILE "); break; + case llvm::omp::Directive::OMPD_unroll: + Word("UNROLL "); + break; default: break; } diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -1222,6 +1222,7 @@ case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd: case llvm::omp::Directive::OMPD_teams_distribute_simd: case llvm::omp::Directive::OMPD_tile: + case llvm::omp::Directive::OMPD_unroll: PushContext(beginDir.source, beginDir.v); break; default: diff --git a/flang/test/Parser/omp-unroll-full.f90 b/flang/test/Parser/omp-unroll-full.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-unroll-full.f90 @@ -0,0 +1,22 @@ +! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s +! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine openmp_parse_unroll(x) + + integer, intent(inout)::x + +!CHECK: !$omp unroll full +!$omp unroll full +!CHECK: do + do x = 1, 100 + call F1() +!CHECK: end do + end do +!CHECK: !$omp end unroll +!$omp end unroll + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE: OmpBeginLoopDirective +!PARSE-TREE: OmpLoopDirective -> llvm::omp::Directive = unroll +!PARSE-TREE: OmpClauseList -> OmpClause -> Full +END subroutine openmp_parse_unroll diff --git a/flang/test/Parser/omp-unroll.f90 b/flang/test/Parser/omp-unroll.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Parser/omp-unroll.f90 @@ -0,0 +1,24 @@ +! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s +! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine openmp_parse_unroll(x) + + integer, intent(inout)::x + +!CHECK: !$omp unroll partial(3) +!$omp unroll partial(3) +!CHECK: do + do x = 1, 100 + call F1() +!CHECK: end do + end do +!CHECK: !$omp end unroll +!$omp end unroll + +!PARSE-TREE: OpenMPConstruct -> OpenMPLoopConstruct +!PARSE-TREE: OmpBeginLoopDirective +!PARSE-TREE: OmpLoopDirective -> llvm::omp::Directive = unroll +!PARSE-TREE: OmpClauseList -> OmpClause -> Partial -> Scalar -> Integer -> Constant -> Expr = '3_4' +!PARSE-TREE: LiteralConstant -> IntLiteralConstant = '3' + +END subroutine openmp_parse_unroll diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td --- a/llvm/include/llvm/Frontend/OpenMP/OMP.td +++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td @@ -72,8 +72,14 @@ let flangClass = "ScalarIntExpr"; let isValueList = true; } -def OMPC_Full: Clause<"full"> { let clangClass = "OMPFullClause"; } -def OMPC_Partial: Clause<"partial"> { let clangClass = "OMPPartialClause"; } +def OMPC_Full: Clause<"full"> { + let clangClass = "OMPFullClause"; +} +def OMPC_Partial: Clause<"partial"> { + let clangClass = "OMPPartialClause"; + let flangClass = "ScalarIntConstantExpr"; + let isValueOptional = true; + } def OMPC_FirstPrivate : Clause<"firstprivate"> { let clangClass = "OMPFirstprivateClause"; let flangClass = "OmpObjectList";