[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
This commit is contained in:
Josh Mottley 2021-10-20 12:20:25 +00:00 committed by Josh Mottley
parent 7323d07483
commit 2aec2549e8
4 changed files with 301 additions and 61 deletions

View File

@ -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<const OpenMPConstruct *>(curConstruct)) {
if (const auto *olc = std::get_if<OpenMPLoopConstruct>(&(*oc)->u)) {
const auto &beginLoopDir{
std::get<Fortran::parser::OmpBeginLoopDirective>(olc->t)};
const auto &beginDir{
std::get<Fortran::parser::OmpLoopDirective>(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

View File

@ -17,7 +17,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <deque>
#include <string>
namespace Fortran {
@ -62,13 +61,10 @@ struct OpenMPCounterVisitor {
template <typename A> 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<LogRecord> constructClauses;
LogRecord *curLoopLogRecord{nullptr};
llvm::SmallVector<LogRecord *> loopLogRecordStack;
llvm::SmallVector<LogRecord> constructClauses;
llvm::SmallVector<OmpWrapperType *> ompWrapperStack;
llvm::DenseMap<OmpWrapperType *, llvm::SmallVector<ClauseInfo>> clauseStrings;
Parsing *parsing{nullptr};

View File

@ -33,10 +33,6 @@ namespace llvm {
namespace yaml {
using llvm::yaml::IO;
using llvm::yaml::MappingTraits;
template <typename T>
struct SequenceTraits<std::deque<T>,
std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
: SequenceTraitsImpl<std::deque<T>, SequenceElementTraits<T>::flow> {};
template <> struct MappingTraits<ClauseInfo> {
static void mapping(IO &io, ClauseInfo &info) {
io.mapRequired("clause", info.clause);

View File

@ -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:...