@@ -221,50 +221,106 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(
221221 }
222222}
223223
224+ namespace {
225+ // Given two collapse clauses, and the uninstanted version of the new one,
226+ // return the 'best' one for the purposes of setting the collapse checking
227+ // values.
228+ const OpenACCCollapseClause *
229+ getBestCollapseCandidate (const OpenACCCollapseClause *Old,
230+ const OpenACCCollapseClause *New,
231+ const OpenACCCollapseClause *UnInstNew) {
232+ // If the loop count is nullptr, it is because instantiation failed, so this
233+ // can't be the best one.
234+ if (!New->getLoopCount ())
235+ return Old;
236+
237+ // If the loop-count had an error, than 'new' isn't a candidate.
238+ if (!New->getLoopCount ())
239+ return Old;
240+
241+ // Don't consider uninstantiated ones, since we can't really check these.
242+ if (New->getLoopCount ()->isInstantiationDependent ())
243+ return Old;
244+
245+ // If this is an instantiation, and the old version wasn't instantation
246+ // dependent, than nothing has changed and we've already done a diagnostic
247+ // based on this one, so don't consider it.
248+ if (UnInstNew && !UnInstNew->getLoopCount ()->isInstantiationDependent ())
249+ return Old;
250+
251+ // New is now a valid candidate, so if there isn't an old one at this point,
252+ // New is the only valid one.
253+ if (!Old)
254+ return New;
255+
256+ // If the 'New' expression has a larger value than 'Old', then it is the new
257+ // best candidate.
258+ if (cast<ConstantExpr>(Old->getLoopCount ())->getResultAsAPSInt () <
259+ cast<ConstantExpr>(New->getLoopCount ())->getResultAsAPSInt ())
260+ return New;
261+
262+ return Old;
263+ }
264+ } // namespace
265+
224266void SemaOpenACC::AssociatedStmtRAII::SetCollapseInfoBeforeAssociatedStmt (
225267 ArrayRef<const OpenACCClause *> UnInstClauses,
226268 ArrayRef<OpenACCClause *> Clauses) {
227269
228270 // Reset this checking for loops that aren't covered in a RAII object.
229271 SemaRef.LoopInfo .CurLevelHasLoopAlready = false ;
230272 SemaRef.CollapseInfo .CollapseDepthSatisfied = true ;
273+ SemaRef.CollapseInfo .CurCollapseCount = 0 ;
231274 SemaRef.TileInfo .TileDepthSatisfied = true ;
232275
233276 // We make sure to take an optional list of uninstantiated clauses, so that
234277 // we can check to make sure we don't 'double diagnose' in the event that
235- // the value of 'N' was not dependent in a template. We also ensure during
236- // Sema that there is only 1 collapse on each construct, so we can count on
237- // the fact that if both find a 'collapse', that they are the same one.
238- auto *CollapseClauseItr =
239- llvm::find_if (Clauses, llvm::IsaPred<OpenACCCollapseClause>);
240- auto *UnInstCollapseClauseItr =
278+ // the value of 'N' was not dependent in a template. Since we cannot count on
279+ // there only being a single collapse clause, we count on the order to make
280+ // sure get the matching ones, and we count on TreeTransform not removing
281+ // these, even if loop-count instantiation failed. We can check the
282+ // non-dependent ones right away, and realize that subsequent instantiation
283+ // can only make it more specific.
284+
285+ auto *UnInstClauseItr =
241286 llvm::find_if (UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>);
242-
243- if (Clauses.end () == CollapseClauseItr)
244- return ;
245-
246- OpenACCCollapseClause *CollapseClause =
247- cast<OpenACCCollapseClause>(*CollapseClauseItr);
248-
249- SemaRef.CollapseInfo .ActiveCollapse = CollapseClause;
250- Expr *LoopCount = CollapseClause->getLoopCount ();
251-
252- // If the loop count is still instantiation dependent, setting the depth
253- // counter isn't necessary, so return here.
254- if (!LoopCount || LoopCount->isInstantiationDependent ())
255- return ;
256-
257- // Suppress diagnostics if we've done a 'transform' where the previous version
258- // wasn't dependent, meaning we already diagnosed it.
259- if (UnInstCollapseClauseItr != UnInstClauses.end () &&
260- !cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr)
261- ->getLoopCount ()
262- ->isInstantiationDependent ())
287+ auto *ClauseItr =
288+ llvm::find_if (Clauses, llvm::IsaPred<OpenACCCollapseClause>);
289+ const OpenACCCollapseClause *FoundClause = nullptr ;
290+
291+ // Loop through the list of Collapse clauses and find the one that:
292+ // 1- Has a non-dependent, non-null loop count (null means error, likely
293+ // during instantiation).
294+ // 2- If UnInstClauses isn't empty, its corresponding
295+ // loop count was dependent.
296+ // 3- Has the largest 'loop count' of all.
297+ while (ClauseItr != Clauses.end ()) {
298+ const OpenACCCollapseClause *CurClause =
299+ cast<OpenACCCollapseClause>(*ClauseItr);
300+ const OpenACCCollapseClause *UnInstCurClause =
301+ UnInstClauseItr == UnInstClauses.end ()
302+ ? nullptr
303+ : cast<OpenACCCollapseClause>(*UnInstClauseItr);
304+
305+ FoundClause =
306+ getBestCollapseCandidate (FoundClause, CurClause, UnInstCurClause);
307+
308+ UnInstClauseItr =
309+ UnInstClauseItr == UnInstClauses.end ()
310+ ? UnInstClauseItr
311+ : std::find_if (std::next (UnInstClauseItr), UnInstClauses.end (),
312+ llvm::IsaPred<OpenACCCollapseClause>);
313+ ClauseItr = std::find_if (std::next (ClauseItr), Clauses.end (),
314+ llvm::IsaPred<OpenACCCollapseClause>);
315+ }
316+
317+ if (!FoundClause)
263318 return ;
264319
320+ SemaRef.CollapseInfo .ActiveCollapse = FoundClause;
265321 SemaRef.CollapseInfo .CollapseDepthSatisfied = false ;
266322 SemaRef.CollapseInfo .CurCollapseCount =
267- cast<ConstantExpr>(LoopCount )->getResultAsAPSInt ();
323+ cast<ConstantExpr>(FoundClause-> getLoopCount () )->getResultAsAPSInt ();
268324 SemaRef.CollapseInfo .DirectiveKind = DirKind;
269325}
270326
@@ -283,6 +339,17 @@ void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt(
283339 return ;
284340
285341 OpenACCTileClause *TileClause = cast<OpenACCTileClause>(*TileClauseItr);
342+
343+ // Multiple tile clauses are allowed, so ensure that we use the one with the
344+ // largest 'tile count'.
345+ while (Clauses.end () !=
346+ (TileClauseItr = std::find_if (std::next (TileClauseItr), Clauses.end (),
347+ llvm::IsaPred<OpenACCTileClause>))) {
348+ OpenACCTileClause *NewClause = cast<OpenACCTileClause>(*TileClauseItr);
349+ if (NewClause->getSizeExprs ().size () > TileClause->getSizeExprs ().size ())
350+ TileClause = NewClause;
351+ }
352+
286353 SemaRef.TileInfo .ActiveTile = TileClause;
287354 SemaRef.TileInfo .TileDepthSatisfied = false ;
288355 SemaRef.TileInfo .CurTileCount =
0 commit comments