@@ -264,6 +264,7 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
264264 Stmt *CS = nullptr ;
265265 llvm::SmallVector<Expr *, 4 > ImplicitShared;
266266 llvm::SmallVector<Expr *, 4 > ImplicitFirstprivate;
267+ llvm::SmallSet<const ValueDecl *, 4 > InnerDecls;
267268
268269public:
269270 void VisitDeclRefExpr (DeclRefExpr *E) {
@@ -273,18 +274,24 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
273274 if (auto *VD = dyn_cast<VarDecl>(E->getDecl ())) {
274275 VD = VD->getCanonicalDecl ();
275276
277+ // Variables declared inside region don't have DSA
278+ if (InnerDecls.count (VD))
279+ return ;
280+
276281 DSAStackTy::DSAVarData DVarCurrent = Stack->getCurrentDSA (VD);
277282 DSAStackTy::DSAVarData DVarFromParent = Stack->getTopDSA (VD, /* FromParent=*/ true );
278283
279- bool IsParentExplicit = DVarFromParent.RefExpr && !DVarFromParent. Ignore ;
280- bool IsCurrentExplicit = DVarCurrent. RefExpr && !DVarCurrent .Ignore ;
284+ bool ExistsParent = DVarFromParent.RefExpr ;
285+ bool ParentIgnore = DVarFromParent .Ignore ;
281286
282- // Check if the variable has explicit DSA only set on the current
287+ bool ExistsCurrent = DVarCurrent.RefExpr ;
288+
289+ // Check if the variable has DSA set on the current
283290 // directive and stop analysis if it so.
284- if (IsCurrentExplicit )
291+ if (ExistsCurrent )
285292 return ;
286293 // If explicit DSA comes from parent inherit it
287- if (IsParentExplicit ) {
294+ if (ExistsParent && !ParentIgnore ) {
288295 switch (DVarFromParent.CKind ) {
289296 case OSSC_shared:
290297 ImplicitShared.push_back (E);
@@ -309,6 +316,8 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
309316 // Define implicit data-sharing attributes for task.
310317 if (isOmpSsTaskingDirective (DKind))
311318 ImplicitShared.push_back (E);
319+ // Record DSA as Ignored to avoid making the same node again
320+ Stack->addDSA (VD, E, OSSC_shared, /* Ignore=*/ true );
312321 break ;
313322 case DSA_none:
314323 if (!DVarCurrent.Ignore ) {
@@ -326,13 +335,19 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
326335 // Define implicit data-sharing attributes for task.
327336 if (isOmpSsTaskingDirective (DKind))
328337 ImplicitFirstprivate.push_back (E);
338+
339+ // Record DSA as Ignored to avoid making the same node again
340+ Stack->addDSA (VD, E, OSSC_firstprivate, /* Ignore=*/ true );
329341 } else {
330342 // If no default clause is present and the variable was shared/global
331343 // in the context encountering the construct, the variable will be shared.
332344
333345 // Define implicit data-sharing attributes for task.
334346 if (isOmpSsTaskingDirective (DKind))
335347 ImplicitShared.push_back (E);
348+
349+ // Record DSA as Ignored to avoid making the same node again
350+ Stack->addDSA (VD, E, OSSC_shared, /* Ignore=*/ true );
336351 }
337352 }
338353 }
@@ -346,6 +361,12 @@ class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
346361 }
347362 }
348363
364+ void VisitDeclStmt (DeclStmt *S) {
365+ for (const Decl *D : S->decls ())
366+ if (const auto *VD = dyn_cast_or_null<ValueDecl>(D))
367+ InnerDecls.insert (VD);
368+ }
369+
349370 bool isErrorFound () const { return ErrorFound; }
350371
351372 ArrayRef<Expr *> getImplicitShared () const {
0 commit comments