From 2aec2549e8e52f57bc9e9b082be06ece69be61ad Mon Sep 17 00:00:00 2001 From: Josh Mottley Date: Wed, 20 Oct 2021 12:20:25 +0000 Subject: [PATCH] [flang][flang-omp-report] Remove the loop workarounds for nowait clause In a "Worksharing-loop construct", one can add a nowait clause at the end of the loop (i.e. at the loop tail). This clause wasn't associated with the corresponding loop when originally worked on in flang-omp-report. Note that this refers to parsing and parse-tree generation. To work around it, it was needed to track such clauses and the loops. This should no longer be required (and in fact no longer works) and so was removed. This results in 'curLoopLogRecord' and 'loopLogRecordStack' and all references to them being removed. This also allows for 'constructClauses' to be swapped from std::deque to llvm::SmallVector. Lastly a new test has been added testing the "nowait" clauses in a variety of ways. Reviewed By: awarzynski, kiranchandramohan Differential Revision: https://reviews.llvm.org/D112217 --- .../flang-omp-report-visitor.cpp | 44 +-- .../flang-omp-report-visitor.h | 17 +- .../flang-omp-report.cpp | 4 - flang/test/Examples/omp-nowait.f90 | 297 ++++++++++++++++++ 4 files changed, 301 insertions(+), 61 deletions(-) create mode 100644 flang/test/Examples/omp-nowait.f90 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 index f49e72fabee8..32dcef25feda 100644 --- 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 @@ bool OpenMPCounterVisitor::Pre(const OpenMPConstruct &c) { 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 @@ void OpenMPCounterVisitor::PostConstructsCommon() { 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 @@ void OpenMPCounterVisitor::Post(const OmpClause &c) { 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-visitor.h b/flang/examples/flang-omp-report-plugin/flang-omp-report-visitor.h index 188e8f9b61f9..d31fa8cc4689 100644 --- 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 @@ struct OpenMPCounterVisitor { 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 @@ struct OpenMPCounterVisitor { 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.cpp b/flang/examples/flang-omp-report-plugin/flang-omp-report.cpp index 0654513d1dae..9ee8eb1a80cb 100644 --- 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 llvm { 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 index 000000000000..091a952ae910 --- /dev/null +++ b/flang/test/Examples/omp-nowait.f90 @@ -0,0 +1,297 @@ +! REQUIRES: plugins, examples, shell + +! RUN: %flang_fc1 -load %llvmshlibdir/flangOmpReport.so -plugin flang-omp-report -fopenmp %s -o - | FileCheck %s + +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:...