Skip to content

Commit 3c98d8c

Browse files
authored
[OpenACC] Implement 'tile' loop count/tightly nested loop requirement (#111038)
the 'tile' clause requires that it be followed by N (where N is the number of size expressions) 'tightly nested loops'. This means the same as it does in 'collapse', so much of the implementation is simliar/shared with that.
1 parent e5a0c30 commit 3c98d8c

File tree

7 files changed

+504
-76
lines changed

7 files changed

+504
-76
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12670,19 +12670,19 @@ def err_acc_size_expr_value
1267012670
: Error<
1267112671
"OpenACC 'tile' clause size expression must be %select{an asterisk "
1267212672
"or a constant expression|positive integer value, evaluated to %1}0">;
12673-
def err_acc_invalid_in_collapse_loop
12674-
: Error<"%select{OpenACC '%1' construct|while loop|do loop}0 cannot appear "
12675-
"in intervening code of a 'loop' with a 'collapse' clause">;
12676-
def note_acc_collapse_clause_here
12677-
: Note<"active 'collapse' clause defined here">;
12678-
def err_acc_collapse_multiple_loops
12673+
def err_acc_invalid_in_loop
12674+
: Error<"%select{OpenACC '%2' construct|while loop|do loop}0 cannot appear "
12675+
"in intervening code of a 'loop' with a '%1' clause">;
12676+
def note_acc_active_clause_here
12677+
: Note<"active '%0' clause defined here">;
12678+
def err_acc_clause_multiple_loops
1267912679
: Error<"more than one for-loop in a loop associated with OpenACC 'loop' "
12680-
"construct with a 'collapse' clause">;
12681-
def err_acc_collapse_insufficient_loops
12682-
: Error<"'collapse' clause specifies a loop count greater than the number "
12680+
"construct with a '%select{collapse|tile}0' clause">;
12681+
def err_acc_insufficient_loops
12682+
: Error<"'%0' clause specifies a loop count greater than the number "
1268312683
"of available loops">;
12684-
def err_acc_collapse_intervening_code
12685-
: Error<"inner loops must be tightly nested inside a 'collapse' clause on "
12684+
def err_acc_intervening_code
12685+
: Error<"inner loops must be tightly nested inside a '%0' clause on "
1268612686
"a 'loop' construct">;
1268712687

1268812688
// AMDGCN builtins diagnostics

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,23 @@ class SemaOpenACC : public SemaBase {
4242
/// above collection.
4343
bool InsideComputeConstruct = false;
4444

45+
/// Certain clauses care about the same things that aren't specific to the
46+
/// individual clause, but can be shared by a few, so store them here. All
47+
/// require a 'no intervening constructs' rule, so we know they are all from
48+
/// the same 'place'.
49+
struct LoopCheckingInfo {
50+
/// Records whether we've seen the top level 'for'. We already diagnose
51+
/// later that the 'top level' is a for loop, so we use this to suppress the
52+
/// 'collapse inner loop not a 'for' loop' diagnostic.
53+
LLVM_PREFERRED_TYPE(bool)
54+
unsigned TopLevelLoopSeen : 1;
55+
56+
/// Records whether this 'tier' of the loop has already seen a 'for' loop,
57+
/// used to diagnose if there are multiple 'for' loops at any one level.
58+
LLVM_PREFERRED_TYPE(bool)
59+
unsigned CurLevelHasLoopAlready : 1;
60+
} LoopInfo{/*TopLevelLoopSeen=*/false, /*CurLevelHasLoopAlready=*/false};
61+
4562
/// The 'collapse' clause requires quite a bit of checking while
4663
/// parsing/instantiating its body, so this structure/object keeps all of the
4764
/// necessary information as we do checking. This should rarely be directly
@@ -59,25 +76,27 @@ class SemaOpenACC : public SemaBase {
5976
/// else it should be 'N' minus the current depth traversed.
6077
std::optional<llvm::APSInt> CurCollapseCount;
6178

62-
/// Records whether we've seen the top level 'for'. We already diagnose
63-
/// later that the 'top level' is a for loop, so we use this to suppress the
64-
/// 'collapse inner loop not a 'for' loop' diagnostic.
65-
LLVM_PREFERRED_TYPE(bool)
66-
unsigned TopLevelLoopSeen : 1;
67-
68-
/// Records whether this 'tier' of the loop has already seen a 'for' loop,
69-
/// used to diagnose if there are multiple 'for' loops at any one level.
70-
LLVM_PREFERRED_TYPE(bool)
71-
unsigned CurLevelHasLoopAlready : 1;
72-
7379
/// Records whether we've hit a CurCollapseCount of '0' on the way down,
7480
/// which allows us to diagnose if the value of 'N' is too large for the
7581
/// current number of 'for' loops.
76-
LLVM_PREFERRED_TYPE(bool)
77-
unsigned CollapseDepthSatisfied : 1;
78-
} CollapseInfo{nullptr, std::nullopt, /*TopLevelLoopSeen=*/false,
79-
/*CurLevelHasLoopAlready=*/false,
80-
/*CollapseDepthSatisfied=*/true};
82+
bool CollapseDepthSatisfied = true;
83+
} CollapseInfo;
84+
85+
/// The 'tile' clause requires a bit of additional checking as well, so like
86+
/// the `CollapseCheckingInfo`, ensure we maintain information here too.
87+
struct TileCheckingInfo {
88+
OpenACCTileClause *ActiveTile = nullptr;
89+
90+
/// This is the number of expressions on a 'tile' clause. This doesn't have
91+
/// to be an APSInt because it isn't the result of a constexpr, just by our
92+
/// own counting of elements.
93+
std::optional<unsigned> CurTileCount;
94+
95+
/// Records whether we've hit a 'CurTileCount' of '0' on the wya down,
96+
/// which allows us to diagnose if the number of arguments is too large for
97+
/// the current number of 'for' loops.
98+
bool TileDepthSatisfied = true;
99+
} TileInfo;
81100

82101
public:
83102
// Redeclaration of the version in OpenACCClause.h.
@@ -537,12 +556,15 @@ class SemaOpenACC : public SemaBase {
537556
/// into a loop (for, etc) inside the construct.
538557
class LoopInConstructRAII {
539558
SemaOpenACC &SemaRef;
559+
LoopCheckingInfo OldLoopInfo;
540560
CollapseCheckingInfo OldCollapseInfo;
561+
TileCheckingInfo OldTileInfo;
541562
bool PreserveDepth;
542563

543564
public:
544565
LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true)
545-
: SemaRef(SemaRef), OldCollapseInfo(SemaRef.CollapseInfo),
566+
: SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
567+
OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
546568
PreserveDepth(PreserveDepth) {}
547569
~LoopInConstructRAII() {
548570
// The associated-statement level of this should NOT preserve this, as it
@@ -551,12 +573,20 @@ class SemaOpenACC : public SemaBase {
551573
bool CollapseDepthSatisified =
552574
PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
553575
: OldCollapseInfo.CollapseDepthSatisfied;
576+
bool TileDepthSatisfied = PreserveDepth
577+
? SemaRef.TileInfo.TileDepthSatisfied
578+
: OldTileInfo.TileDepthSatisfied;
554579
bool CurLevelHasLoopAlready =
555-
PreserveDepth ? SemaRef.CollapseInfo.CurLevelHasLoopAlready
556-
: OldCollapseInfo.CurLevelHasLoopAlready;
580+
PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
581+
: OldLoopInfo.CurLevelHasLoopAlready;
582+
583+
SemaRef.LoopInfo = OldLoopInfo;
557584
SemaRef.CollapseInfo = OldCollapseInfo;
585+
SemaRef.TileInfo = OldTileInfo;
586+
558587
SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
559-
SemaRef.CollapseInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
588+
SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
589+
SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
560590
}
561591
};
562592

@@ -577,6 +607,9 @@ class SemaOpenACC : public SemaBase {
577607
void SetCollapseInfoBeforeAssociatedStmt(
578608
ArrayRef<const OpenACCClause *> UnInstClauses,
579609
ArrayRef<OpenACCClause *> Clauses);
610+
void SetTileInfoBeforeAssociatedStmt(
611+
ArrayRef<const OpenACCClause *> UnInstClauses,
612+
ArrayRef<OpenACCClause *> Clauses);
580613
~AssociatedStmtRAII();
581614
};
582615
};

0 commit comments

Comments
 (0)