Skip to content

Commit 2780875

Browse files
authored
[flang][OpenMP] Get final label from nested constructs (#192517)
Non-block DO loops can share termination statements. When parsing a non-block DO loop, account for labels on terminating statements from recursively parsed ExecutionPartConstructs. Fixes #188892
1 parent e8e8b6a commit 2780875

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,8 +1836,14 @@ struct NonBlockDoConstructParser {
18361836
// Keep parsing ExecutionPartConstructs until the set of open label-do
18371837
// statements becomes empty, or until the EPC parser fails.
18381838
auto processEpc{[&](ExecutionPartConstruct &&epc) {
1839+
// The parsed epc may be a construct. In such case, get the final
1840+
// label from it.
18391841
if (auto &&label{GetStatementLabel(epc)}) {
18401842
labels.erase(*label);
1843+
} else if (auto *omp{Unwrap<OpenMPConstruct>(epc)}) {
1844+
if (auto &&label{GetFinalLabel(*omp)}) {
1845+
labels.erase(*label);
1846+
}
18411847
}
18421848
if (auto *labelDo{Unwrap<LabelDoStmt>(epc)}) {
18431849
labels.insert(std::get<Label>(labelDo->t));
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
!RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s
2+
!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
3+
4+
! Check that this is parsed correctly. Specifically, that the "10 continue"
5+
! terminates both do-loops, and both "parallel do" directives.
6+
7+
subroutine f
8+
!$omp parallel do lastprivate(i)
9+
do 10 i=1,2
10+
!$omp parallel do lastprivate(j)
11+
do 10 j=1,2
12+
10 continue
13+
!$omp parallel
14+
!$omp end parallel
15+
print *,'pass'
16+
end
17+
18+
!UNPARSE: SUBROUTINE f
19+
!UNPARSE: !$OMP PARALLEL DO LASTPRIVATE(i)
20+
!UNPARSE: DO i=1_4,2_4
21+
!UNPARSE: !$OMP PARALLEL DO LASTPRIVATE(j)
22+
!UNPARSE: DO j=1_4,2_4
23+
!UNPARSE: 10 CONTINUE
24+
!UNPARSE: END DO
25+
!UNPARSE: END DO
26+
!UNPARSE: !$OMP PARALLEL
27+
!UNPARSE: !$OMP END PARALLEL
28+
!UNPARSE: PRINT *, "pass"
29+
!UNPARSE: END SUBROUTINE
30+
31+
!PARSE-TREE: Program -> ProgramUnit -> SubroutineSubprogram
32+
!PARSE-TREE: | SubroutineStmt
33+
!PARSE-TREE: | | Name = 'f'
34+
!PARSE-TREE: | SpecificationPart
35+
!PARSE-TREE: | | ImplicitPart ->
36+
!PARSE-TREE: | ExecutionPart -> Block
37+
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
38+
!PARSE-TREE: | | | OmpBeginLoopDirective
39+
!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = parallel do
40+
!PARSE-TREE: | | | | OmpClauseList -> OmpClause -> Lastprivate -> OmpLastprivateClause
41+
!PARSE-TREE: | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'i'
42+
!PARSE-TREE: | | | | Flags = {}
43+
!PARSE-TREE: | | | Block
44+
!PARSE-TREE: | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
45+
!PARSE-TREE: | | | | | NonLabelDoStmt
46+
!PARSE-TREE: | | | | | | LoopControl -> LoopBounds
47+
!PARSE-TREE: | | | | | | | Scalar -> Name = 'i'
48+
!PARSE-TREE: | | | | | | | Scalar -> Expr = '1_4'
49+
!PARSE-TREE: | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
50+
!PARSE-TREE: | | | | | | | Scalar -> Expr = '2_4'
51+
!PARSE-TREE: | | | | | | | | LiteralConstant -> IntLiteralConstant = '2'
52+
!PARSE-TREE: | | | | | Block
53+
!PARSE-TREE: | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
54+
!PARSE-TREE: | | | | | | | OmpBeginLoopDirective
55+
!PARSE-TREE: | | | | | | | | OmpDirectiveName -> llvm::omp::Directive = parallel do
56+
!PARSE-TREE: | | | | | | | | OmpClauseList -> OmpClause -> Lastprivate -> OmpLastprivateClause
57+
!PARSE-TREE: | | | | | | | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'j'
58+
!PARSE-TREE: | | | | | | | | Flags = {CrossesLabelDo}
59+
!PARSE-TREE: | | | | | | | Block
60+
!PARSE-TREE: | | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
61+
!PARSE-TREE: | | | | | | | | | NonLabelDoStmt
62+
!PARSE-TREE: | | | | | | | | | | LoopControl -> LoopBounds
63+
!PARSE-TREE: | | | | | | | | | | | Scalar -> Name = 'j'
64+
!PARSE-TREE: | | | | | | | | | | | Scalar -> Expr = '1_4'
65+
!PARSE-TREE: | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
66+
!PARSE-TREE: | | | | | | | | | | | Scalar -> Expr = '2_4'
67+
!PARSE-TREE: | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '2'
68+
!PARSE-TREE: | | | | | | | | | Block
69+
!PARSE-TREE: | | | | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> ContinueStmt
70+
!PARSE-TREE: | | | | | | | | | EndDoStmt ->
71+
!PARSE-TREE: | | | | | EndDoStmt ->
72+
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OmpBlockConstruct
73+
!PARSE-TREE: | | | OmpBeginDirective
74+
!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = parallel
75+
!PARSE-TREE: | | | | OmpClauseList ->
76+
!PARSE-TREE: | | | | Flags = {}
77+
!PARSE-TREE: | | | Block
78+
!PARSE-TREE: | | | OmpEndDirective
79+
!PARSE-TREE: | | | | OmpDirectiveName -> llvm::omp::Directive = parallel
80+
!PARSE-TREE: | | | | OmpClauseList ->
81+
!PARSE-TREE: | | | | Flags = {}
82+
!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> PrintStmt
83+
!PARSE-TREE: | | | Format -> Star
84+
!PARSE-TREE: | | | OutputItem -> Expr = '"pass"'
85+
!PARSE-TREE: | | | | LiteralConstant -> CharLiteralConstant
86+
!PARSE-TREE: | | | | | string = 'pass'
87+
!PARSE-TREE: | EndSubroutineStmt ->
88+

0 commit comments

Comments
 (0)