diff --git a/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.h b/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.h --- a/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.h +++ b/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.h @@ -17,7 +17,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include #include namespace Fortran { @@ -62,13 +61,10 @@ template void Post(const A &) {} bool Pre(const OpenMPDeclarativeConstruct &c); bool Pre(const OpenMPConstruct &c); - bool Pre(const OmpEndLoopDirective &c); - bool Pre(const DoConstruct &); void Post(const OpenMPDeclarativeConstruct &); void Post(const OpenMPConstruct &); void PostConstructsCommon(); - void Post(const OmpEndLoopDirective &c); void Post(const OmpProcBindClause::Type &c); void Post(const OmpDefaultClause::Type &c); @@ -83,20 +79,9 @@ void Post(const OmpCancelType::Type &c); void Post(const OmpClause &c); void PostClauseCommon(const ClauseInfo &ci); - void Post(const DoConstruct &); std::string clauseDetails{""}; - - // curLoopLogRecord and loopLogRecordStack store - // pointers to this datastructure's entries. Hence a - // vector cannot be used since pointers are invalidated - // on resize. Next best option seems to be deque. Also a - // list cannot be used since YAML gen requires a - // datastructure which can be accessed through indices. - std::deque constructClauses; - - LogRecord *curLoopLogRecord{nullptr}; - llvm::SmallVector loopLogRecordStack; + llvm::SmallVector constructClauses; llvm::SmallVector ompWrapperStack; llvm::DenseMap> clauseStrings; Parsing *parsing{nullptr}; diff --git a/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp b/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp --- a/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp +++ b/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.cpp @@ -156,11 +156,6 @@ ompWrapperStack.push_back(ow); return true; } -bool OpenMPCounterVisitor::Pre(const OmpEndLoopDirective &c) { return true; } -bool OpenMPCounterVisitor::Pre(const DoConstruct &) { - loopLogRecordStack.push_back(curLoopLogRecord); - return true; -} void OpenMPCounterVisitor::Post(const OpenMPDeclarativeConstruct &) { PostConstructsCommon(); @@ -178,27 +173,11 @@ clauseStrings[curConstruct]}; constructClauses.push_back(r); - // Keep track of loop log records if it can potentially have the - // nowait clause added on later. - if (const auto *oc = std::get_if(curConstruct)) { - if (const auto *olc = std::get_if(&(*oc)->u)) { - const auto &beginLoopDir{ - std::get(olc->t)}; - const auto &beginDir{ - std::get(beginLoopDir.t)}; - if (beginDir.v == llvm::omp::Directive::OMPD_do || - beginDir.v == llvm::omp::Directive::OMPD_do_simd) { - curLoopLogRecord = &constructClauses.back(); - } - } - } - auto it = clauseStrings.find(curConstruct); clauseStrings.erase(it); ompWrapperStack.pop_back(); delete curConstruct; } -void OpenMPCounterVisitor::Post(const OmpEndLoopDirective &c) {} void OpenMPCounterVisitor::Post(const OmpProcBindClause::Type &c) { clauseDetails += "type=" + OmpProcBindClause::EnumToString(c) + ";"; @@ -242,26 +221,9 @@ clauseDetails.clear(); } void OpenMPCounterVisitor::PostClauseCommon(const ClauseInfo &ci) { - // The end loop construct (!$omp end do) can contain a nowait clause. - // The flang parser does not parse the end loop construct as part of - // the OpenMP construct for the loop construct. So the end loop is left - // hanging as a separate executable construct. If a nowait clause is seen in - // an end loop construct we have to find the associated loop construct and - // add nowait to its list of clauses. Note: This is not a bug in flang, the - // parse tree is corrected during semantic analysis. - if (ci.clause == "nowait") { - assert(curLoopLogRecord && - "loop Construct should be visited before a nowait clause"); - curLoopLogRecord->clauses.push_back(ci); - } else { - assert(!ompWrapperStack.empty() && - "Construct should be visited before clause"); - clauseStrings[ompWrapperStack.back()].push_back(ci); - } -} -void OpenMPCounterVisitor::Post(const DoConstruct &) { - curLoopLogRecord = loopLogRecordStack.back(); - loopLogRecordStack.pop_back(); + assert( + !ompWrapperStack.empty() && "Construct should be visited before clause"); + clauseStrings[ompWrapperStack.back()].push_back(ci); } } // namespace parser } // namespace Fortran diff --git a/flang/examples/flang-omp-report-plugin/flang-omp-report.cpp b/flang/examples/flang-omp-report-plugin/flang-omp-report.cpp --- a/flang/examples/flang-omp-report-plugin/flang-omp-report.cpp +++ b/flang/examples/flang-omp-report-plugin/flang-omp-report.cpp @@ -33,10 +33,6 @@ namespace yaml { using llvm::yaml::IO; using llvm::yaml::MappingTraits; -template -struct SequenceTraits, - std::enable_if_t::flow>::value>> - : SequenceTraitsImpl, SequenceElementTraits::flow> {}; template <> struct MappingTraits { static void mapping(IO &io, ClauseInfo &info) { io.mapRequired("clause", info.clause); diff --git a/flang/test/Examples/omp-nowait.f90 b/flang/test/Examples/omp-nowait.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Examples/omp-nowait.f90 @@ -0,0 +1,301 @@ +! Check the flang-omp-report plugin for omp-nowait.f90 + +! REQUIRES: plugins, examples, shell + +! RUN: %flang_fc1 -load %llvmshlibdir/flangOmpReport.so -plugin flang-omp-report -fopenmp %s -o - | FileCheck %s + +! Check OpenMP 2.13.6 atomic Construct + +subroutine sb(n) +implicit none + +integer :: n +integer :: arr(n,n), brr(n,n), crr(n,n) +integer :: arr_single(n),arr_quad(n,n,n,n) +integer :: i,j,k,l,tmp,tmp1,tmp2 + +! CHECK:--- + +!Simple check with nowait +!$omp do +do i = 1, n + arr_single(i) = i +end do +!$omp end do nowait +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-6]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' + +!Check for no effects on loop without nowait +!$omp do +do i = 1, n + arr_single(i) = i +end do +!$omp end do +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-6]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: [] + +!Check with another construct nested inside loop with nowait +!$omp parallel shared(arr) +!$omp do +do i = 1, n +!$omp critical + arr_single(i) = i +!$omp end critical +end do +!$omp end do nowait +!$omp end parallel +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-7]] +! CHECK-NEXT: construct: critical +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-13]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-20]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: shared +! CHECK-NEXT: details: arr + +!Check with back to back loops (one with nowait) inside a parallel construct +!$omp parallel shared(arr) +!$omp do +do i=1,10 + arr(i,j) = i+j +end do +!$omp end do nowait +!$omp do schedule(guided) +do j=1,10 +end do +!$omp end do +!$omp end parallel +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-11]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-12]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: schedule +! CHECK-NEXT: details: guided +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-24]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: shared +! CHECK-NEXT: details: arr + + +!Check nested parallel do loops with a nowait outside +!$omp parallel shared(arr) +!$omp do +do i=1,10 + arr_single(i)=i + !$omp parallel + !$omp do + do j=1,10 + !$omp critical + arr(i,j) = i+j + !$omp end critical + end do + !$omp end do + !$omp end parallel +end do +!$omp end do nowait +!$omp end parallel +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-10]] +! CHECK-NEXT: construct: critical +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-16]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-21]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-28]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-35]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: shared +! CHECK-NEXT: details: arr + +!Check nested parallel do loops with a nowait inside +!$omp parallel shared(arr) +!$omp do +do i=1,10 + arr_single(i)=i + !$omp parallel + !$omp do + do j=1,10 + !$omp critical + arr(i,j) = i+j + !$omp end critical + end do + !$omp end do nowait + !$omp end parallel +end do +!$omp end do +!$omp end parallel +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-10]] +! CHECK-NEXT: construct: critical +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-16]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-23]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-30]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-35]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: shared +! CHECK-NEXT: details: arr + +!Check nested parallel do loops with a nowait inside +!$omp parallel +!$omp do +do i=1,10 + arr_single(i)=i + !$omp parallel shared(arr_quad) + !$omp do schedule(dynamic) + do j=1,10 + !$omp parallel + !$omp do + do k=1,10 + !$omp parallel + !$omp do + do l=1,10 + arr_quad(i,j,k,l) = i+j+k+l + end do + !$omp end do nowait + !$omp end parallel + end do + !$omp end do + !$omp end parallel + end do + !$omp end do nowait + !$omp end parallel +end do +!$omp end do +!$omp end parallel +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-16]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-23]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-29]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-34]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-40]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT: - clause: schedule +! CHECK-NEXT: details: dynamic +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-49]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: shared +! CHECK-NEXT: details: arr_quad +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-58]] +! CHECK-NEXT: construct: do +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-63]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: [] + + +!Check a do simd with nowait +!$omp do simd private(tmp) +do j = 1,n + do i = 1,n + tmp = arr(i,j) + brr(i,j) + crr(i,j) = tmp + end do +end do +!$omp end do simd nowait +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-9]] +! CHECK-NEXT: construct: do simd +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT: - clause: private +! CHECK-NEXT: details: tmp + + +!test nowait on non-do construct +!$omp parallel +!$omp single +tmp1 = i+j +!$omp end single + +!$omp single +tmp2 = i-j +!$omp end single nowait +!$omp end parallel +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-9]] +! CHECK-NEXT: construct: single +! CHECK-NEXT: clauses: [] +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-9]] +! CHECK-NEXT: construct: single +! CHECK-NEXT: clauses: +! CHECK-NEXT: - clause: nowait +! CHECK-NEXT: details: '' +! CHECK-NEXT:- file: '{{[^"]*}}omp-nowait.f90' +! CHECK-NEXT: line: [[@LINE-20]] +! CHECK-NEXT: construct: parallel +! CHECK-NEXT: clauses: [] + +end subroutine + +! CHECK-NEXT:...