|
12 | 12 | #include "flang/Parser/parse-tree.h"
|
13 | 13 | #include "flang/Semantics/expression.h"
|
14 | 14 | #include "flang/Semantics/tools.h"
|
| 15 | +#include <variant> |
15 | 16 |
|
16 | 17 | namespace Fortran::semantics {
|
17 | 18 |
|
@@ -747,63 +748,61 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
|
747 | 748 | // current context yet.
|
748 | 749 | // TODO: Check for declare simd regions.
|
749 | 750 | bool eligibleSIMD{false};
|
750 |
| - common::visit( |
751 |
| - Fortran::common::visitors{ |
752 |
| - // Allow `!$OMP ORDERED SIMD` |
753 |
| - [&](const parser::OpenMPBlockConstruct &c) { |
754 |
| - const auto &beginBlockDir{ |
755 |
| - std::get<parser::OmpBeginBlockDirective>(c.t)}; |
756 |
| - const auto &beginDir{ |
757 |
| - std::get<parser::OmpBlockDirective>(beginBlockDir.t)}; |
758 |
| - if (beginDir.v == llvm::omp::Directive::OMPD_ordered) { |
759 |
| - const auto &clauses{ |
760 |
| - std::get<parser::OmpClauseList>(beginBlockDir.t)}; |
761 |
| - for (const auto &clause : clauses.v) { |
762 |
| - if (std::get_if<parser::OmpClause::Simd>(&clause.u)) { |
763 |
| - eligibleSIMD = true; |
764 |
| - break; |
765 |
| - } |
766 |
| - } |
767 |
| - } |
768 |
| - }, |
769 |
| - [&](const parser::OpenMPStandaloneConstruct &c) { |
770 |
| - if (const auto &simpleConstruct = |
771 |
| - std::get_if<parser::OpenMPSimpleStandaloneConstruct>( |
772 |
| - &c.u)) { |
773 |
| - const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>( |
774 |
| - simpleConstruct->t)}; |
775 |
| - if (dir.v == llvm::omp::Directive::OMPD_ordered) { |
776 |
| - const auto &clauses{ |
777 |
| - std::get<parser::OmpClauseList>(simpleConstruct->t)}; |
778 |
| - for (const auto &clause : clauses.v) { |
779 |
| - if (std::get_if<parser::OmpClause::Simd>(&clause.u)) { |
780 |
| - eligibleSIMD = true; |
781 |
| - break; |
782 |
| - } |
783 |
| - } |
784 |
| - } else if (dir.v == llvm::omp::Directive::OMPD_scan) { |
785 |
| - eligibleSIMD = true; |
786 |
| - } |
787 |
| - } |
788 |
| - }, |
789 |
| - // Allowing SIMD construct |
790 |
| - [&](const parser::OpenMPLoopConstruct &c) { |
791 |
| - const auto &beginLoopDir{ |
792 |
| - std::get<parser::OmpBeginLoopDirective>(c.t)}; |
793 |
| - const auto &beginDir{ |
794 |
| - std::get<parser::OmpLoopDirective>(beginLoopDir.t)}; |
795 |
| - if ((beginDir.v == llvm::omp::Directive::OMPD_simd) || |
796 |
| - (beginDir.v == llvm::omp::Directive::OMPD_parallel_do_simd) || |
797 |
| - (beginDir.v == llvm::omp::Directive::OMPD_do_simd)) { |
798 |
| - eligibleSIMD = true; |
799 |
| - } |
800 |
| - }, |
801 |
| - [&](const parser::OpenMPAtomicConstruct &c) { |
802 |
| - // Allow `!$OMP ATOMIC` |
803 |
| - eligibleSIMD = true; |
804 |
| - }, |
805 |
| - [&](const auto &c) {}, |
806 |
| - }, |
| 751 | + common::visit(Fortran::common::visitors{ |
| 752 | + // Allow `!$OMP ORDERED SIMD` |
| 753 | + [&](const parser::OpenMPBlockConstruct &c) { |
| 754 | + const auto &beginBlockDir{ |
| 755 | + std::get<parser::OmpBeginBlockDirective>(c.t)}; |
| 756 | + const auto &beginDir{ |
| 757 | + std::get<parser::OmpBlockDirective>(beginBlockDir.t)}; |
| 758 | + if (beginDir.v == llvm::omp::Directive::OMPD_ordered) { |
| 759 | + const auto &clauses{ |
| 760 | + std::get<parser::OmpClauseList>(beginBlockDir.t)}; |
| 761 | + for (const auto &clause : clauses.v) { |
| 762 | + if (std::get_if<parser::OmpClause::Simd>(&clause.u)) { |
| 763 | + eligibleSIMD = true; |
| 764 | + break; |
| 765 | + } |
| 766 | + } |
| 767 | + } |
| 768 | + }, |
| 769 | + [&](const parser::OpenMPStandaloneConstruct &c) { |
| 770 | + if (const auto &simpleConstruct = |
| 771 | + std::get_if<parser::OpenMPSimpleStandaloneConstruct>( |
| 772 | + &c.u)) { |
| 773 | + const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>( |
| 774 | + simpleConstruct->t)}; |
| 775 | + if (dir.v == llvm::omp::Directive::OMPD_ordered) { |
| 776 | + const auto &clauses{ |
| 777 | + std::get<parser::OmpClauseList>(simpleConstruct->t)}; |
| 778 | + for (const auto &clause : clauses.v) { |
| 779 | + if (std::get_if<parser::OmpClause::Simd>(&clause.u)) { |
| 780 | + eligibleSIMD = true; |
| 781 | + break; |
| 782 | + } |
| 783 | + } |
| 784 | + } else if (dir.v == llvm::omp::Directive::OMPD_scan) { |
| 785 | + eligibleSIMD = true; |
| 786 | + } |
| 787 | + } |
| 788 | + }, |
| 789 | + // Allowing SIMD construct |
| 790 | + [&](const parser::OpenMPLoopConstruct &c) { |
| 791 | + const auto &beginLoopDir{ |
| 792 | + std::get<parser::OmpBeginLoopDirective>(c.t)}; |
| 793 | + const auto &beginDir{ |
| 794 | + std::get<parser::OmpLoopDirective>(beginLoopDir.t)}; |
| 795 | + if ((beginDir.v == llvm::omp::Directive::OMPD_simd) || |
| 796 | + (beginDir.v == llvm::omp::Directive::OMPD_do_simd)) { |
| 797 | + eligibleSIMD = true; |
| 798 | + } |
| 799 | + }, |
| 800 | + [&](const parser::OpenMPAtomicConstruct &c) { |
| 801 | + // Allow `!$OMP ATOMIC` |
| 802 | + eligibleSIMD = true; |
| 803 | + }, |
| 804 | + [&](const auto &c) {}, |
| 805 | + }, |
807 | 806 | c.u);
|
808 | 807 | if (!eligibleSIMD) {
|
809 | 808 | context_.Say(parser::FindSourceLocation(c),
|
@@ -2990,15 +2989,7 @@ void OmpStructureChecker::CheckReductionModifier(
|
2990 | 2989 | // or "simd" directive.
|
2991 | 2990 | // The worksharing-loop directives are OMPD_do and OMPD_for. Only the
|
2992 | 2991 | // former is allowed in Fortran.
|
2993 |
| - switch (dirCtx.directive) { |
2994 |
| - case llvm::omp::Directive::OMPD_do: // worksharing-loop |
2995 |
| - case llvm::omp::Directive::OMPD_do_simd: // worksharing-loop simd |
2996 |
| - case llvm::omp::Directive:: |
2997 |
| - OMPD_parallel_do_simd: // worksharing-parallel-loop |
2998 |
| - // simd |
2999 |
| - case llvm::omp::Directive::OMPD_simd: // "simd" |
3000 |
| - break; |
3001 |
| - default: |
| 2992 | + if (!llvm::omp::scanAllowedSet.test(dirCtx.directive)) { |
3002 | 2993 | context_.Say(GetContext().clauseSource,
|
3003 | 2994 | "Modifier 'INSCAN' on REDUCTION clause is only allowed with "
|
3004 | 2995 | "worksharing-loop, worksharing-loop simd, "
|
|
0 commit comments